diff --git a/Makefile.in b/Makefile.in index 268a25d72fc19..dd2e6a95861bd 100644 --- a/Makefile.in +++ b/Makefile.in @@ -238,7 +238,7 @@ $(foreach target,$(CFG_TARGET_TRIPLES),\ CORELIB_CRATE := $(S)src/libcore/core.rc CORELIB_INPUTS := $(wildcard $(addprefix $(S)src/libcore/, \ - core.rc *.rs */*.rs)) + core.rc *.rs */*.rs */*/*rs)) ###################################################################### # Standard library variables diff --git a/RELEASES.txt b/RELEASES.txt index 9db4a7954e47c..47ddd77ad9e33 100644 --- a/RELEASES.txt +++ b/RELEASES.txt @@ -1,20 +1,21 @@ Version 0.6 (March 2013) --------------------------- - * ~??? changes, numerous bugfixes + * ~2000 changes, numerous bugfixes * TODO: * Ord/Cmp * Lifetime changes - * Implicit self * Remove `static` keyword * Static method syntax * `as Trait` * `copy` removed, replaced with `Clone`? - * `std::map` removed, replaced with `core::hashmap` + * More details for "Name resolution continues to be tweaked"? * Syntax changes * The self type parameter in traits is now spelled `Self` + * The `self` parameter in trait and impl methods must now be explicitly + named (for example: `fn f(&self) { }`). Implicit self is deprecated. * Replaced the `Durable` trait with the `'static` lifetime * The old closure type syntax with the trailing sigil has been removed in favor of the more consistent leading sigil @@ -23,7 +24,7 @@ Version 0.6 (March 2013) * Traits are implemented with `impl Trait for Type` instead of `impl Type: Trait` * The `export` keyword has finally been removed - * The `move` keyword has been removed (linear types move by default) + * The `move` keyword has been removed (see "Semantic changes") * The interior mutability qualifier on vectors, `[mut T]`, has been removed. Use `&mut [T]`, etc. * `mut` is no longer valid in `~mut T`. Use inherited mutability @@ -37,6 +38,12 @@ Version 0.6 (March 2013) function modules. Use extern blocks: `extern { ... }` * Newtype enums removed. Used tuple-structs. * Trait implementations no longer support visibility modifiers + * Pattern matching over vectors improved and expanded + * `const` renamed to `static` to correspond to lifetime name, + and make room for future `static mut` unsafe mutable globals. + * Replaced `#[deriving_eq]` with `#[deriving(Eq)]` + * `Clone` implementations can be automatically generated with + `#[deriving(Clone)]` * Semantic changes * Types with owned pointers or custom destructors move by default, @@ -49,14 +56,14 @@ Version 0.6 (March 2013) * The default type of an inferred closure is &fn instead of @fn * Name resolution continues to be tweaked * Method visibility is inherited from the implementation declaration - - * Other language changes * Structural records have been removed - * Many more types can be used in constants, including enums - `static lifetime pointers and vectors + * Many more types can be used in static items, including enums + 'static-lifetime pointers and vectors * Pattern matching over vectors improved and expanded * Typechecking of closure types has been overhauled to improve inference and eliminate unsoundness + * Macros leave scope at the end of modules, unless that module is + tagged with #[macro_escape] * Libraries * Added big integers to `std::bigint` @@ -68,6 +75,7 @@ Version 0.6 (March 2013) * Containers reorganized around traits in `core::container` * `core::dvec` removed, `~[T]` is a drop-in replacement * `core::send_map` renamed to `core::hashmap` + * `std::map` removed; replaced with `core::hashmap` * `std::treemap` reimplemented as an owned balanced tree * `std::deque` and `std::smallintmap` reimplemented as owned containers * `core::trie` added as a fast ordered map for integer keys @@ -76,15 +84,16 @@ Version 0.6 (March 2013) * Tools * Replaced the 'cargo' package manager with 'rustpkg' * Added all-purpose 'rust' tool - * `rustc --test` now supports a benchmarks with the `#[bench]` attribute + * `rustc --test` now supports benchmarks with the `#[bench]` attribute * rustc now attempts to offer spelling suggestions * Misc * Improved support for ARM and Android * Preliminary MIPS backend * Improved foreign function ABI implementation for x86, x86_64 - * Various and memory usage improvements + * Various memory usage improvements * Rust code may be embedded in foreign code under limited circumstances + * Inline assembler supported by new asm!() syntax extension. Version 0.5 (December 2012) --------------------------- diff --git a/configure b/configure index 1d0afbea80431..a58a0a6326c37 100755 --- a/configure +++ b/configure @@ -136,9 +136,17 @@ validate_opt () { isArgValid=1 fi done - if test $isArgValid -eq 0 + if [ "$arg" = "--help" ] then - err "Option '$arg' is not recognized" + echo "" + echo "No more help available for Configure options," + echo "check the Wiki or join our IRC channel" + break + else + if test $isArgValid -eq 0 + then + err "Option '$arg' is not recognized" + fi fi done } @@ -266,13 +274,42 @@ case $CFG_OSTYPE in MINGW32*) CFG_OSTYPE=pc-mingw32 ;; +# Thad's Cygwin identifers below + +# Vista 32 bit + CYGWIN_NT-6.0) + CFG_OSTYPE=pc-mingw32 + CFG_CPUTYPE=i686 + ;; + +# Vista 64 bit + CYGWIN_NT-6.0-WOW64) + CFG_OSTYPE=w64-mingw32 + CFG_CPUTYPE=x86_64 + ;; + +# Win 7 32 bit + CYGWIN_NT-6.1) + CFG_OSTYPE=pc-mingw32 + CFG_CPUTYPE=i686 + ;; +# Win 7 64 bit + CYGWIN_NT-6.1-WOW64) + CFG_OSTYPE=w64-mingw32 + CFG_CPUTYPE=x86_64 + ;; + +# We do not detect other OS such as XP/2003 using 64 bit using uname. +# If we want to in the future, we will need to use Cygwin - Chuck's csih helper in /usr/lib/csih/winProductName.exe or alternative. *) err "unknown OS type: $CFG_OSTYPE" ;; esac +if [ -z "$CFG_CPUTYPE" ] +then case $CFG_CPUTYPE in i386 | i486 | i686 | i786 | x86) @@ -290,6 +327,7 @@ case $CFG_CPUTYPE in *) err "unknown CPU type: $CFG_CPUTYPE" esac +fi # Detect 64 bit linux systems with 32 bit userland and force 32 bit compilation if [ $CFG_OSTYPE = unknown-linux-gnu -a $CFG_CPUTYPE = x86_64 ] @@ -406,12 +444,13 @@ fi if [ ! -z "$CFG_PANDOC" ] then - PANDOC_VER_LINE=$(pandoc --version | grep '^pandoc ') - PANDOC_VER=${PANDOC_VER_LINE#pandoc } - PV_MAJOR_MINOR=${PANDOC_VER%.[0-9]*} - PV_MAJOR=${PV_MAJOR_MINOR%%[.][0-9]*} - PV_MINOR=${PV_MAJOR_MINOR#[0-9]*[.]} - PV_MINOR=${PV_MINOR%%[.][0-9]*} + PV_MAJOR_MINOR=$(pandoc --version | grep '^pandoc ' | + # extract the first 2 version fields, ignore everything else + sed 's/pandoc \([0-9]*\)\.\([0-9]*\).*/\1 \2/') + + # these patterns are shell globs, *not* regexps + PV_MAJOR=${PV_MAJOR_MINOR% *} + PV_MINOR=${PV_MAJOR_MINOR#* } if [ "$PV_MAJOR" -lt "1" ] || [ "$PV_MINOR" -lt "8" ] then step_msg "pandoc $PV_MAJOR.$PV_MINOR is too old. disabling" @@ -519,7 +558,7 @@ then | cut -d ' ' -f 2) case $CFG_CLANG_VERSION in - (3.0svn | 3.0 | 3.1* | 3.2* | 4.0* | 4.1* | 4.2*) + (3.0svn | 3.0 | 3.1* | 3.2* | 3.3* | 4.0* | 4.1* | 4.2*) step_msg "found ok version of CLANG: $CFG_CLANG_VERSION" CFG_C_COMPILER="clang" ;; @@ -536,6 +575,7 @@ fi CFG_PREFIX=${CFG_PREFIX%/} CFG_HOST_TRIPLES="$(echo $CFG_HOST_TRIPLES | tr ',' ' ')" CFG_TARGET_TRIPLES="$(echo $CFG_TARGET_TRIPLES | tr ',' ' ')" +CFG_SUPPORTED_TARGET_TRIPLES="$(grep ^CC_*=* $CFG_SRC_DIR/mk/platform.mk | sed 's,^[^_]*_,,' | sed 's/\([^=]*\).*/\1/' | xargs)" # copy host-triples to target-triples so that hosts are a subset of targets V_TEMP="" @@ -548,8 +588,22 @@ CFG_TARGET_TRIPLES=$V_TEMP # check target-specific tool-chains for i in $CFG_TARGET_TRIPLES do + L_CHECK=false + for j in $CFG_SUPPORTED_TARGET_TRIPLES + do + if [ $i = $j ] + then + L_CHECK=true + fi + done + + if [ $L_CHECK = false ] + then + err "unsupported target triples \"$i\" found" + fi + case $i in - arm-unknown-android) + arm-linux-androideabi) if [ ! -f $CFG_ANDROID_CROSS_PATH/bin/arm-linux-androideabi-gcc ] then diff --git a/doc/rust.md b/doc/rust.md index 6be428ef27908..60a83662b0e4c 100644 --- a/doc/rust.md +++ b/doc/rust.md @@ -91,11 +91,10 @@ This EBNF dialect should hopefully be familiar to many readers. ## Unicode productions -A small number of productions in Rust's grammar permit Unicode codepoints -outside the ASCII range; these productions are defined in terms of character -properties given by the Unicode standard, rather than ASCII-range -codepoints. These are given in the section [Special Unicode -Productions](#special-unicode-productions). +A few productions in Rust's grammar permit Unicode codepoints outside the ASCII range. +We define these productions in terms of character properties specified in the Unicode standard, +rather than in terms of ASCII-range codepoints. +The section [Special Unicode Productions](#special-unicode-productions) lists these productions. ## String table productions @@ -207,7 +206,7 @@ The keywords are the following strings: ~~~~~~~~ {.keyword} as break -const copy +copy do drop else enum extern false fn for @@ -222,8 +221,8 @@ unsafe use while ~~~~~~~~ -Any of these have special meaning in their respective grammars, and are -excluded from the `ident` rule. +Each of these keywords has special meaning in its grammar, +and all of them are excluded from the `ident` rule. ### Literals @@ -486,16 +485,18 @@ transcriber : '(' transcriber * ')' | '[' transcriber * ']' ~~~~~~~~ -User-defined syntax extensions are called "macros", and they can be defined -with the `macro_rules!` syntax extension. User-defined macros can currently -be invoked as expressions, statements, or items. +User-defined syntax extensions are called "macros", +and the `macro_rules` syntax extension defines them. +Currently, user-defined macros can expand to expressions, statements, or items. -(A `sep_token` is any token other than `*` and `+`. A `non_special_token` is -any token other than a delimiter or `$`.) +(A `sep_token` is any token other than `*` and `+`. +A `non_special_token` is any token other than a delimiter or `$`.) -Macro invocations are looked up by name, and each macro rule is tried in turn; -the first successful match is transcribed. The matching and transcription -processes are closely related, and will be described together: +The macro expander looks up macro invocations by name, +and tries each macro rule in turn. +It transcribes the first successful match. +Matching and transcription are closely related to each other, +and we will describe them together. ### Macro By Example @@ -548,12 +549,10 @@ This requirement most often affects name-designator pairs when they occur at the ## Syntax extensions useful for the macro author * `log_syntax!` : print out the arguments at compile time -* `trace_macros!` : supply `true` or `false` to enable or disable printing of the macro expansion process. +* `trace_macros!` : supply `true` or `false` to enable or disable macro expansion logging * `stringify!` : turn the identifier argument into a string literal * `concat_idents!` : create a new identifier by concatenating the arguments - - # Crates and source files Rust is a *compiled* language. @@ -618,8 +617,8 @@ each of which may have some number of [attributes](#attributes) attached to it. ## Items ~~~~~~~~ {.ebnf .gram} -item : mod_item | fn_item | type_item | enum_item - | const_item | trait_item | impl_item | foreign_mod_item ; +item : mod_item | fn_item | type_item | struct_item | enum_item + | static_item | trait_item | impl_item | foreign_mod_item ; ~~~~~~~~ An _item_ is a component of a crate; some module items can be defined in crate @@ -628,7 +627,7 @@ crate by a nested set of [modules](#modules). Every crate has a single "outermost" anonymous module; all further items within the crate have [paths](#paths) within the module tree of the crate. -Items are entirely determined at compile-time, remain constant during +Items are entirely determined at compile-time, generally remain fixed during execution, and may reside in read-only memory. There are several kinds of item: @@ -638,7 +637,7 @@ There are several kinds of item: * [type definitions](#type-definitions) * [structures](#structures) * [enumerations](#enumerations) - * [constants](#constants) + * [static items](#static-items) * [traits](#traits) * [implementations](#implementations) @@ -785,22 +784,19 @@ path_glob : ident [ "::" path_glob ] ? ~~~~~~~~ A _use declaration_ creates one or more local name bindings synonymous -with some other [path](#paths). Usually a `use` declaration is used to -shorten the path required to refer to a module item. +with some other [path](#paths). +Usually a `use` declaration is used to shorten the path required to refer to a module item. -*Note*: unlike many languages, Rust's `use` declarations do *not* declare -linkage-dependency with external crates. Linkage dependencies are -independently declared with -[`extern mod` declarations](#extern-mod-declarations). +*Note*: Unlike in many languages, +`use` declarations in Rust do *not* declare linkage dependency with external crates. +Rather, [`extern mod` declarations](#extern-mod-declarations) declare linkage dependencies. -Use declarations support a number of "convenience" notations: +Use declarations support a number of convenient shortcuts: - * Rebinding the target name as a new local name, using the - syntax `use x = p::q::r;`. - * Simultaneously binding a list of paths differing only in final element, + * Rebinding the target name as a new local name, using the syntax `use x = p::q::r;`. + * Simultaneously binding a list of paths differing only in their 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::*;` + * Binding all paths matching a given prefix, using the asterisk wildcard syntax `use a::b::*;` An example of `use` declarations: @@ -825,9 +821,10 @@ fn main() { 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. Such a `use` declaration serves to _re-export_ a name. -A public `use` declaration can therefore be used to _redirect_ some public name to a different target definition, +A public `use` declaration can therefore _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. +If a sequence of such redirections form a cycle or cannot be resolved unambiguously, +they represent a compile-time error. An example of re-exporting: ~~~~ @@ -844,8 +841,8 @@ mod quux { In this example, the module `quux` re-exports all of the public names defined in `foo`. -Also note that the paths contained in `use` items are relative to the crate root; so, in the previous -example, the use refers to `quux::foo::*`, and not simply to `foo::*`. +Also note that the paths contained in `use` items are relative to the crate root. +So, in the previous example, the `use` refers to `quux::foo::*`, and not simply to `foo::*`. ### Functions @@ -994,27 +991,27 @@ Thus the return type on `f` only needs to reflect the `if` branch of the conditi #### Extern functions -Extern functions are part of Rust's foreign function interface, providing -the opposite functionality to [foreign modules](#foreign-modules). Whereas -foreign modules allow Rust code to call foreign code, extern functions with -bodies defined in Rust code _can be called by foreign code_. They are defined the -same as any other Rust function, except that they are prepended with the -`extern` keyword. +Extern functions are part of Rust's foreign function interface, +providing the opposite functionality to [foreign modules](#foreign-modules). +Whereas foreign modules allow Rust code to call foreign code, +extern functions with bodies defined in Rust code _can be called by foreign code_. +They are defined in the same way as any other Rust function, +except that they have the `extern` modifier. ~~~ extern fn new_vec() -> ~[int] { ~[] } ~~~ -Extern functions may not be called from Rust code, but their value -may be taken as a raw `u8` pointer. +Extern functions may not be called from Rust code, +but Rust code may take their value as a raw `u8` pointer. ~~~ # extern fn new_vec() -> ~[int] { ~[] } let fptr: *u8 = new_vec; ~~~ -The primary motivation of extern functions is to create callbacks -for foreign functions that expect to receive function pointers. +The primary motivation for extern functions is +to create callbacks for foreign functions that expect to receive function pointers. ### Type definitions @@ -1052,7 +1049,7 @@ let p = Point(10, 11); let px: int = match p { Point(x, _) => x }; ~~~~ -A _unit-like struct_ is a structure without any fields, defined by leaving off the fields list entirely. +A _unit-like struct_ is a structure without any fields, defined by leaving off the list of fields entirely. Such types will have a single value, just like the [unit value `()`](#unit-and-boolean-literals) of the unit type. For example: @@ -1094,35 +1091,37 @@ a = Cat{ name: ~"Spotty", weight: 2.7 }; In this example, `Cat` is a _struct-like enum variant_, whereas `Dog` is simply called an enum variant. -### Constants +### Static items ~~~~~~~~ {.ebnf .gram} -const_item : "const" ident ':' type '=' expr ';' ; +static_item : "static" ident ':' type '=' expr ';' ; ~~~~~~~~ -A *constant* is a named value stored in read-only memory in a crate. -The value bound to a constant is evaluated at compile time. -Constants are declared with the `const` keyword. -A constant item must have an expression giving its definition. -The definition expression of a constant is limited to expression forms that can be evaluated at compile time. +A *static item* is a named _constant value_ stored in the global data section of a crate. +Immutable static items are stored in the read-only data section. +The constant value bound to a static item is, like all constant values, evaluated at compile time. +Static items have the `static` lifetime, which outlives all other lifetimes in a Rust program. +Static items are declared with the `static` keyword. +A static item must have a _constant expression_ giving its definition. -Constants must be explicitly typed. The type may be ```bool```, ```char```, a number, or a type derived from those primitive types. -The derived types are borrowed pointers, static arrays, tuples, and structs. -Borrowed pointers must be have the `'static` lifetime. +Static items must be explicitly typed. +The type may be ```bool```, ```char```, a number, or a type derived from those primitive types. +The derived types are borrowed pointers with the `'static` lifetime, +fixed-size arrays, tuples, and structs. ~~~~ -const bit1: uint = 1 << 0; -const bit2: uint = 1 << 1; +static bit1: uint = 1 << 0; +static bit2: uint = 1 << 1; -const bits: [uint * 2] = [bit1, bit2]; -const string: &'static str = "bitstring"; +static bits: [uint, ..2] = [bit1, bit2]; +static string: &'static str = "bitstring"; struct BitsNStrings { - mybits: [uint *2], + mybits: [uint, ..2], mystring: &'self str } -const bits_n_strings: BitsNStrings<'static> = BitsNStrings { +static bits_n_strings: BitsNStrings<'static> = BitsNStrings { mybits: bits, mystring: string }; @@ -1209,10 +1208,10 @@ For example: ~~~~ trait Num { - static fn from_int(n: int) -> Self; + fn from_int(n: int) -> Self; } impl Num for float { - static fn from_int(n: int) -> float { n as float } + fn from_int(n: int) -> float { n as float } } let x: float = Num::from_int(42); ~~~~ @@ -1459,7 +1458,7 @@ The declared names may denote new slots or new items. An _item declaration statement_ has a syntactic form identical to an [item](#items) declaration within a module. Declaring an item -- a function, -enumeration, type, constant, trait, implementation or module -- locally +enumeration, structure, type, static, trait, implementation or module -- locally within a statement block is simply a way of restricting its scope to a narrow region containing all of its uses; it is otherwise identical in meaning to declaring the item outside the statement block. @@ -1484,23 +1483,25 @@ Any slots introduced by a slot declaration are visible from the point of declara ### Expression statements An _expression statement_ is one that evaluates an [expression](#expressions) -and drops its result. The purpose of an expression statement is often to cause -the side effects of the expression's evaluation. +and ignores its result. +The type of an expression statement `e;` is always `()`, regardless of the type of `e`. +As a rule, an expression statement's purpose is to trigger the effects of evaluating its expression. ## Expressions -An expression plays the dual roles of causing side effects and producing a -*value*. Expressions are said to *evaluate to* a value, and the side effects -are caused during *evaluation*. Many expressions contain sub-expressions as -operands; the definition of each kind of expression dictates whether or not, -and in which order, it will evaluate its sub-expressions, and how the -expression's value derives from the value of its sub-expressions. +An expression may have two roles: it always produces a *value*, and it may have *effects* +(otherwise known as "side effects"). +An expression *evaluates to* a value, and has effects during *evaluation*. +Many expressions contain sub-expressions (operands). +The meaning of each kind of expression dictates several things: + * Whether or not to evaluate the sub-expressions when evaluating the expression + * The order in which to evaluate the sub-expressions + * How to combine the sub-expressions' values to obtain the value of the expression. -In this way, the structure of execution -- both the overall sequence of -observable side effects and the final produced value -- is dictated by the -structure of expressions. Blocks themselves are expressions, so the nesting -sequence of block, statement, expression, and block can repeatedly nest to an -arbitrary depth. +In this way, the structure of expressions dictates the structure of execution. +Blocks are just another kind of expression, +so blocks, statements, expressions, and blocks again can recursively nest inside each other +to an arbitrary depth. #### Lvalues, rvalues and temporaries @@ -1579,11 +1580,11 @@ A _structure expression_ consists of the [path](#paths) of a [structure item](#s followed by a brace-enclosed list of one or more comma-separated name-value pairs, providing the field values of a new instance of the structure. A field name can be any identifier, and is separated from its value expression by a colon. -To indicate that a field is mutable, the `mut` keyword is written before its name. +The location denoted by a structure field is mutable if and only if the enclosing structure is mutable. A _tuple structure expression_ consists of the [path](#paths) of a [structure item](#structures), followed by a parenthesized list of one or more comma-separated expressions -(in other words, the path of a structured item followed by a tuple expression). +(in other words, the path of a structure item followed by a tuple expression). The structure item must be a tuple structure item. A _unit-like structure expression_ consists only of the [path](#paths) of a [structure item](#structures). @@ -1597,7 +1598,7 @@ The following are examples of structure expressions: # struct Cookie; fn some_fn(t: T) {} Point {x: 10f, y: 20f}; TuplePoint(10f, 20f); -let u = game::User {name: "Joe", age: 35u, score: 100_000}; +let u = game::User {name: "Joe", age: 35, score: 100_000}; some_fn::(Cookie); ~~~~ @@ -1605,8 +1606,10 @@ A structure expression forms a new value of the named structure type. Note that for a given *unit-like* structure type, this will always be the same value. A structure expression can terminate with the syntax `..` followed by an expression to denote a functional update. -The expression following `..` (the base) must be of the same structure type as the new structure type being formed. -A new structure will be created, of the same type as the base expression, with the given values for the fields that were explicitly specified, +The expression following `..` (the base) must have the same structure type as the new structure type being formed. +The entire expression denotes the result of allocating a new structure +(with the same type as the base expression) +with the given values for the fields that were explicitly specified and the values in the base record for all other fields. ~~~~ @@ -1758,36 +1761,35 @@ The default meaning of the operators on standard types is given here. #### Bitwise operators -Bitwise operators are, like the [arithmetic operators](#arithmetic-operators), -syntactic sugar for calls to built-in traits. +Like the [arithmetic operators](#arithmetic-operators), bitwise operators +are syntactic sugar for calls to methods of built-in traits. This means that bitwise operators can be overridden for user-defined types. The default meaning of the operators on standard types is given here. `&` : And. - Calls the `bitand` method on the `core::ops::BitAnd` trait. + Calls the `bitand` method of the `core::ops::BitAnd` trait. `|` : Inclusive or. - Calls the `bitor` method on the `core::ops::BitOr` trait. + Calls the `bitor` method of the `core::ops::BitOr` trait. `^` : Exclusive or. - Calls the `bitxor` method on the `core::ops::BitXor` trait. + Calls the `bitxor` method of the `core::ops::BitXor` trait. `<<` : Logical left shift. - Calls the `shl` method on the `core::ops::Shl` trait. + Calls the `shl` method of the `core::ops::Shl` trait. `>>` : Logical right shift. - Calls the `shr` method on the `core::ops::Shr` trait. + Calls the `shr` method of the `core::ops::Shr` trait. #### Lazy boolean operators -The operators `||` and `&&` may be applied to operands of boolean -type. The first performs the 'or' operation, and the second the 'and' -operation. They differ from `|` and `&` in that the right-hand operand -is only evaluated when the left-hand operand does not already -determine the outcome of the expression. That is, `||` only evaluates -its right-hand operand when the left-hand operand evaluates to `false`, -and `&&` only when it evaluates to `true`. +The operators `||` and `&&` may be applied to operands of boolean type. +The `||` operator denotes logical 'or', and the `&&` operator denotes logical 'and'. +They differ from `|` and `&` in that the right-hand operand is only evaluated +when the left-hand operand does not already determine the result of the expression. +That is, `||` only evaluates its right-hand operand +when the left-hand operand evaluates to `false`, and `&&` only when it evaluates to `true`. #### Comparison operators @@ -1937,6 +1939,9 @@ let x = (2 + 3) * 4; copy_expr : "copy" expr ; ~~~~~~~~ +> **Note:** `copy` expressions are deprecated. It's preferable to use +> the `Clone` trait and `clone()` method. + A _unary copy expression_ consists of the unary `copy` operator applied to some argument expression. @@ -2013,27 +2018,29 @@ ident_list : [ ident [ ',' ident ]* ] ? ; lambda_expr : '|' ident_list '|' expr ; ~~~~~~~~ -A _lambda expression_ (a.k.a. "anonymous function expression") defines a function and denotes it as a value, +A _lambda expression_ (sometimes called an "anonymous function expression") defines a function and denotes it as a value, in a single expression. -Lambda expressions are written by prepending a list of identifiers, surrounded by pipe symbols (`|`), -to an expression. +A lambda expression is a pipe-symbol-delimited (`|`) list of identifiers followed by an expression. -A lambda expression denotes a function mapping parameters to the expression to the right of the `ident_list`. -The identifiers in the `ident_list` are the parameters to the function, with types inferred from context. +A lambda expression denotes a function that maps a list of parameters (`ident_list`) +onto the expression that follows the `ident_list`. +The identifiers in the `ident_list` are the parameters to the function. +These parameters' types need not be specified, as the compiler infers them from context. Lambda expressions are most useful when passing functions as arguments to other functions, -as an abbreviation for defining and capturing a separate fucntion. +as an abbreviation for defining and capturing a separate function. Significantly, lambda expressions _capture their environment_, which regular [function definitions](#functions) do not. +The exact type of capture depends on the [function type](#function-types) inferred for the lambda expression. +In the simplest and least-expensive form (analogous to a ```&fn() { }``` expression), +the lambda expression captures its environment by reference, +effectively borrowing pointers to all outer variables mentioned inside the function. +Alternately, the compiler may infer that a lambda expression should copy or move values (depending on their type.) +from the environment into the lambda expression's captured environment. -The exact type of capture depends on the [function type](#function-types) inferred for the lambda expression; -in the simplest and least-expensive form, the environment is captured by reference, -effectively borrowing pointers to all outer variables referenced inside the function. -Other forms of capture include making copies of captured variables, -and moving values from the environment into the lambda expression's captured environment. - -An example of a lambda expression: +In this example, we define a function `ten_times` that takes a higher-order function argument, +and call it with a lambda expression as an argument. ~~~~ fn ten_times(f: &fn(int)) { @@ -2428,12 +2435,12 @@ type `float` may not be equal to the largest *supported* floating-point type. The types `char` and `str` hold textual data. -A value of type `char` is a Unicode character, represented as a 32-bit -unsigned word holding a UCS-4 codepoint. +A value of type `char` is a Unicode character, +represented as a 32-bit unsigned word holding a UCS-4 codepoint. -A value of type `str` is a Unicode string, represented as a vector of 8-bit -unsigned bytes holding a sequence of UTF-8 codepoints. -Since `str` is of indefinite size, it is not a _first class_ type, +A value of type `str` is a Unicode string, +represented as a vector of 8-bit unsigned bytes holding a sequence of UTF-8 codepoints. +Since `str` is of unknown size, it is not a _first class_ type, but can only be instantiated through a pointer type, such as `&str`, `@str` or `~str`. @@ -2465,15 +2472,17 @@ fail_unless!(b != "world"); ### Vector types -The vector type-constructor represents a homogeneous array of values of a given type. +The vector type constructor represents a homogeneous array of values of a given type. A vector has a fixed size. -A vector type can be accompanied by _definite_ size, written with a trailing asterisk and integer literal, such as `[int * 10]`. -Such a definite-sized vector can be treated as a first class type since its size is known statically. +A vector type can be annotated with a _definite_ size, +written with a trailing asterisk and integer literal, such as `[int * 10]`. +Such a definite-sized vector type is a first-class type, since its size is known statically. A vector without such a size is said to be of _indefinite_ size, -and is therefore not a _first class_ type, -can only be instantiated through a pointer type, +and is therefore not a _first-class_ type. +An indefinite-size vector can only be instantiated through a pointer type, such as `&[T]`, `@[T]` or `~[T]`. -The kind of a vector type depends on the kind of its member type, as with other simple structural types. +The kind of a vector type depends on the kind of its element type, +as with other simple structural types. An example of a vector type and its use: @@ -2483,7 +2492,8 @@ let i: int = v[2]; fail_unless!(i == 3); ~~~~ -All accessible elements of a vector are always initialized, and access to a vector is always bounds-checked. +All in-bounds elements of a vector are always initialized, +and access to a vector is always bounds-checked. ### Structure types @@ -2605,9 +2615,9 @@ Raw pointers (`*`) ### Function types -The function type-constructor `fn` forms new function types. A function type -consists of a set of function-type modifiers (`unsafe`, `extern`, etc.), -a sequence of input slots and an output slot. +The function type constructor `fn` forms new function types. +A function type consists of a possibly-empty set of function-type modifiers +(such as `unsafe` or `extern`), a sequence of input types and an output type. An example of a `fn` type: @@ -2916,24 +2926,28 @@ fn main() { ## Tasks -An executing Rust program consists of a tree of tasks. A Rust _task_ -consists of an entry function, a stack, a set of outgoing communication -channels and incoming communication ports, and ownership of some portion of -the heap of a single operating-system process. - -Multiple Rust tasks may coexist in a single operating-system process. The -runtime scheduler maps tasks to a certain number of operating-system threads; -by default a number of threads is used based on the number of concurrent -physical CPUs detected at startup, but this can be changed dynamically at -runtime. When the number of tasks exceeds the number of threads -- which is -quite possible -- the tasks are multiplexed onto the threads ^[This is an M:N -scheduler, which is known to give suboptimal results for CPU-bound concurrency -problems. In such cases, running with the same number of threads as tasks can -give better results. The M:N scheduling in Rust exists to support very large -numbers of tasks in contexts where threads are too resource-intensive to use -in a similar volume. The cost of threads varies substantially per operating -system, and is sometimes quite low, so this flexibility is not always worth -exploiting.] +An executing Rust program consists of a tree of tasks. +A Rust _task_ consists of an entry function, a stack, +a set of outgoing communication channels and incoming communication ports, +and ownership of some portion of the heap of a single operating-system process. +(We expect that many programs will not use channels and ports directly, +but will instead use higher-level abstractions provided in standard libraries, +such as pipes.) + +Multiple Rust tasks may coexist in a single operating-system process. +The runtime scheduler maps tasks to a certain number of operating-system threads. +By default, the scheduler chooses the number of threads based on +the number of concurrent physical CPUs detected at startup. +It's also possible to override this choice at runtime. +When the number of tasks exceeds the number of threads -- which is likely -- +the scheduler multiplexes the tasks onto threads.^[ +This is an M:N scheduler, +which is known to give suboptimal results for CPU-bound concurrency problems. +In such cases, running with the same number of threads and tasks can yield better results. +Rust has M:N scheduling in order to support very large numbers of tasks +in contexts where threads are too resource-intensive to use in large number. +The cost of threads varies substantially per operating system, and is sometimes quite low, +so this flexibility is not always worth exploiting.] ### Communication between tasks @@ -3024,16 +3038,15 @@ communication and logging. ### Memory allocation -The runtime memory-management system is based on a _service-provider -interface_, through which the runtime requests blocks of memory from its -environment and releases them back to its environment when they are no longer -in use. The default implementation of the service-provider interface consists -of the C runtime functions `malloc` and `free`. - -The runtime memory-management system in turn supplies Rust tasks with -facilities for allocating, extending and releasing stacks, as well as -allocating and freeing boxed values. +The runtime memory-management system is based on a _service-provider interface_, +through which the runtime requests blocks of memory from its environment +and releases them back to its environment when they are no longer needed. +The default implementation of the service-provider interface +consists of the C runtime functions `malloc` and `free`. +The runtime memory-management system, in turn, supplies Rust tasks +with facilities for allocating, extending and releasing stacks, +as well as allocating and freeing heap data. ### Built in types diff --git a/doc/tutorial-borrowed-ptr.md b/doc/tutorial-borrowed-ptr.md index 8e0ca297f657c..e8b5ab9dda22f 100644 --- a/doc/tutorial-borrowed-ptr.md +++ b/doc/tutorial-borrowed-ptr.md @@ -394,7 +394,7 @@ copying. # Circle(Point, float), // origin, radius # Rectangle(Point, Size) // upper-left, dimensions # } -# const tau: float = 6.28f; +# static tau: float = 6.28f; fn compute_area(shape: &Shape) -> float { match *shape { Circle(_, radius) => 0.5 * tau * radius * radius, @@ -468,11 +468,10 @@ overwritten for the duration of the borrow. In fact, the compiler would accept the example we gave earlier. The example is safe because the shape 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 be ill-typed. Just as with unique boxes, the compiler will -permit `ref` bindings into data owned by the stack frame even if the -data are mutable, but otherwise it requires that the data reside in -immutable memory. +pointer were `&mut Shape`, then the ref binding would be ill-typed. +Just as with unique boxes, the compiler will permit `ref` bindings +into data owned by the stack frame even if the data are mutable, +but otherwise it requires that the data reside in immutable memory. # Returning borrowed pointers diff --git a/doc/tutorial-macros.md b/doc/tutorial-macros.md index 42bd319a2a4bd..24e9f4abc38e6 100644 --- a/doc/tutorial-macros.md +++ b/doc/tutorial-macros.md @@ -3,10 +3,12 @@ # Introduction Functions are the primary tool that programmers can use to build abstractions. -Sometimes, however, programmers want to perform abstractions over things that are not -runtime values. Macros provide a syntactic abstraction. For an example of how this -can be useful, consider the following two code fragments, which both pattern-match -on their input and return early in one case, and do nothing otherwise: +Sometimes, however, programmers want to abstract over compile-time syntax +rather than run-time values. +Macros provide syntactic abstraction. +For an example of how this can be useful, consider the following two code fragments, +which both pattern-match on their input and both return early in one case, +doing nothing otherwise: ~~~~ # enum t { special_a(uint), special_b(uint) }; @@ -25,9 +27,10 @@ match input_2 { # } ~~~~ -This code could become tiresome if repeated many times. However, no function -can capture its functionality to make it possible to rewrite the repetition -away. Rust's macro system, however, can eliminate the repetition. Macros are +This code could become tiresome if repeated many times. +However, no function can capture its functionality to make it possible +to abstract the repetition away. +Rust's macro system, however, can eliminate the repetition. Macros are lightweight custom syntax extensions, themselves defined using the `macro_rules!` syntax extension. The following `early_return` macro captures the pattern in the above code: @@ -37,7 +40,7 @@ the pattern in the above code: # fn f() -> uint { # let input_1 = special_a(0), input_2 = special_a(0); macro_rules! early_return( - ($inp:expr $sp:ident) => ( //invoke it like `(input_5 special_e)` + ($inp:expr $sp:ident) => ( // invoke it like `(input_5 special_e)` match $inp { $sp(x) => { return x; } _ => {} @@ -93,10 +96,10 @@ that could be invoked like: `my_macro!(i->(( 2+2 )))`. ## Invocation location -A macro invocation may take the place of (and therefore expand to) either an -expression, an item, or a statement. The Rust parser will parse the macro -invocation as a "placeholder" for whichever of those three nonterminals is -appropriate for the location. +A macro invocation may take the place of (and therefore expand to) +an expression, an item, or a statement. +The Rust parser will parse the macro invocation as a "placeholder" +for whichever of those three nonterminals is appropriate for the location. At expansion time, the output of the macro will be parsed as whichever of the three nonterminals it stands in for. This means that a single macro might, @@ -112,17 +115,19 @@ The right-hand side of the `=>` follows the same rules as the left-hand side, except that a `$` need only be followed by the name of the syntactic fragment to transcribe into the macro expansion; its type need not be repeated. -The right-hand side must be enclosed by delimiters, which are ignored by the -transcriber (therefore `() => ((1,2,3))` is a macro that expands to a tuple -expression, `() => (let $x=$val)` is a macro that expands to a statement, and -`() => (1,2,3)` is a macro that expands to a syntax error). +The right-hand side must be enclosed by delimiters, which the transcriber ignores. +Therefore `() => ((1,2,3))` is a macro that expands to a tuple expression, +`() => (let $x=$val)` is a macro that expands to a statement, +and `() => (1,2,3)` is a macro that expands to a syntax error +(since the transcriber interprets the parentheses on the right-hand-size as delimiters, +and `1,2,3` is not a valid Rust expression on its own). Except for permissibility of `$name` (and `$(...)*`, discussed below), the right-hand side of a macro definition is ordinary Rust syntax. In particular, macro invocations (including invocations of the macro currently being defined) are permitted in expression, statement, and item locations. However, nothing else about the code is examined or executed by the macro system; execution -still has to wait until runtime. +still has to wait until run-time. ## Interpolation location @@ -287,7 +292,6 @@ A macro may accept multiple different input grammars. The first one to successfully match the actual argument to a macro invocation is the one that "wins". - In the case of the example above, we want to write a recursive macro to process the semicolon-terminated lines, one-by-one. So, we want the following input patterns: @@ -369,19 +373,19 @@ return result + val; # } ~~~~ -This technique is applicable in many cases where transcribing a result "all -at once" is not possible. It resembles ordinary functional programming in some -respects, but it is important to recognize the differences. +This technique applies to many cases where transcribing a result all at once is not possible. +The resulting code resembles ordinary functional programming in some respects, +but has some important differences from functional programming. The first difference is important, but also easy to forget: the transcription (right-hand) side of a `macro_rules!` rule is literal syntax, which can only be executed at run-time. If a piece of transcription syntax does not itself appear inside another macro invocation, it will become part of the final program. If it is inside a macro invocation (for example, the recursive -invocation of `biased_match_rec!`), it does have the opprotunity to affect +invocation of `biased_match_rec!`), it does have the opportunity to affect transcription, but only through the process of attempted pattern matching. -The second difference is related: the evaluation order of macros feels +The second, related, difference is that the evaluation order of macros feels "backwards" compared to ordinary programming. Given an invocation `m1!(m2!())`, the expander first expands `m1!`, giving it as input the literal syntax `m2!()`. If it transcribes its argument unchanged into an appropriate diff --git a/doc/tutorial.md b/doc/tutorial.md index 699fc33863a1c..30e230b67b0d3 100644 --- a/doc/tutorial.md +++ b/doc/tutorial.md @@ -234,10 +234,10 @@ while count < 10 { Although Rust can almost always infer the types of local variables, you can specify a variable's type by following it with a colon, then the type -name. Constants, on the other hand, always require a type annotation. +name. Static items, on the other hand, always require a type annotation. ~~~~ -const monster_factor: float = 57.8; +static monster_factor: float = 57.8; let monster_size = monster_factor * 10.0; let monster_size: int = 50; ~~~~ @@ -579,21 +579,30 @@ Structs are quite similar to C structs and are even laid out the same way in memory (so you can read from a Rust struct in C, and vice-versa). Use the dot operator to access struct fields, as in `mypoint.x`. -Inherited mutability means that any field of a struct may be mutable, if the -struct is in a mutable slot (or a field of a struct in a mutable slot, and -so forth). - ~~~~ -struct Stack { - content: ~[int], - head: uint +struct Point { + x: float, + y: float } ~~~~ -With a value (say, `mystack`) of such a type in a mutable location, you can do -`mystack.head += 1`. But in an immutable location, such an assignment to a +Inherited mutability means that any field of a struct may be mutable, if the +struct is in a mutable slot (or a field of a struct in a mutable slot, and +so forth). + +With a value (say, `mypoint`) of such a type in a mutable location, you can do +`mypoint.y += 1.0`. But in an immutable location, such an assignment to a struct without inherited mutability would result in a type error. +~~~~ {.xfail-test} +# struct Point { x: float, y: float } +let mut mypoint = Point { x: 1.0, y: 1.0 }; +let origin = Point { x: 0.0, y: 0.0 }; + +mypoint.y += 1.0; // mypoint is mutable, and its fields as well +origin.y += 1.0; // ERROR: assigning to immutable field +~~~~ + `match` patterns destructure structs. The basic syntax is `Name { fieldname: pattern, ... }`: @@ -907,7 +916,7 @@ use core::libc::types::os::arch::c95::size_t; struct Blob { priv ptr: *c_void } impl Blob { - static fn new() -> Blob { + fn new() -> Blob { unsafe { Blob{ptr: calloc(1, int::bytes as size_t)} } } } @@ -1213,7 +1222,7 @@ pointers to vectors are also called 'slices'. # Black, BlizzardBlue, Blue # } // A fixed-size stack vector -let stack_crayons: [Crayon * 3] = [Almond, AntiqueBrass, Apricot]; +let stack_crayons: [Crayon, ..3] = [Almond, AntiqueBrass, Apricot]; // A borrowed pointer to stack-allocated vector let stack_crayons: &[Crayon] = &[Aquamarine, Asparagus, AtomicTangerine]; @@ -1255,7 +1264,7 @@ Square brackets denote indexing into a vector: # Aquamarine, Asparagus, AtomicTangerine, # BananaMania, Beaver, Bittersweet }; # fn draw_scene(c: Crayon) { } -let crayons: [Crayon * 3] = [BananaMania, Beaver, Bittersweet]; +let crayons: [Crayon, ..3] = [BananaMania, Beaver, Bittersweet]; match crayons[0] { Bittersweet => draw_scene(crayons[0]), _ => () @@ -1265,7 +1274,7 @@ match crayons[0] { A vector can be destructured using pattern matching: ~~~~ -let numbers: [int * 3] = [1, 2, 3]; +let numbers: [int, ..3] = [1, 2, 3]; let score = match numbers { [] => 0, [a] => a * 10, @@ -1759,32 +1768,25 @@ s.draw_borrowed(); (&@~s).draw_borrowed(); ~~~ -Implementations may also define _static_ methods, -which don't have an explicit `self` argument. -The `static` keyword distinguishes static methods from methods that have a `self`: +Implementations may also define standalone (sometimes called "static") +methods. The absence of a `self` paramater distinguishes such methods. +These methods are the preferred way to define constructor functions. ~~~~ {.xfail-test} impl Circle { fn area(&self) -> float { ... } - static fn new(area: float) -> Circle { ... } + fn new(area: float) -> Circle { ... } } ~~~~ -> ***Note***: In the future the `static` keyword will be removed and static methods -> will be distinguished solely by the presence or absence of the `self` argument. -> In the current langugage instance methods may also be declared without an explicit -> `self` argument, in which case `self` is an implicit reference. -> That form of method is deprecated. - -Constructors are one common application for static methods, as in `new` above. -To call a static method, you have to prefix it with the type name and a double colon: +To call such a method, just prefix it with the type name and a double colon: ~~~~ # use core::float::consts::pi; # use core::float::sqrt; struct Circle { radius: float } impl Circle { - static fn new(area: float) -> Circle { Circle { radius: sqrt(area / pi) } } + fn new(area: float) -> Circle { Circle { radius: sqrt(area / pi) } } } let c = Circle::new(42.5); ~~~~ @@ -2046,22 +2048,23 @@ second parameter of type `self`. In contrast, in the `impl`, `equals` takes a second parameter of type `int`, only using `self` as the name of the receiver. -Traits can also define static methods which are called by prefixing -the method name with the trait name. -The compiler will use type inference to decide which implementation to call. +Just as in type implementations, traits can define standalone (static) +methods. These methods are called by prefixing the method name with the trait +name and a double colon. The compiler uses type inference to decide which +implementation to use. ~~~~ -trait Shape { static fn new(area: float) -> Self; } +trait Shape { fn new(area: float) -> Self; } # use core::float::consts::pi; # use core::float::sqrt; struct Circle { radius: float } struct Square { length: float } impl Shape for Circle { - static fn new(area: float) -> Circle { Circle { radius: sqrt(area / pi) } } + fn new(area: float) -> Circle { Circle { radius: sqrt(area / pi) } } } impl Shape for Square { - static fn new(area: float) -> Square { Square { length: sqrt(area) } } + fn new(area: float) -> Square { Square { length: sqrt(area) } } } let area = 42.5; @@ -2303,7 +2306,7 @@ them. The `pub` keyword modifies an item's visibility, making it visible outside its containing module. An expression with `::`, like `farm::chicken`, can name an item outside of its containing module. Items, such as those declared with `fn`, `struct`, `enum`, -`type`, or `const`, are module-private by default. +`type`, or `static`, are module-private by default. Visibility restrictions in Rust exist only at module boundaries. This is quite different from most object-oriented languages that also diff --git a/mk/install.mk b/mk/install.mk index 3824d77586b3d..90679f0a116bf 100644 --- a/mk/install.mk +++ b/mk/install.mk @@ -113,11 +113,6 @@ install-host: $(CSREQ$(ISTAGE)_T_$(CFG_BUILD_TRIPLE)_H_$(CFG_BUILD_TRIPLE)) $(Q)$(call INSTALL,$(HB2),$(PHB),rustdoc$(X_$(CFG_BUILD_TRIPLE))) $(Q)$(call INSTALL,$(HB2),$(PHB),rusti$(X_$(CFG_BUILD_TRIPLE))) $(Q)$(call INSTALL,$(HB2),$(PHB),rust$(X_$(CFG_BUILD_TRIPLE))) - $(Q)$(call INSTALL,$(HL),$(PHL),$(CFG_LIBRUSTC_$(CFG_BUILD_TRIPLE))) - $(Q)$(call INSTALL,$(HL),$(PHL),$(CFG_LIBRUSTPKG_$(CFG_BUILD_TRIPLE))) - $(Q)$(call INSTALL,$(HL),$(PHL),$(CFG_LIBRUSTDOC_$(CFG_BUILD_TRIPLE))) - $(Q)$(call INSTALL,$(HL),$(PHL),$(CFG_LIBRUSTI_$(CFG_BUILD_TRIPLE))) - $(Q)$(call INSTALL,$(HL),$(PHL),$(CFG_LIBRUST_$(CFG_BUILD_TRIPLE))) $(Q)$(call INSTALL_LIB,$(HL),$(PHL),$(CORELIB_GLOB_$(CFG_BUILD_TRIPLE))) $(Q)$(call INSTALL_LIB,$(HL),$(PHL),$(STDLIB_GLOB_$(CFG_BUILD_TRIPLE))) $(Q)$(call INSTALL_LIB,$(HL),$(PHL),$(LIBRUSTC_GLOB_$(CFG_BUILD_TRIPLE))) @@ -142,11 +137,6 @@ uninstall: $(Q)rm -f $(PHB)/rust$(X_$(CFG_BUILD_TRIPLE)) $(Q)rm -f $(PHB)/rustdoc$(X_$(CFG_BUILD_TRIPLE)) $(Q)rm -f $(PHL)/$(CFG_RUSTLLVM_$(CFG_BUILD_TRIPLE)) - $(Q)rm -f $(PHL)/$(CFG_LIBRUSTPKG_$(CFG_BUILD_TRIPLE)) - $(Q)rm -f $(PHL)/$(CFG_LIBRUSTC_$(CFG_BUILD_TRIPLE)) - $(Q)rm -f $(PHL)/$(CFG_LIBRUSTDOC_$(CFG_BUILD_TRIPLE)) - $(Q)rm -f $(PHL)/$(CFG_LIBRUSTI_$(CFG_BUILD_TRIPLE)) - $(Q)rm -f $(PHL)/$(CFG_LIBRUST_$(CFG_BUILD_TRIPLE)) $(Q)rm -f $(PHL)/$(CFG_RUNTIME_$(CFG_BUILD_TRIPLE)) $(Q)for i in \ $(call HOST_LIB_FROM_HL_GLOB,$(CORELIB_GLOB_$(CFG_BUILD_TRIPLE))) \ diff --git a/mk/tests.mk b/mk/tests.mk index 33a828d6e6785..f96b7325f60d4 100644 --- a/mk/tests.mk +++ b/mk/tests.mk @@ -244,21 +244,29 @@ $(foreach host,$(CFG_HOST_TRIPLES), \ define TEST_RUNNER +# If NO_REBUILD is set then break the dependencies on std so we can +# test crates without rebuilding core and std first +ifeq ($(NO_REBUILD),) +STDTESTDEP_$(1)_$(2)_$(3) = $$(TLIB$(1)_T_$(2)_H_$(3))/$$(CFG_STDLIB_$(2)) +else +STDTESTDEP_$(1)_$(2)_$(3) = +endif + $(3)/test/coretest.stage$(1)-$(2)$$(X_$(2)): \ $$(CORELIB_CRATE) $$(CORELIB_INPUTS) \ - $$(TLIB$(1)_T_$(2)_H_$(3))/$$(CFG_STDLIB_$(2)) + $$(STDTESTDEP_$(1)_$(2)_$(3)) @$$(call E, compile_and_link: $$@) $$(STAGE$(1)_T_$(2)_H_$(3)) -o $$@ $$< --test $(3)/test/stdtest.stage$(1)-$(2)$$(X_$(2)): \ $$(STDLIB_CRATE) $$(STDLIB_INPUTS) \ - $$(TLIB$(1)_T_$(2)_H_$(3))/$$(CFG_STDLIB_$(2)) + $$(STDTESTDEP_$(1)_$(2)_$(3)) @$$(call E, compile_and_link: $$@) $$(STAGE$(1)_T_$(2)_H_$(3)) -o $$@ $$< --test $(3)/test/syntaxtest.stage$(1)-$(2)$$(X_$(2)): \ $$(LIBSYNTAX_CRATE) $$(LIBSYNTAX_INPUTS) \ - $$(TLIB$(1)_T_$(2)_H_$(3))/$$(CFG_STDLIB_$(2)) + $$(STDTESTDEP_$(1)_$(2)_$(3)) @$$(call E, compile_and_link: $$@) $$(STAGE$(1)_T_$(2)_H_$(3)) -o $$@ $$< --test diff --git a/src/compiletest/common.rs b/src/compiletest/common.rs index b7c4e26c4b15c..f892e3a1e232a 100644 --- a/src/compiletest/common.rs +++ b/src/compiletest/common.rs @@ -10,7 +10,7 @@ use core::prelude::*; -#[deriving_eq] +#[deriving(Eq)] pub enum mode { mode_compile_fail, mode_run_fail, @@ -63,6 +63,9 @@ pub struct config { // Run tests using the JIT jit: bool, + // Run tests using the new runtime + newrt: bool, + // Explain what's going on verbose: bool diff --git a/src/compiletest/compiletest.rc b/src/compiletest/compiletest.rc index 7d53b29e04029..0c1f328ad09fa 100644 --- a/src/compiletest/compiletest.rc +++ b/src/compiletest/compiletest.rc @@ -61,7 +61,8 @@ pub fn parse_config(args: ~[~str]) -> config { getopts::optopt(~"runtool"), getopts::optopt(~"rustcflags"), getopts::optflag(~"verbose"), getopts::optopt(~"logfile"), - getopts::optflag(~"jit")]; + getopts::optflag(~"jit"), + getopts::optflag(~"newrt")]; fail_unless!(!args.is_empty()); let args_ = vec::tail(args); @@ -95,6 +96,7 @@ pub fn parse_config(args: ~[~str]) -> config { runtool: getopts::opt_maybe_str(matches, ~"runtool"), rustcflags: getopts::opt_maybe_str(matches, ~"rustcflags"), jit: getopts::opt_present(matches, ~"jit"), + newrt: getopts::opt_present(matches, ~"newrt"), verbose: getopts::opt_present(matches, ~"verbose") } } @@ -114,6 +116,7 @@ pub fn log_config(config: config) { logv(c, fmt!("runtool: %s", opt_str(config.runtool))); logv(c, fmt!("rustcflags: %s", opt_str(config.rustcflags))); logv(c, fmt!("jit: %b", config.jit)); + logv(c, fmt!("newrt: %b", config.newrt)); logv(c, fmt!("verbose: %b", config.verbose)); logv(c, fmt!("\n")); } diff --git a/src/compiletest/errors.rs b/src/compiletest/errors.rs index 16af0a4b5752d..63b5c64c6d4a6 100644 --- a/src/compiletest/errors.rs +++ b/src/compiletest/errors.rs @@ -51,11 +51,11 @@ fn parse_expected(line_num: uint, line: ~str) -> ~[ExpectedError] { while idx < len && line[idx] == (' ' as u8) { idx += 1u; } let start_kind = idx; while idx < len && line[idx] != (' ' as u8) { idx += 1u; } - let kind = str::to_lower(str::slice(line, start_kind, idx)); + let kind = str::to_lower(str::slice(line, start_kind, idx).to_owned()); // Extract msg: while idx < len && line[idx] == (' ' as u8) { idx += 1u; } - let msg = str::slice(line, idx, len); + let msg = str::slice(line, idx, len).to_owned(); debug!("line=%u kind=%s msg=%s", line_num - adjust_line, kind, msg); diff --git a/src/compiletest/header.rs b/src/compiletest/header.rs index 7d0a4d7dcc805..a039aaf56835a 100644 --- a/src/compiletest/header.rs +++ b/src/compiletest/header.rs @@ -175,7 +175,7 @@ fn parse_name_value_directive(line: ~str, match str::find_str(line, keycolon) { Some(colon) => { let value = str::slice(line, colon + str::len(keycolon), - str::len(line)); + str::len(line)).to_owned(); debug!("%s: %s", directive, value); Some(value) } diff --git a/src/compiletest/runtest.rs b/src/compiletest/runtest.rs index 2eb44ba6815e3..f17e9ffe548bd 100644 --- a/src/compiletest/runtest.rs +++ b/src/compiletest/runtest.rs @@ -81,7 +81,7 @@ fn run_rfail_test(config: config, props: TestProps, testfile: &Path) { }; // The value our Makefile configures valgrind to return on failure - const valgrind_err: int = 100; + static valgrind_err: int = 100; if ProcRes.status == valgrind_err { fatal_ProcRes(~"run-fail test isn't valgrind-clean!", ProcRes); } @@ -92,7 +92,7 @@ fn run_rfail_test(config: config, props: TestProps, testfile: &Path) { fn check_correct_failure_status(ProcRes: ProcRes) { // The value the rust runtime returns on failure - const rust_err: int = 101; + static rust_err: int = 101; if ProcRes.status != rust_err { fatal_ProcRes( fmt!("failure produced the wrong error code: %d", @@ -267,7 +267,7 @@ fn run_debuginfo_test(config: config, props: TestProps, testfile: &Path) { // check if each line in props.check_lines appears in the // output (in order) let mut i = 0u; - for str::lines(ProcRes.stdout).each |line| { + for str::lines_each(ProcRes.stdout) |line| { if props.check_lines[i].trim() == line.trim() { i += 1u; } @@ -297,8 +297,8 @@ fn check_error_patterns(props: TestProps, let mut next_err_idx = 0u; let mut next_err_pat = props.error_patterns[next_err_idx]; let mut done = false; - for str::split_char(ProcRes.stderr, '\n').each |line| { - if str::contains(*line, next_err_pat) { + for str::lines_each(ProcRes.stderr) |line| { + if str::contains(line, next_err_pat) { debug!("found error pattern %s", next_err_pat); next_err_idx += 1u; if next_err_idx == vec::len(props.error_patterns) { @@ -347,15 +347,15 @@ fn check_expected_errors(expected_errors: ~[errors::ExpectedError], // filename:line1:col1: line2:col2: *warning:* msg // where line1:col1: is the starting point, line2:col2: // is the ending point, and * represents ANSI color codes. - for str::split_char(ProcRes.stderr, '\n').each |line| { + for str::lines_each(ProcRes.stderr) |line| { let mut was_expected = false; for vec::eachi(expected_errors) |i, ee| { if !found_flags[i] { debug!("prefix=%s ee.kind=%s ee.msg=%s line=%s", - prefixes[i], ee.kind, ee.msg, *line); - if (str::starts_with(*line, prefixes[i]) && - str::contains(*line, ee.kind) && - str::contains(*line, ee.msg)) { + prefixes[i], ee.kind, ee.msg, line); + if (str::starts_with(line, prefixes[i]) && + str::contains(line, ee.kind) && + str::contains(line, ee.msg)) { found_flags[i] = true; was_expected = true; break; @@ -364,13 +364,13 @@ fn check_expected_errors(expected_errors: ~[errors::ExpectedError], } // ignore this msg which gets printed at the end - if str::contains(*line, ~"aborting due to") { + if str::contains(line, ~"aborting due to") { was_expected = true; } - if !was_expected && is_compiler_error_or_warning(*line) { + if !was_expected && is_compiler_error_or_warning(str::from_slice(line)) { fatal_ProcRes(fmt!("unexpected compiler error or warning: '%s'", - *line), + line), ProcRes); } } @@ -484,9 +484,17 @@ fn compile_test_(config: config, props: TestProps, fn exec_compiled_test(config: config, props: TestProps, testfile: &Path) -> ProcRes { + + // If testing the new runtime then set the RUST_NEWRT env var + let env = if config.newrt { + props.exec_env + ~[(~"RUST_NEWRT", ~"1")] + } else { + props.exec_env + }; + compose_and_run(config, testfile, make_run_args(config, props, testfile), - props.exec_env, + env, config.run_lib_path, None) } diff --git a/src/etc/kate/rust.xml b/src/etc/kate/rust.xml index 1551cebcf02c2..f0c057ff25b49 100644 --- a/src/etc/kate/rust.xml +++ b/src/etc/kate/rust.xml @@ -18,7 +18,6 @@ as break - const copy do drop @@ -29,18 +28,17 @@ if impl let - log loop match mod mut priv pub - pure ref return static struct + super trait unsafe use diff --git a/src/etc/x86.supp b/src/etc/x86.supp index 8c3fe7e6aa463..95508fa12d236 100644 --- a/src/etc/x86.supp +++ b/src/etc/x86.supp @@ -451,6 +451,21 @@ fun:*uv_loop_delete* } +{ + race-or-something-ask-pcwalton-0 + Memcheck:Value4 + fun:*task_start_wrapper* + ... +} + +{ + race-or-something-ask-pcwalton-1 + Memcheck:Value4 + ... + fun:*build_start_wrapper* + ... +} + { lock_and_signal-probably-threadsafe-access-outside-of-lock Helgrind:Race diff --git a/src/libcore/at_vec.rs b/src/libcore/at_vec.rs index 8d3c8561957b0..dbc132899d90e 100644 --- a/src/libcore/at_vec.rs +++ b/src/libcore/at_vec.rs @@ -38,7 +38,7 @@ pub mod rustrt { /// Returns the number of elements the vector can hold without reallocating #[inline(always)] -pub pure fn capacity(v: @[const T]) -> uint { +pub fn capacity(v: @[const T]) -> uint { unsafe { let repr: **raw::VecRepr = ::cast::reinterpret_cast(&addr_of(&v)); @@ -59,8 +59,7 @@ pub pure fn capacity(v: @[const T]) -> uint { * onto the vector being constructed. */ #[inline(always)] -pub pure fn build_sized(size: uint, - builder: &fn(push: &pure fn(v: A))) -> @[A] { +pub fn build_sized(size: uint, builder: &fn(push: &fn(v: A))) -> @[A] { let mut vec: @[const A] = @[]; unsafe { raw::reserve(&mut vec, size); } builder(|+x| unsafe { raw::push(&mut vec, x) }); @@ -78,7 +77,7 @@ pub pure fn build_sized(size: uint, * onto the vector being constructed. */ #[inline(always)] -pub pure fn build(builder: &fn(push: &pure fn(v: A))) -> @[A] { +pub fn build(builder: &fn(push: &fn(v: A))) -> @[A] { build_sized(4, builder) } @@ -95,14 +94,15 @@ pub pure fn build(builder: &fn(push: &pure fn(v: A))) -> @[A] { * onto the vector being constructed. */ #[inline(always)] -pub pure fn build_sized_opt(size: Option, - builder: &fn(push: &pure fn(v: A))) -> @[A] { +pub fn build_sized_opt(size: Option, + builder: &fn(push: &fn(v: A))) + -> @[A] { build_sized(size.get_or_default(4), builder) } // Appending #[inline(always)] -pub pure fn append(lhs: @[T], rhs: &[const T]) -> @[T] { +pub 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]); } @@ -111,7 +111,7 @@ pub pure fn append(lhs: @[T], rhs: &[const T]) -> @[T] { /// Apply a function to each element of a vector and return the results -pub pure fn map(v: &[T], f: &fn(x: &T) -> U) -> @[U] { +pub fn map(v: &[T], f: &fn(x: &T) -> U) -> @[U] { do build_sized(v.len()) |push| { for vec::each(v) |elem| { push(f(elem)); @@ -125,7 +125,7 @@ pub pure fn map(v: &[T], f: &fn(x: &T) -> U) -> @[U] { * Creates an immutable vector of size `n_elts` and initializes the elements * to the value returned by the function `op`. */ -pub pure fn from_fn(n_elts: uint, op: iter::InitOp) -> @[T] { +pub 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; } @@ -138,7 +138,7 @@ pub 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`. */ -pub pure fn from_elem(n_elts: uint, t: T) -> @[T] { +pub 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(copy t); i += 1u; } @@ -176,7 +176,7 @@ pub mod traits { impl Add<&'self [const T],@[T]> for @[T] { #[inline(always)] - pure fn add(&self, rhs: & &'self [const T]) -> @[T] { + fn add(&self, rhs: & &'self [const T]) -> @[T] { append(*self, (*rhs)) } } @@ -291,7 +291,7 @@ pub fn test() { } } - fail_unless!(seq_range(10, 15) == @[10, 11, 12, 13, 14]); + assert_eq!(seq_range(10, 15), @[10, 11, 12, 13, 14]); fail_unless!(from_fn(5, |x| x+1) == @[1, 2, 3, 4, 5]); fail_unless!(from_elem(5, 3.14) == @[3.14, 3.14, 3.14, 3.14, 3.14]); } diff --git a/src/libcore/bool.rs b/src/libcore/bool.rs index 512855d8f86c0..2b669a285b31c 100644 --- a/src/libcore/bool.rs +++ b/src/libcore/bool.rs @@ -17,39 +17,39 @@ use from_str::FromStr; #[cfg(notest)] use cmp; /// Negation / inverse -pub pure fn not(v: bool) -> bool { !v } +pub fn not(v: bool) -> bool { !v } /// Conjunction -pub pure fn and(a: bool, b: bool) -> bool { a && b } +pub fn and(a: bool, b: bool) -> bool { a && b } /// Disjunction -pub pure fn or(a: bool, b: bool) -> bool { a || b } +pub fn or(a: bool, b: bool) -> bool { a || b } /** * Exclusive or * * Identical to `or(and(a, not(b)), and(not(a), b))` */ -pub pure fn xor(a: bool, b: bool) -> bool { (a && !b) || (!a && b) } +pub fn xor(a: bool, b: bool) -> bool { (a && !b) || (!a && b) } /// Implication in the logic, i.e. from `a` follows `b` -pub pure fn implies(a: bool, b: bool) -> bool { !a || b } +pub fn implies(a: bool, b: bool) -> bool { !a || b } /// true if truth values `a` and `b` are indistinguishable in the logic -pub pure fn eq(a: bool, b: bool) -> bool { a == b } +pub fn eq(a: bool, b: bool) -> bool { a == b } /// true if truth values `a` and `b` are distinguishable in the logic -pub pure fn ne(a: bool, b: bool) -> bool { a != b } +pub fn ne(a: bool, b: bool) -> bool { a != b } /// true if `v` represents truth in the logic -pub pure fn is_true(v: bool) -> bool { v } +pub fn is_true(v: bool) -> bool { v } /// true if `v` represents falsehood in the logic -pub pure fn is_false(v: bool) -> bool { !v } +pub fn is_false(v: bool) -> bool { !v } /// Parse logic value from `s` impl FromStr for bool { - static pure fn from_str(s: &str) -> Option { + fn from_str(s: &str) -> Option { if s == "true" { Some(true) } else if s == "false" { @@ -61,7 +61,7 @@ impl FromStr for bool { } /// Convert `v` into a string -pub pure fn to_str(v: bool) -> ~str { if v { ~"true" } else { ~"false" } } +pub fn to_str(v: bool) -> ~str { if v { ~"true" } else { ~"false" } } /** * Iterates over all truth values by passing them to `blk` in an unspecified @@ -73,12 +73,12 @@ pub fn all_values(blk: &fn(v: bool)) { } /// converts truth value to an 8 bit byte -pub pure fn to_bit(v: bool) -> u8 { if v { 1u8 } else { 0u8 } } +pub fn to_bit(v: bool) -> u8 { if v { 1u8 } else { 0u8 } } #[cfg(notest)] impl cmp::Eq for bool { - pure fn eq(&self, other: &bool) -> bool { (*self) == (*other) } - pure fn ne(&self, other: &bool) -> bool { (*self) != (*other) } + fn eq(&self, other: &bool) -> bool { (*self) == (*other) } + fn ne(&self, other: &bool) -> bool { (*self) != (*other) } } #[test] diff --git a/src/libcore/cell.rs b/src/libcore/cell.rs index cfd1b8dfef000..bf5f93159381a 100644 --- a/src/libcore/cell.rs +++ b/src/libcore/cell.rs @@ -21,14 +21,14 @@ pub struct Cell { } impl cmp::Eq for Cell { - pure fn eq(&self, other: &Cell) -> bool { + fn eq(&self, other: &Cell) -> bool { unsafe { let frozen_self: &Option = transmute(&mut self.value); let frozen_other: &Option = transmute(&mut other.value); frozen_self == frozen_other } } - pure fn ne(&self, other: &Cell) -> bool { !self.eq(other) } + fn ne(&self, other: &Cell) -> bool { !self.eq(other) } } /// Creates a new full cell with the given value. @@ -36,7 +36,7 @@ pub fn Cell(value: T) -> Cell { Cell { value: Some(value) } } -pub pure fn empty_cell() -> Cell { +pub fn empty_cell() -> Cell { Cell { value: None } } @@ -61,7 +61,7 @@ pub impl Cell { } /// Returns true if the cell is empty and false if the cell is full. - pure fn is_empty(&self) -> bool { + fn is_empty(&self) -> bool { self.value.is_none() } diff --git a/src/libcore/char.rs b/src/libcore/char.rs index 7922103029b51..027329a235544 100644 --- a/src/libcore/char.rs +++ b/src/libcore/char.rs @@ -61,7 +61,7 @@ pub use is_XID_continue = unicode::derived_property::XID_Continue; * in terms of the Unicode General Category 'Ll' */ #[inline(always)] -pub pure fn is_lowercase(c: char) -> bool { +pub fn is_lowercase(c: char) -> bool { return unicode::general_category::Ll(c); } @@ -70,7 +70,7 @@ pub pure fn is_lowercase(c: char) -> bool { * in terms of the Unicode General Category 'Lu'. */ #[inline(always)] -pub pure fn is_uppercase(c: char) -> bool { +pub fn is_uppercase(c: char) -> bool { return unicode::general_category::Lu(c); } @@ -80,7 +80,7 @@ pub pure fn is_uppercase(c: char) -> bool { * additional 'Cc'-category control codes in the range [0x09, 0x0d] */ #[inline(always)] -pub pure fn is_whitespace(c: char) -> bool { +pub fn is_whitespace(c: char) -> bool { return ('\x09' <= c && c <= '\x0d') || unicode::general_category::Zs(c) || unicode::general_category::Zl(c) @@ -93,7 +93,7 @@ pub pure fn is_whitespace(c: char) -> bool { * and the Derived Core Property 'Alphabetic'. */ #[inline(always)] -pub pure fn is_alphanumeric(c: char) -> bool { +pub fn is_alphanumeric(c: char) -> bool { return unicode::derived_property::Alphabetic(c) || unicode::general_category::Nd(c) || unicode::general_category::Nl(c) || @@ -102,13 +102,13 @@ pub pure fn is_alphanumeric(c: char) -> bool { /// Indicates whether the character is an ASCII character #[inline(always)] -pub pure fn is_ascii(c: char) -> bool { +pub fn is_ascii(c: char) -> bool { c - ('\x7F' & c) == '\x00' } /// Indicates whether the character is numeric (Nd, Nl, or No) #[inline(always)] -pub pure fn is_digit(c: char) -> bool { +pub fn is_digit(c: char) -> bool { return unicode::general_category::Nd(c) || unicode::general_category::Nl(c) || unicode::general_category::No(c); @@ -127,7 +127,7 @@ pub pure fn is_digit(c: char) -> bool { * Note: This just wraps `to_digit()`. */ #[inline(always)] -pub pure fn is_digit_radix(c: char, radix: uint) -> bool { +pub fn is_digit_radix(c: char, radix: uint) -> bool { match to_digit(c, radix) { Some(_) => true, None => false @@ -148,7 +148,7 @@ pub pure fn is_digit_radix(c: char, radix: uint) -> bool { * Fails if given a `radix` outside the range `[0..36]`. */ #[inline] -pub pure fn to_digit(c: char, radix: uint) -> Option { +pub fn to_digit(c: char, radix: uint) -> Option { if radix > 36 { fail!(fmt!("to_digit: radix %? is to high (maximum 36)", radix)); } @@ -171,7 +171,7 @@ pub pure fn to_digit(c: char, radix: uint) -> Option { * Fails if given an `radix` > 36. */ #[inline] -pub pure fn from_digit(num: uint, radix: uint) -> Option { +pub fn from_digit(num: uint, radix: uint) -> Option { if radix > 36 { fail!(fmt!("from_digit: radix %? is to high (maximum 36)", num)); } @@ -195,7 +195,7 @@ pub pure fn from_digit(num: uint, radix: uint) -> Option { * - chars in [0x100,0xffff] get 4-digit escapes: `\\uNNNN` * - chars above 0x10000 get 8-digit escapes: `\\UNNNNNNNN` */ -pub pure fn escape_unicode(c: char) -> ~str { +pub fn escape_unicode(c: char) -> ~str { let s = u32::to_str_radix(c as u32, 16u); let (c, pad) = (if c <= '\xff' { ('x', 2u) } else if c <= '\uffff' { ('u', 4u) } @@ -223,7 +223,7 @@ pub pure 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`. */ -pub pure fn escape_default(c: char) -> ~str { +pub fn escape_default(c: char) -> ~str { match c { '\t' => ~"\\t", '\r' => ~"\\r", @@ -244,7 +244,7 @@ pub pure fn escape_default(c: char) -> ~str { * -1 if a < b, 0 if a == b, +1 if a > b */ #[inline(always)] -pub pure fn cmp(a: char, b: char) -> int { +pub fn cmp(a: char, b: char) -> int { return if b > a { -1 } else if b < a { 1 } else { 0 } @@ -252,8 +252,8 @@ pub pure fn cmp(a: char, b: char) -> int { #[cfg(notest)] impl Eq for char { - pure fn eq(&self, other: &char) -> bool { (*self) == (*other) } - pure fn ne(&self, other: &char) -> bool { (*self) != (*other) } + fn eq(&self, other: &char) -> bool { (*self) == (*other) } + fn ne(&self, other: &char) -> bool { (*self) != (*other) } } #[test] @@ -288,16 +288,16 @@ fn test_is_whitespace() { #[test] fn test_to_digit() { - fail_unless!(to_digit('0', 10u) == Some(0u)); - fail_unless!(to_digit('1', 2u) == Some(1u)); - fail_unless!(to_digit('2', 3u) == Some(2u)); - fail_unless!(to_digit('9', 10u) == Some(9u)); - fail_unless!(to_digit('a', 16u) == Some(10u)); - fail_unless!(to_digit('A', 16u) == Some(10u)); - fail_unless!(to_digit('b', 16u) == Some(11u)); - fail_unless!(to_digit('B', 16u) == Some(11u)); - fail_unless!(to_digit('z', 36u) == Some(35u)); - fail_unless!(to_digit('Z', 36u) == Some(35u)); + assert_eq!(to_digit('0', 10u), Some(0u)); + assert_eq!(to_digit('1', 2u), Some(1u)); + assert_eq!(to_digit('2', 3u), Some(2u)); + assert_eq!(to_digit('9', 10u), Some(9u)); + assert_eq!(to_digit('a', 16u), Some(10u)); + assert_eq!(to_digit('A', 16u), Some(10u)); + assert_eq!(to_digit('b', 16u), Some(11u)); + assert_eq!(to_digit('B', 16u), Some(11u)); + assert_eq!(to_digit('z', 36u), Some(35u)); + assert_eq!(to_digit('Z', 36u), Some(35u)); fail_unless!(to_digit(' ', 10u).is_none()); fail_unless!(to_digit('$', 36u).is_none()); @@ -321,28 +321,28 @@ fn test_is_digit() { #[test] fn test_escape_default() { - fail_unless!(escape_default('\n') == ~"\\n"); - fail_unless!(escape_default('\r') == ~"\\r"); - fail_unless!(escape_default('\'') == ~"\\'"); - fail_unless!(escape_default('"') == ~"\\\""); - fail_unless!(escape_default(' ') == ~" "); - fail_unless!(escape_default('a') == ~"a"); - fail_unless!(escape_default('~') == ~"~"); - fail_unless!(escape_default('\x00') == ~"\\x00"); - fail_unless!(escape_default('\x1f') == ~"\\x1f"); - fail_unless!(escape_default('\x7f') == ~"\\x7f"); - fail_unless!(escape_default('\xff') == ~"\\xff"); - fail_unless!(escape_default('\u011b') == ~"\\u011b"); - fail_unless!(escape_default('\U0001d4b6') == ~"\\U0001d4b6"); + assert_eq!(escape_default('\n'), ~"\\n"); + assert_eq!(escape_default('\r'), ~"\\r"); + assert_eq!(escape_default('\''), ~"\\'"); + assert_eq!(escape_default('"'), ~"\\\""); + assert_eq!(escape_default(' '), ~" "); + assert_eq!(escape_default('a'), ~"a"); + assert_eq!(escape_default('~'), ~"~"); + assert_eq!(escape_default('\x00'), ~"\\x00"); + assert_eq!(escape_default('\x1f'), ~"\\x1f"); + assert_eq!(escape_default('\x7f'), ~"\\x7f"); + assert_eq!(escape_default('\xff'), ~"\\xff"); + assert_eq!(escape_default('\u011b'), ~"\\u011b"); + assert_eq!(escape_default('\U0001d4b6'), ~"\\U0001d4b6"); } #[test] fn test_escape_unicode() { - fail_unless!(escape_unicode('\x00') == ~"\\x00"); - fail_unless!(escape_unicode('\n') == ~"\\x0a"); - fail_unless!(escape_unicode(' ') == ~"\\x20"); - fail_unless!(escape_unicode('a') == ~"\\x61"); - fail_unless!(escape_unicode('\u011b') == ~"\\u011b"); - fail_unless!(escape_unicode('\U0001d4b6') == ~"\\U0001d4b6"); + assert_eq!(escape_unicode('\x00'), ~"\\x00"); + assert_eq!(escape_unicode('\n'), ~"\\x0a"); + assert_eq!(escape_unicode(' '), ~"\\x20"); + assert_eq!(escape_unicode('a'), ~"\\x61"); + assert_eq!(escape_unicode('\u011b'), ~"\\u011b"); + assert_eq!(escape_unicode('\U0001d4b6'), ~"\\U0001d4b6"); } diff --git a/src/libcore/cmp.rs b/src/libcore/cmp.rs index 81f6a7e426640..7c45ecae63234 100644 --- a/src/libcore/cmp.rs +++ b/src/libcore/cmp.rs @@ -33,20 +33,20 @@ and `Eq` to overload the `==` and `!=` operators. */ #[lang="eq"] pub trait Eq { - pure fn eq(&self, other: &Self) -> bool; - pure fn ne(&self, other: &Self) -> bool; + fn eq(&self, other: &Self) -> bool; + fn ne(&self, other: &Self) -> bool; } -#[deriving_eq] +#[deriving(Eq)] pub enum Ordering { Less, Equal, Greater } /// Trait for types that form a total order pub trait TotalOrd { - pure fn cmp(&self, other: &Self) -> Ordering; + fn cmp(&self, other: &Self) -> Ordering; } #[inline(always)] -pure fn icmp(a: &T, b: &T) -> Ordering { +fn icmp(a: &T, b: &T) -> Ordering { if *a < *b { Less } else if *a > *b { Greater } else { Equal } @@ -54,52 +54,52 @@ pure fn icmp(a: &T, b: &T) -> Ordering { impl TotalOrd for u8 { #[inline(always)] - pure fn cmp(&self, other: &u8) -> Ordering { icmp(self, other) } + fn cmp(&self, other: &u8) -> Ordering { icmp(self, other) } } impl TotalOrd for u16 { #[inline(always)] - pure fn cmp(&self, other: &u16) -> Ordering { icmp(self, other) } + fn cmp(&self, other: &u16) -> Ordering { icmp(self, other) } } impl TotalOrd for u32 { #[inline(always)] - pure fn cmp(&self, other: &u32) -> Ordering { icmp(self, other) } + fn cmp(&self, other: &u32) -> Ordering { icmp(self, other) } } impl TotalOrd for u64 { #[inline(always)] - pure fn cmp(&self, other: &u64) -> Ordering { icmp(self, other) } + fn cmp(&self, other: &u64) -> Ordering { icmp(self, other) } } impl TotalOrd for i8 { #[inline(always)] - pure fn cmp(&self, other: &i8) -> Ordering { icmp(self, other) } + fn cmp(&self, other: &i8) -> Ordering { icmp(self, other) } } impl TotalOrd for i16 { #[inline(always)] - pure fn cmp(&self, other: &i16) -> Ordering { icmp(self, other) } + fn cmp(&self, other: &i16) -> Ordering { icmp(self, other) } } impl TotalOrd for i32 { #[inline(always)] - pure fn cmp(&self, other: &i32) -> Ordering { icmp(self, other) } + fn cmp(&self, other: &i32) -> Ordering { icmp(self, other) } } impl TotalOrd for i64 { #[inline(always)] - pure fn cmp(&self, other: &i64) -> Ordering { icmp(self, other) } + fn cmp(&self, other: &i64) -> Ordering { icmp(self, other) } } impl TotalOrd for int { #[inline(always)] - pure fn cmp(&self, other: &int) -> Ordering { icmp(self, other) } + fn cmp(&self, other: &int) -> Ordering { icmp(self, other) } } impl TotalOrd for uint { #[inline(always)] - pure fn cmp(&self, other: &uint) -> Ordering { icmp(self, other) } + fn cmp(&self, other: &uint) -> Ordering { icmp(self, other) } } /** @@ -114,39 +114,39 @@ impl TotalOrd for uint { */ #[lang="ord"] pub trait Ord { - pure fn lt(&self, other: &Self) -> bool; - pure fn le(&self, other: &Self) -> bool; - pure fn ge(&self, other: &Self) -> bool; - pure fn gt(&self, other: &Self) -> bool; + fn lt(&self, other: &Self) -> bool; + fn le(&self, other: &Self) -> bool; + fn ge(&self, other: &Self) -> bool; + fn gt(&self, other: &Self) -> bool; } #[inline(always)] -pub pure fn lt(v1: &T, v2: &T) -> bool { +pub fn lt(v1: &T, v2: &T) -> bool { (*v1).lt(v2) } #[inline(always)] -pub pure fn le(v1: &T, v2: &T) -> bool { +pub fn le(v1: &T, v2: &T) -> bool { (*v1).le(v2) } #[inline(always)] -pub pure fn eq(v1: &T, v2: &T) -> bool { +pub fn eq(v1: &T, v2: &T) -> bool { (*v1).eq(v2) } #[inline(always)] -pub pure fn ne(v1: &T, v2: &T) -> bool { +pub fn ne(v1: &T, v2: &T) -> bool { (*v1).ne(v2) } #[inline(always)] -pub pure fn ge(v1: &T, v2: &T) -> bool { +pub fn ge(v1: &T, v2: &T) -> bool { (*v1).ge(v2) } #[inline(always)] -pub pure fn gt(v1: &T, v2: &T) -> bool { +pub fn gt(v1: &T, v2: &T) -> bool { (*v1).gt(v2) } @@ -155,16 +155,16 @@ pub pure fn gt(v1: &T, v2: &T) -> bool { /// container types; e.g. it is often desirable to be able to use `&str` /// values to look up entries in a container with `~str` keys. pub trait Equiv { - pure fn equiv(&self, other: &T) -> bool; + fn equiv(&self, other: &T) -> bool; } #[inline(always)] -pub pure fn min(v1: T, v2: T) -> T { +pub fn min(v1: T, v2: T) -> T { if v1 < v2 { v1 } else { v2 } } #[inline(always)] -pub pure fn max(v1: T, v2: T) -> T { +pub fn max(v1: T, v2: T) -> T { if v1 > v2 { v1 } else { v2 } } @@ -172,10 +172,10 @@ pub pure fn max(v1: T, v2: T) -> T { mod test { #[test] fn test_int() { - fail_unless!(5.cmp(&10) == Less); - fail_unless!(10.cmp(&5) == Greater); - fail_unless!(5.cmp(&5) == Equal); - fail_unless!((-5).cmp(&12) == Less); - fail_unless!(12.cmp(-5) == Greater); + assert_eq!(5.cmp(&10), Less); + assert_eq!(10.cmp(&5), Greater); + assert_eq!(5.cmp(&5), Equal); + assert_eq!((-5).cmp(&12), Less); + assert_eq!(12.cmp(-5), Greater); } } diff --git a/src/libcore/comm.rs b/src/libcore/comm.rs index 12dc2d7e34158..6dadca8dc57ba 100644 --- a/src/libcore/comm.rs +++ b/src/libcore/comm.rs @@ -50,7 +50,7 @@ pub trait GenericPort { /// Ports that can `peek` pub trait Peekable { /// Returns true if a message is available - pure fn peek(&self) -> bool; + fn peek(&self) -> bool; } /// Returns the index of an endpoint that is ready to receive. @@ -108,8 +108,6 @@ pub fn stream() -> (Port, Chan) { // Add an inherent method so that imports of GenericChan are not // required. -#[cfg(stage1)] -#[cfg(stage2)] pub impl Chan { fn send(&self, x: T) { chan_send(self, x) } fn try_send(&self, x: T) -> bool { chan_try_send(self, x) } @@ -147,12 +145,10 @@ fn chan_try_send(self: &Chan, x: T) -> bool { } // Use an inherent impl so that imports are not required: -#[cfg(stage1)] -#[cfg(stage2)] pub impl Port { fn recv(&self) -> T { port_recv(self) } fn try_recv(&self) -> Option { port_try_recv(self) } - pure fn peek(&self) -> bool { port_peek(self) } + fn peek(&self) -> bool { port_peek(self) } } impl GenericPort for Port { @@ -184,11 +180,11 @@ fn port_try_recv(self: &Port) -> Option { } impl Peekable for Port { - pure fn peek(&self) -> bool { port_peek(self) } + fn peek(&self) -> bool { port_peek(self) } } #[inline(always)] -pure fn port_peek(self: &Port) -> bool { +fn port_peek(self: &Port) -> bool { unsafe { let mut endp = None; endp <-> self.endp; @@ -202,7 +198,7 @@ pure fn port_peek(self: &Port) -> bool { } impl Selectable for Port { - pure fn header(&self) -> *PacketHeader { + fn header(&self) -> *PacketHeader { unsafe { match self.endp { Some(ref endp) => endp.header(), @@ -224,12 +220,10 @@ pub fn PortSet() -> PortSet{ } // Use an inherent impl so that imports are not required: -#[cfg(stage1)] -#[cfg(stage2)] pub impl PortSet { fn recv(&self) -> T { port_set_recv(self) } fn try_recv(&self) -> Option { port_set_try_recv(self) } - pure fn peek(&self) -> bool { port_set_peek(self) } + fn peek(&self) -> bool { port_set_peek(self) } } pub impl PortSet { @@ -278,11 +272,11 @@ fn port_set_try_recv(self: &PortSet) -> Option { } impl Peekable for PortSet { - pure fn peek(&self) -> bool { port_set_peek(self) } + fn peek(&self) -> bool { port_set_peek(self) } } #[inline(always)] -pure fn port_set_peek(self: &PortSet) -> bool { +fn port_set_peek(self: &PortSet) -> bool { // It'd be nice to use self.port.each, but that version isn't // pure. for uint::range(0, vec::uniq_len(&const self.ports)) |i| { @@ -299,8 +293,6 @@ pure fn port_set_peek(self: &PortSet) -> bool { /// A channel that can be shared between many senders. pub type SharedChan = unstable::Exclusive>; -#[cfg(stage1)] -#[cfg(stage2)] pub impl SharedChan { fn send(&self, x: T) { shared_chan_send(self, x) } fn try_send(&self, x: T) -> bool { shared_chan_try_send(self, x) } diff --git a/src/libcore/condition.rs b/src/libcore/condition.rs index 56b690ca8afd8..767b6ecfad4b8 100644 --- a/src/libcore/condition.rs +++ b/src/libcore/condition.rs @@ -22,11 +22,11 @@ pub struct Handler { pub struct Condition { name: &'static str, - key: task::local_data::LocalDataKey/&self> + key: task::local_data::LocalDataKey<'self, Handler> } -pub impl Condition/&self { - fn trap(&self, h: &'self fn(T) -> U) -> Trap/&self { +pub impl Condition<'self, T, U> { + fn trap(&self, h: &'self fn(T) -> U) -> Trap<'self, T, U> { unsafe { let p : *RustClosure = ::cast::transmute(&h); let prev = task::local_data::local_data_get(self.key); @@ -65,11 +65,11 @@ pub impl Condition/&self { } struct Trap { - cond: &'self Condition/&self, + cond: &'self Condition<'self, T, U>, handler: @Handler } -pub impl Trap/&self { +pub impl Trap<'self, T, U> { fn in(&self, inner: &'self fn() -> V) -> V { unsafe { let _g = Guard { cond: self.cond }; @@ -81,10 +81,11 @@ pub impl Trap/&self { } struct Guard { - cond: &'self Condition/&self + cond: &'self Condition<'self, T, U> } -impl Drop for Guard/&self { +#[unsafe_destructor] +impl Drop for Guard<'self, T, U> { fn finalize(&self) { unsafe { debug!("Guard: popping handler from TLS"); diff --git a/src/libcore/container.rs b/src/libcore/container.rs index 5044b3a6c5de1..e20821b919b6c 100644 --- a/src/libcore/container.rs +++ b/src/libcore/container.rs @@ -14,10 +14,10 @@ use option::Option; pub trait Container { /// Return the number of elements in the container - pure fn len(&const self) -> uint; + fn len(&const self) -> uint; /// Return true if the container contains no elements - pure fn is_empty(&const self) -> bool; + fn is_empty(&const self) -> bool; } pub trait Mutable: Container { @@ -27,19 +27,22 @@ pub trait Mutable: Container { pub trait Map: Mutable { /// Return true if the map contains a value for the specified key - pure fn contains_key(&self, key: &K) -> bool; + fn contains_key(&self, key: &K) -> bool; /// Visit all keys - pure fn each_key(&self, f: &fn(&K) -> bool); + fn each_key(&self, f: &fn(&K) -> bool); /// Visit all values - pure fn each_value(&self, f: &fn(&V) -> bool); + fn each_value(&self, f: &fn(&V) -> bool); /// Iterate over the map and mutate the contained values fn mutate_values(&mut self, f: &fn(&K, &mut V) -> bool); - /// Return the value corresponding to the key in the map - pure fn find(&self, key: &K) -> Option<&'self V>; + /// Return a reference to the value corresponding to the key + fn find(&self, key: &K) -> Option<&'self V>; + + /// Return a mutable reference to the value corresponding to the key + fn find_mut(&mut self, key: &K) -> Option<&'self mut V>; /// Insert a key-value pair into the map. An existing value for a /// key is replaced by the new value. Return true if the key did @@ -53,7 +56,7 @@ pub trait Map: Mutable { pub trait Set: Mutable { /// Return true if the set contains a value - pure fn contains(&self, value: &T) -> bool; + fn contains(&self, value: &T) -> bool; /// Add a value to the set. Return true if the value was not already /// present in the set. @@ -65,23 +68,23 @@ pub trait Set: Mutable { /// Return true if the set has no elements in common with `other`. /// This is equivalent to checking for an empty intersection. - pure fn is_disjoint(&self, other: &Self) -> bool; + fn is_disjoint(&self, other: &Self) -> bool; /// Return true if the set is a subset of another - pure fn is_subset(&self, other: &Self) -> bool; + fn is_subset(&self, other: &Self) -> bool; /// Return true if the set is a superset of another - pure fn is_superset(&self, other: &Self) -> bool; + fn is_superset(&self, other: &Self) -> bool; /// Visit the values representing the difference - pure fn difference(&self, other: &Self, f: &fn(&T) -> bool); + fn difference(&self, other: &Self, f: &fn(&T) -> bool); /// Visit the values representing the symmetric difference - pure fn symmetric_difference(&self, other: &Self, f: &fn(&T) -> bool); + fn symmetric_difference(&self, other: &Self, f: &fn(&T) -> bool); /// Visit the values representing the intersection - pure fn intersection(&self, other: &Self, f: &fn(&T) -> bool); + fn intersection(&self, other: &Self, f: &fn(&T) -> bool); /// Visit the values representing the union - pure fn union(&self, other: &Self, f: &fn(&T) -> bool); + fn union(&self, other: &Self, f: &fn(&T) -> bool); } diff --git a/src/libcore/core.rc b/src/libcore/core.rc index 955c1f46d76ba..f38227de49725 100644 --- a/src/libcore/core.rc +++ b/src/libcore/core.rc @@ -51,7 +51,6 @@ Implicitly, all crates behave as if they included the following prologue: #[warn(vecs_implicitly_copyable)]; #[deny(non_camel_case_types)]; #[allow(deprecated_mutable_fields)]; -#[deny(deprecated_self)]; #[allow(deprecated_drop)]; // On Linux, link to the runtime with -lrt. @@ -198,7 +197,7 @@ pub use path::WindowsPath; pub use path::PosixPath; pub use tuple::{CopyableTuple, ImmutableTuple, ExtendedTupleOps}; -pub use str::{StrSlice, Trimmable}; +pub use str::{StrSlice}; pub use container::{Container, Mutable}; pub use vec::{CopyableVector, ImmutableVector}; pub use vec::{ImmutableEqVector, ImmutableCopyableVector}; @@ -212,34 +211,10 @@ pub use to_str::ToStr; pub use clone::Clone; -/* - * Export the log levels as global constants. Higher levels mean - * more-verbosity. Error is the bottom level, default logging level is - * warn-and-below. - */ -/// The error log level -#[cfg(stage0)] -pub const error : u32 = 1_u32; -/// The warning log level -#[cfg(stage0)] -pub const warn : u32 = 2_u32; -/// The info log level -#[cfg(stage0)] -pub const info : u32 = 3_u32; -/// The debug log level -#[cfg(stage0)] -pub const debug : u32 = 4_u32; - - /* Unsupported interfaces */ // Private APIs pub mod unstable; -// NOTE: Remove after snapshot -#[cfg(stage0)] -pub mod private { - pub use super::unstable::extfmt; -} /* For internal use, not exported */ @@ -255,15 +230,7 @@ pub mod rt; // can be resolved within libcore. #[doc(hidden)] pub mod core { - #[cfg(stage0)] - pub const error : u32 = 1_u32; - #[cfg(stage0)] - pub const warn : u32 = 2_u32; - #[cfg(stage0)] - pub const info : u32 = 3_u32; - #[cfg(stage0)] - pub const debug : u32 = 4_u32; - + pub use clone; pub use cmp; pub use condition; pub use option; diff --git a/src/libcore/dlist.rs b/src/libcore/dlist.rs index 1b5d03d9eb8cd..ff86e8d1ffcdb 100644 --- a/src/libcore/dlist.rs +++ b/src/libcore/dlist.rs @@ -42,7 +42,7 @@ pub struct DList { } priv impl DListNode { - pure fn assert_links(@mut self) { + fn assert_links(@mut self) { match self.next { Some(neighbour) => match neighbour.prev { Some(me) => if !managed::mut_ptr_eq(self, me) { @@ -66,24 +66,24 @@ priv impl DListNode { pub impl DListNode { /// Get the next node in the list, if there is one. - pure fn next_link(@mut self) -> DListLink { + fn next_link(@mut self) -> DListLink { self.assert_links(); self.next } /// Get the next node in the list, failing if there isn't one. - pure fn next_node(@mut self) -> @mut DListNode { + fn next_node(@mut self) -> @mut DListNode { match self.next_link() { Some(nobe) => nobe, None => fail!(~"This dlist node has no next neighbour.") } } /// Get the previous node in the list, if there is one. - pure fn prev_link(@mut self) -> DListLink { + fn prev_link(@mut self) -> DListLink { self.assert_links(); self.prev } /// Get the previous node in the list, failing if there isn't one. - pure fn prev_node(@mut self) -> @mut DListNode { + fn prev_node(@mut self) -> @mut DListNode { match self.prev_link() { Some(nobe) => nobe, None => fail!(~"This dlist node has no previous neighbour.") @@ -92,17 +92,17 @@ pub impl DListNode { } /// Creates a new dlist node with the given data. -pub pure fn new_dlist_node(data: T) -> @mut DListNode { +pub fn new_dlist_node(data: T) -> @mut DListNode { @mut DListNode { data: data, linked: false, prev: None, next: None } } /// Creates a new, empty dlist. -pub pure fn DList() -> @mut DList { +pub fn DList() -> @mut DList { @mut DList { size: 0, hd: None, tl: None } } /// Creates a new dlist with a single element -pub pure fn from_elem(data: T) -> @mut DList { +pub fn from_elem(data: T) -> @mut DList { let list = DList(); unsafe { list.push(data); } list @@ -126,7 +126,7 @@ pub fn concat(lists: @mut DList<@mut DList>) -> @mut DList { } priv impl DList { - static pure fn new_link(data: T) -> DListLink { + fn new_link(data: T) -> DListLink { Some(@mut DListNode { data: data, linked: true, @@ -134,7 +134,7 @@ priv impl DList { next: None }) } - pure fn assert_mine(@mut self, nobe: @mut DListNode) { + fn assert_mine(@mut self, nobe: @mut DListNode) { // These asserts could be stronger if we had node-root back-pointers, // but those wouldn't allow for O(1) append. if self.size == 0 { @@ -212,9 +212,9 @@ priv impl DList { pub impl DList { /// Get the size of the list. O(1). - pure fn len(@mut self) -> uint { self.size } + fn len(@mut self) -> uint { self.size } /// Returns true if the list is empty. O(1). - pure fn is_empty(@mut self) -> bool { self.len() == 0 } + fn is_empty(@mut self) -> bool { self.len() == 0 } /// Add data to the head of the list. O(1). fn push_head(@mut self, data: T) { @@ -316,12 +316,12 @@ pub impl DList { tl } /// Get the node at the list's head. O(1). - pure fn peek_n(@mut self) -> DListLink { self.hd } + fn peek_n(@mut self) -> DListLink { self.hd } /// Get the node at the list's tail. O(1). - pure fn peek_tail_n(@mut self) -> DListLink { self.tl } + fn peek_tail_n(@mut self) -> DListLink { self.tl } /// Get the node at the list's head, failing if empty. O(1). - pure fn head_n(@mut self) -> @mut DListNode { + fn head_n(@mut self) -> @mut DListNode { match self.hd { Some(nobe) => nobe, None => fail!( @@ -329,7 +329,7 @@ pub impl DList { } } /// Get the node at the list's tail, failing if empty. O(1). - pure fn tail_n(@mut self) -> @mut DListNode { + fn tail_n(@mut self) -> @mut DListNode { match self.tl { Some(nobe) => nobe, None => fail!( @@ -399,7 +399,7 @@ pub impl DList { } /// Iterate over nodes. - pure fn each_node(@mut self, f: &fn(@mut DListNode) -> bool) { + fn each_node(@mut self, f: &fn(@mut DListNode) -> bool) { let mut link = self.peek_n(); while link.is_some() { let nobe = link.get(); @@ -471,23 +471,23 @@ pub impl DList { } /// Get data at the list's head. O(1). - pure fn peek(@mut self) -> Option { + fn peek(@mut self) -> Option { self.peek_n().map(|nobe| nobe.data) } /// Get data at the list's tail. O(1). - pure fn peek_tail(@mut self) -> Option { + fn peek_tail(@mut self) -> Option { self.peek_tail_n().map (|nobe| nobe.data) } /// Get data at the list's head, failing if empty. O(1). - pure fn head(@mut self) -> T { self.head_n().data } + fn head(@mut self) -> T { self.head_n().data } /// Get data at the list's tail, failing if empty. O(1). - pure fn tail(@mut self) -> T { self.tail_n().data } + fn tail(@mut self) -> T { self.tail_n().data } /// Get the elements of the list as a vector. O(n). - pure fn to_vec(@mut self) -> ~[T] { + fn to_vec(@mut self) -> ~[T] { let mut v = vec::with_capacity(self.size); unsafe { // Take this out of the unchecked when iter's functions are pure @@ -507,7 +507,7 @@ impl BaseIter for @mut DList { * allow for e.g. breadth-first search with in-place enqueues), but * removing the current node is forbidden. */ - pure fn each(&self, f: &fn(v: &T) -> bool) { + fn each(&self, f: &fn(v: &T) -> bool) { let mut link = self.peek_n(); while option::is_some(&link) { let nobe = option::get(link); @@ -536,7 +536,7 @@ impl BaseIter for @mut DList { } #[inline(always)] - pure fn size_hint(&self) -> Option { Some(self.len()) } + fn size_hint(&self) -> Option { Some(self.len()) } } #[cfg(test)] @@ -555,15 +555,15 @@ mod tests { let ab = from_vec(~[a,b]); let cd = from_vec(~[c,d]); let abcd = concat(concat(from_vec(~[ab,cd]))); - abcd.assert_consistent(); fail_unless!(abcd.len() == 8); - abcd.assert_consistent(); fail_unless!(abcd.pop().get() == 1); - abcd.assert_consistent(); fail_unless!(abcd.pop().get() == 2); - abcd.assert_consistent(); fail_unless!(abcd.pop().get() == 3); - abcd.assert_consistent(); fail_unless!(abcd.pop().get() == 4); - abcd.assert_consistent(); fail_unless!(abcd.pop().get() == 5); - abcd.assert_consistent(); fail_unless!(abcd.pop().get() == 6); - abcd.assert_consistent(); fail_unless!(abcd.pop().get() == 7); - abcd.assert_consistent(); fail_unless!(abcd.pop().get() == 8); + abcd.assert_consistent(); assert_eq!(abcd.len(), 8); + abcd.assert_consistent(); assert_eq!(abcd.pop().get(), 1); + abcd.assert_consistent(); assert_eq!(abcd.pop().get(), 2); + abcd.assert_consistent(); assert_eq!(abcd.pop().get(), 3); + abcd.assert_consistent(); assert_eq!(abcd.pop().get(), 4); + abcd.assert_consistent(); assert_eq!(abcd.pop().get(), 5); + abcd.assert_consistent(); assert_eq!(abcd.pop().get(), 6); + abcd.assert_consistent(); assert_eq!(abcd.pop().get(), 7); + abcd.assert_consistent(); assert_eq!(abcd.pop().get(), 8); abcd.assert_consistent(); fail_unless!(abcd.is_empty()); } #[test] @@ -571,15 +571,15 @@ mod tests { let a = from_vec(~[1,2,3]); let b = from_vec(~[4,5,6]); a.append(b); - fail_unless!(a.len() == 6); - fail_unless!(b.len() == 0); + assert_eq!(a.len(), 6); + assert_eq!(b.len(), 0); b.assert_consistent(); - a.assert_consistent(); fail_unless!(a.pop().get() == 1); - a.assert_consistent(); fail_unless!(a.pop().get() == 2); - a.assert_consistent(); fail_unless!(a.pop().get() == 3); - a.assert_consistent(); fail_unless!(a.pop().get() == 4); - a.assert_consistent(); fail_unless!(a.pop().get() == 5); - a.assert_consistent(); fail_unless!(a.pop().get() == 6); + a.assert_consistent(); assert_eq!(a.pop().get(), 1); + a.assert_consistent(); assert_eq!(a.pop().get(), 2); + a.assert_consistent(); assert_eq!(a.pop().get(), 3); + a.assert_consistent(); assert_eq!(a.pop().get(), 4); + a.assert_consistent(); assert_eq!(a.pop().get(), 5); + a.assert_consistent(); assert_eq!(a.pop().get(), 6); a.assert_consistent(); fail_unless!(a.is_empty()); } #[test] @@ -587,12 +587,12 @@ mod tests { let a = from_vec(~[1,2,3]); let b = DList::(); a.append(b); - fail_unless!(a.len() == 3); - fail_unless!(b.len() == 0); + assert_eq!(a.len(), 3); + assert_eq!(b.len(), 0); b.assert_consistent(); - a.assert_consistent(); fail_unless!(a.pop().get() == 1); - a.assert_consistent(); fail_unless!(a.pop().get() == 2); - a.assert_consistent(); fail_unless!(a.pop().get() == 3); + a.assert_consistent(); assert_eq!(a.pop().get(), 1); + a.assert_consistent(); assert_eq!(a.pop().get(), 2); + a.assert_consistent(); assert_eq!(a.pop().get(), 3); a.assert_consistent(); fail_unless!(a.is_empty()); } #[test] @@ -600,12 +600,12 @@ mod tests { let a = DList::(); let b = from_vec(~[4,5,6]); a.append(b); - fail_unless!(a.len() == 3); - fail_unless!(b.len() == 0); + assert_eq!(a.len(), 3); + assert_eq!(b.len(), 0); b.assert_consistent(); - a.assert_consistent(); fail_unless!(a.pop().get() == 4); - a.assert_consistent(); fail_unless!(a.pop().get() == 5); - a.assert_consistent(); fail_unless!(a.pop().get() == 6); + a.assert_consistent(); assert_eq!(a.pop().get(), 4); + a.assert_consistent(); assert_eq!(a.pop().get(), 5); + a.assert_consistent(); assert_eq!(a.pop().get(), 6); a.assert_consistent(); fail_unless!(a.is_empty()); } #[test] @@ -613,8 +613,8 @@ mod tests { let a = DList::(); let b = DList::(); a.append(b); - fail_unless!(a.len() == 0); - fail_unless!(b.len() == 0); + assert_eq!(a.len(), 0); + assert_eq!(b.len(), 0); b.assert_consistent(); a.assert_consistent(); } @@ -637,34 +637,34 @@ mod tests { let a = from_vec(~[1,2,3]); let b = from_vec(~[4,5,6]); b.prepend(a); - fail_unless!(a.len() == 0); - fail_unless!(b.len() == 6); + assert_eq!(a.len(), 0); + assert_eq!(b.len(), 6); a.assert_consistent(); - b.assert_consistent(); fail_unless!(b.pop().get() == 1); - b.assert_consistent(); fail_unless!(b.pop().get() == 2); - b.assert_consistent(); fail_unless!(b.pop().get() == 3); - b.assert_consistent(); fail_unless!(b.pop().get() == 4); - b.assert_consistent(); fail_unless!(b.pop().get() == 5); - b.assert_consistent(); fail_unless!(b.pop().get() == 6); + b.assert_consistent(); assert_eq!(b.pop().get(), 1); + b.assert_consistent(); assert_eq!(b.pop().get(), 2); + b.assert_consistent(); assert_eq!(b.pop().get(), 3); + b.assert_consistent(); assert_eq!(b.pop().get(), 4); + b.assert_consistent(); assert_eq!(b.pop().get(), 5); + b.assert_consistent(); assert_eq!(b.pop().get(), 6); b.assert_consistent(); fail_unless!(b.is_empty()); } #[test] pub fn test_dlist_reverse() { let a = from_vec(~[5,4,3,2,1]); a.reverse(); - fail_unless!(a.len() == 5); - a.assert_consistent(); fail_unless!(a.pop().get() == 1); - a.assert_consistent(); fail_unless!(a.pop().get() == 2); - a.assert_consistent(); fail_unless!(a.pop().get() == 3); - a.assert_consistent(); fail_unless!(a.pop().get() == 4); - a.assert_consistent(); fail_unless!(a.pop().get() == 5); + assert_eq!(a.len(), 5); + a.assert_consistent(); assert_eq!(a.pop().get(), 1); + a.assert_consistent(); assert_eq!(a.pop().get(), 2); + a.assert_consistent(); assert_eq!(a.pop().get(), 3); + a.assert_consistent(); assert_eq!(a.pop().get(), 4); + a.assert_consistent(); assert_eq!(a.pop().get(), 5); a.assert_consistent(); fail_unless!(a.is_empty()); } #[test] pub fn test_dlist_reverse_empty() { let a = DList::(); a.reverse(); - fail_unless!(a.len() == 0); + assert_eq!(a.len(), 0); a.assert_consistent(); } #[test] @@ -675,20 +675,20 @@ mod tests { a.insert_before(3, nobe); } } - fail_unless!(a.len() == 6); - a.assert_consistent(); fail_unless!(a.pop().get() == 1); - a.assert_consistent(); fail_unless!(a.pop().get() == 2); - a.assert_consistent(); fail_unless!(a.pop().get() == 3); - a.assert_consistent(); fail_unless!(a.pop().get() == 4); - a.assert_consistent(); fail_unless!(a.pop().get() == 3); - a.assert_consistent(); fail_unless!(a.pop().get() == 5); + assert_eq!(a.len(), 6); + a.assert_consistent(); assert_eq!(a.pop().get(), 1); + a.assert_consistent(); assert_eq!(a.pop().get(), 2); + a.assert_consistent(); assert_eq!(a.pop().get(), 3); + a.assert_consistent(); assert_eq!(a.pop().get(), 4); + a.assert_consistent(); assert_eq!(a.pop().get(), 3); + a.assert_consistent(); assert_eq!(a.pop().get(), 5); a.assert_consistent(); fail_unless!(a.is_empty()); } #[test] pub fn test_dlist_clear() { let a = from_vec(~[5,4,3,2,1]); a.clear(); - fail_unless!(a.len() == 0); + assert_eq!(a.len(), 0); a.assert_consistent(); } #[test] @@ -701,33 +701,33 @@ mod tests { #[test] pub fn test_dlist_head_tail() { let l = from_vec(~[1,2,3]); - fail_unless!(l.head() == 1); - fail_unless!(l.tail() == 3); - fail_unless!(l.len() == 3); + assert_eq!(l.head(), 1); + assert_eq!(l.tail(), 3); + assert_eq!(l.len(), 3); } #[test] pub fn test_dlist_pop() { let l = from_vec(~[1,2,3]); - fail_unless!(l.pop().get() == 1); - fail_unless!(l.tail() == 3); - fail_unless!(l.head() == 2); - fail_unless!(l.pop().get() == 2); - fail_unless!(l.tail() == 3); - fail_unless!(l.head() == 3); - fail_unless!(l.pop().get() == 3); + assert_eq!(l.pop().get(), 1); + assert_eq!(l.tail(), 3); + assert_eq!(l.head(), 2); + assert_eq!(l.pop().get(), 2); + assert_eq!(l.tail(), 3); + assert_eq!(l.head(), 3); + assert_eq!(l.pop().get(), 3); fail_unless!(l.is_empty()); fail_unless!(l.pop().is_none()); } #[test] pub fn test_dlist_pop_tail() { let l = from_vec(~[1,2,3]); - fail_unless!(l.pop_tail().get() == 3); - fail_unless!(l.tail() == 2); - fail_unless!(l.head() == 1); - fail_unless!(l.pop_tail().get() == 2); - fail_unless!(l.tail() == 1); - fail_unless!(l.head() == 1); - fail_unless!(l.pop_tail().get() == 1); + assert_eq!(l.pop_tail().get(), 3); + assert_eq!(l.tail(), 2); + assert_eq!(l.head(), 1); + assert_eq!(l.pop_tail().get(), 2); + assert_eq!(l.tail(), 1); + assert_eq!(l.head(), 1); + assert_eq!(l.pop_tail().get(), 1); fail_unless!(l.is_empty()); fail_unless!(l.pop_tail().is_none()); } @@ -735,34 +735,34 @@ mod tests { pub fn test_dlist_push() { let l = DList::(); l.push(1); - fail_unless!(l.head() == 1); - fail_unless!(l.tail() == 1); + assert_eq!(l.head(), 1); + assert_eq!(l.tail(), 1); l.push(2); - fail_unless!(l.head() == 1); - fail_unless!(l.tail() == 2); + assert_eq!(l.head(), 1); + assert_eq!(l.tail(), 2); l.push(3); - fail_unless!(l.head() == 1); - fail_unless!(l.tail() == 3); - fail_unless!(l.len() == 3); + assert_eq!(l.head(), 1); + assert_eq!(l.tail(), 3); + assert_eq!(l.len(), 3); } #[test] pub fn test_dlist_push_head() { let l = DList::(); l.push_head(3); - fail_unless!(l.head() == 3); - fail_unless!(l.tail() == 3); + assert_eq!(l.head(), 3); + assert_eq!(l.tail(), 3); l.push_head(2); - fail_unless!(l.head() == 2); - fail_unless!(l.tail() == 3); + assert_eq!(l.head(), 2); + assert_eq!(l.tail(), 3); l.push_head(1); - fail_unless!(l.head() == 1); - fail_unless!(l.tail() == 3); - fail_unless!(l.len() == 3); + assert_eq!(l.head(), 1); + assert_eq!(l.tail(), 3); + assert_eq!(l.len(), 3); } #[test] pub fn test_dlist_foldl() { let l = from_vec(vec::from_fn(101, |x|x)); - fail_unless!(iter::foldl(&l, 0, |accum,elem| *accum+*elem) == 5050); + assert_eq!(iter::foldl(&l, 0, |accum,elem| *accum+*elem), 5050); } #[test] pub fn test_dlist_break_early() { @@ -772,7 +772,7 @@ mod tests { x += 1; if (*i == 3) { break; } } - fail_unless!(x == 3); + assert_eq!(x, 3); } #[test] pub fn test_dlist_remove_head() { @@ -780,13 +780,13 @@ mod tests { l.assert_consistent(); let one = l.push_n(1); l.assert_consistent(); let _two = l.push_n(2); l.assert_consistent(); let _three = l.push_n(3); - l.assert_consistent(); fail_unless!(l.len() == 3); + l.assert_consistent(); assert_eq!(l.len(), 3); l.assert_consistent(); l.remove(one); - l.assert_consistent(); fail_unless!(l.len() == 2); - l.assert_consistent(); fail_unless!(l.head() == 2); - l.assert_consistent(); fail_unless!(l.tail() == 3); - l.assert_consistent(); fail_unless!(l.pop().get() == 2); - l.assert_consistent(); fail_unless!(l.pop().get() == 3); + l.assert_consistent(); assert_eq!(l.len(), 2); + l.assert_consistent(); assert_eq!(l.head(), 2); + l.assert_consistent(); assert_eq!(l.tail(), 3); + l.assert_consistent(); assert_eq!(l.pop().get(), 2); + l.assert_consistent(); assert_eq!(l.pop().get(), 3); l.assert_consistent(); fail_unless!(l.is_empty()); } #[test] @@ -795,13 +795,13 @@ mod tests { l.assert_consistent(); let _one = l.push_n(1); l.assert_consistent(); let two = l.push_n(2); l.assert_consistent(); let _three = l.push_n(3); - l.assert_consistent(); fail_unless!(l.len() == 3); + l.assert_consistent(); assert_eq!(l.len(), 3); l.assert_consistent(); l.remove(two); - l.assert_consistent(); fail_unless!(l.len() == 2); - l.assert_consistent(); fail_unless!(l.head() == 1); - l.assert_consistent(); fail_unless!(l.tail() == 3); - l.assert_consistent(); fail_unless!(l.pop().get() == 1); - l.assert_consistent(); fail_unless!(l.pop().get() == 3); + l.assert_consistent(); assert_eq!(l.len(), 2); + l.assert_consistent(); assert_eq!(l.head(), 1); + l.assert_consistent(); assert_eq!(l.tail(), 3); + l.assert_consistent(); assert_eq!(l.pop().get(), 1); + l.assert_consistent(); assert_eq!(l.pop().get(), 3); l.assert_consistent(); fail_unless!(l.is_empty()); } #[test] @@ -810,13 +810,13 @@ mod tests { l.assert_consistent(); let _one = l.push_n(1); l.assert_consistent(); let _two = l.push_n(2); l.assert_consistent(); let three = l.push_n(3); - l.assert_consistent(); fail_unless!(l.len() == 3); + l.assert_consistent(); assert_eq!(l.len(), 3); l.assert_consistent(); l.remove(three); - l.assert_consistent(); fail_unless!(l.len() == 2); - l.assert_consistent(); fail_unless!(l.head() == 1); - l.assert_consistent(); fail_unless!(l.tail() == 2); - l.assert_consistent(); fail_unless!(l.pop().get() == 1); - l.assert_consistent(); fail_unless!(l.pop().get() == 2); + l.assert_consistent(); assert_eq!(l.len(), 2); + l.assert_consistent(); assert_eq!(l.head(), 1); + l.assert_consistent(); assert_eq!(l.tail(), 2); + l.assert_consistent(); assert_eq!(l.pop().get(), 1); + l.assert_consistent(); assert_eq!(l.pop().get(), 2); l.assert_consistent(); fail_unless!(l.is_empty()); } #[test] @@ -825,14 +825,14 @@ mod tests { l.assert_consistent(); let one = l.push_n(1); l.assert_consistent(); let two = l.push_n(2); l.assert_consistent(); let _three = l.push_n(3); - l.assert_consistent(); fail_unless!(l.len() == 3); + l.assert_consistent(); assert_eq!(l.len(), 3); l.assert_consistent(); l.remove(one); l.assert_consistent(); l.remove(two); // and through and through, the vorpal blade went snicker-snack - l.assert_consistent(); fail_unless!(l.len() == 1); - l.assert_consistent(); fail_unless!(l.head() == 3); - l.assert_consistent(); fail_unless!(l.tail() == 3); - l.assert_consistent(); fail_unless!(l.pop().get() == 3); + l.assert_consistent(); assert_eq!(l.len(), 1); + l.assert_consistent(); assert_eq!(l.head(), 3); + l.assert_consistent(); assert_eq!(l.tail(), 3); + l.assert_consistent(); assert_eq!(l.pop().get(), 3); l.assert_consistent(); fail_unless!(l.is_empty()); } #[test] @@ -841,13 +841,13 @@ mod tests { l.assert_consistent(); let one = l.push_n(1); l.assert_consistent(); let _two = l.push_n(2); l.assert_consistent(); let three = l.push_n(3); - l.assert_consistent(); fail_unless!(l.len() == 3); + l.assert_consistent(); assert_eq!(l.len(), 3); l.assert_consistent(); l.remove(one); l.assert_consistent(); l.remove(three); - l.assert_consistent(); fail_unless!(l.len() == 1); - l.assert_consistent(); fail_unless!(l.head() == 2); - l.assert_consistent(); fail_unless!(l.tail() == 2); - l.assert_consistent(); fail_unless!(l.pop().get() == 2); + l.assert_consistent(); assert_eq!(l.len(), 1); + l.assert_consistent(); assert_eq!(l.head(), 2); + l.assert_consistent(); assert_eq!(l.tail(), 2); + l.assert_consistent(); assert_eq!(l.pop().get(), 2); l.assert_consistent(); fail_unless!(l.is_empty()); } #[test] @@ -856,13 +856,13 @@ mod tests { l.assert_consistent(); let _one = l.push_n(1); l.assert_consistent(); let two = l.push_n(2); l.assert_consistent(); let three = l.push_n(3); - l.assert_consistent(); fail_unless!(l.len() == 3); + l.assert_consistent(); assert_eq!(l.len(), 3); l.assert_consistent(); l.remove(two); l.assert_consistent(); l.remove(three); - l.assert_consistent(); fail_unless!(l.len() == 1); - l.assert_consistent(); fail_unless!(l.head() == 1); - l.assert_consistent(); fail_unless!(l.tail() == 1); - l.assert_consistent(); fail_unless!(l.pop().get() == 1); + l.assert_consistent(); assert_eq!(l.len(), 1); + l.assert_consistent(); assert_eq!(l.head(), 1); + l.assert_consistent(); assert_eq!(l.tail(), 1); + l.assert_consistent(); assert_eq!(l.pop().get(), 1); l.assert_consistent(); fail_unless!(l.is_empty()); } #[test] @@ -871,7 +871,7 @@ mod tests { l.assert_consistent(); let one = l.push_n(1); l.assert_consistent(); let two = l.push_n(2); l.assert_consistent(); let three = l.push_n(3); - l.assert_consistent(); fail_unless!(l.len() == 3); + l.assert_consistent(); assert_eq!(l.len(), 3); l.assert_consistent(); l.remove(two); l.assert_consistent(); l.remove(three); l.assert_consistent(); l.remove(one); // Twenty-three is number one! @@ -884,14 +884,14 @@ mod tests { l.assert_consistent(); let _one = l.push_n(1); l.assert_consistent(); let two = l.push_n(2); l.assert_consistent(); let three = new_dlist_node(3); - l.assert_consistent(); fail_unless!(l.len() == 2); + l.assert_consistent(); assert_eq!(l.len(), 2); l.assert_consistent(); l.insert_n_before(three, two); - l.assert_consistent(); fail_unless!(l.len() == 3); - l.assert_consistent(); fail_unless!(l.head() == 1); - l.assert_consistent(); fail_unless!(l.tail() == 2); - l.assert_consistent(); fail_unless!(l.pop().get() == 1); - l.assert_consistent(); fail_unless!(l.pop().get() == 3); - l.assert_consistent(); fail_unless!(l.pop().get() == 2); + l.assert_consistent(); assert_eq!(l.len(), 3); + l.assert_consistent(); assert_eq!(l.head(), 1); + l.assert_consistent(); assert_eq!(l.tail(), 2); + l.assert_consistent(); assert_eq!(l.pop().get(), 1); + l.assert_consistent(); assert_eq!(l.pop().get(), 3); + l.assert_consistent(); assert_eq!(l.pop().get(), 2); l.assert_consistent(); fail_unless!(l.is_empty()); } #[test] @@ -900,14 +900,14 @@ mod tests { l.assert_consistent(); let one = l.push_n(1); l.assert_consistent(); let _two = l.push_n(2); l.assert_consistent(); let three = new_dlist_node(3); - l.assert_consistent(); fail_unless!(l.len() == 2); + l.assert_consistent(); assert_eq!(l.len(), 2); l.assert_consistent(); l.insert_n_after(three, one); - l.assert_consistent(); fail_unless!(l.len() == 3); - l.assert_consistent(); fail_unless!(l.head() == 1); - l.assert_consistent(); fail_unless!(l.tail() == 2); - l.assert_consistent(); fail_unless!(l.pop().get() == 1); - l.assert_consistent(); fail_unless!(l.pop().get() == 3); - l.assert_consistent(); fail_unless!(l.pop().get() == 2); + l.assert_consistent(); assert_eq!(l.len(), 3); + l.assert_consistent(); assert_eq!(l.head(), 1); + l.assert_consistent(); assert_eq!(l.tail(), 2); + l.assert_consistent(); assert_eq!(l.pop().get(), 1); + l.assert_consistent(); assert_eq!(l.pop().get(), 3); + l.assert_consistent(); assert_eq!(l.pop().get(), 2); l.assert_consistent(); fail_unless!(l.is_empty()); } #[test] @@ -915,14 +915,14 @@ mod tests { let l = DList::(); l.assert_consistent(); let one = l.push_n(1); l.assert_consistent(); let _two = l.push_n(2); - l.assert_consistent(); fail_unless!(l.len() == 2); + l.assert_consistent(); assert_eq!(l.len(), 2); l.assert_consistent(); l.insert_before(3, one); - l.assert_consistent(); fail_unless!(l.len() == 3); - l.assert_consistent(); fail_unless!(l.head() == 3); - l.assert_consistent(); fail_unless!(l.tail() == 2); - l.assert_consistent(); fail_unless!(l.pop().get() == 3); - l.assert_consistent(); fail_unless!(l.pop().get() == 1); - l.assert_consistent(); fail_unless!(l.pop().get() == 2); + l.assert_consistent(); assert_eq!(l.len(), 3); + l.assert_consistent(); assert_eq!(l.head(), 3); + l.assert_consistent(); assert_eq!(l.tail(), 2); + l.assert_consistent(); assert_eq!(l.pop().get(), 3); + l.assert_consistent(); assert_eq!(l.pop().get(), 1); + l.assert_consistent(); assert_eq!(l.pop().get(), 2); l.assert_consistent(); fail_unless!(l.is_empty()); } #[test] @@ -930,14 +930,14 @@ mod tests { let l = DList::(); l.assert_consistent(); let _one = l.push_n(1); l.assert_consistent(); let two = l.push_n(2); - l.assert_consistent(); fail_unless!(l.len() == 2); + l.assert_consistent(); assert_eq!(l.len(), 2); l.assert_consistent(); l.insert_after(3, two); - l.assert_consistent(); fail_unless!(l.len() == 3); - l.assert_consistent(); fail_unless!(l.head() == 1); - l.assert_consistent(); fail_unless!(l.tail() == 3); - l.assert_consistent(); fail_unless!(l.pop().get() == 1); - l.assert_consistent(); fail_unless!(l.pop().get() == 2); - l.assert_consistent(); fail_unless!(l.pop().get() == 3); + l.assert_consistent(); assert_eq!(l.len(), 3); + l.assert_consistent(); assert_eq!(l.head(), 1); + l.assert_consistent(); assert_eq!(l.tail(), 3); + l.assert_consistent(); assert_eq!(l.pop().get(), 1); + l.assert_consistent(); assert_eq!(l.pop().get(), 2); + l.assert_consistent(); assert_eq!(l.pop().get(), 3); l.assert_consistent(); fail_unless!(l.is_empty()); } #[test] #[should_fail] #[ignore(cfg(windows))] diff --git a/src/libcore/either.rs b/src/libcore/either.rs index e4b7bbbd99e87..2af9e91a30fce 100644 --- a/src/libcore/either.rs +++ b/src/libcore/either.rs @@ -17,7 +17,7 @@ use result; use vec; /// The either type -#[deriving_eq] +#[deriving(Clone, Eq)] pub enum Either { Left(T), Right(U) @@ -87,7 +87,7 @@ pub fn partition(eithers: ~[Either]) } #[inline(always)] -pub pure fn flip(eith: Either) -> Either { +pub fn flip(eith: Either) -> Either { //! Flips between left and right of a given either match eith { @@ -97,7 +97,7 @@ pub pure fn flip(eith: Either) -> Either { } #[inline(always)] -pub pure fn to_result(eith: Either) +pub fn to_result(eith: Either) -> Result { /*! * Converts either::t to a result::t @@ -113,21 +113,21 @@ pub pure fn to_result(eith: Either) } #[inline(always)] -pub pure fn is_left(eith: &Either) -> bool { +pub fn is_left(eith: &Either) -> bool { //! Checks whether the given value is a left match *eith { Left(_) => true, _ => false } } #[inline(always)] -pub pure fn is_right(eith: &Either) -> bool { +pub fn is_right(eith: &Either) -> bool { //! Checks whether the given value is a right match *eith { Right(_) => true, _ => false } } #[inline(always)] -pub pure fn unwrap_left(eith: Either) -> T { +pub fn unwrap_left(eith: Either) -> T { //! Retrieves the value in the left branch. Fails if the either is Right. match eith { @@ -137,7 +137,7 @@ pub pure fn unwrap_left(eith: Either) -> T { } #[inline(always)] -pub pure fn unwrap_right(eith: Either) -> U { +pub fn unwrap_right(eith: Either) -> U { //! Retrieves the value in the right branch. Fails if the either is Left. match eith { @@ -191,77 +191,77 @@ fn test_either_right() { fn test_lefts() { let input = ~[Left(10), Right(11), Left(12), Right(13), Left(14)]; let result = lefts(input); - fail_unless!((result == ~[10, 12, 14])); + assert_eq!(result, ~[10, 12, 14]); } #[test] fn test_lefts_none() { let input: ~[Either] = ~[Right(10), Right(10)]; let result = lefts(input); - fail_unless!((vec::len(result) == 0u)); + assert_eq!(vec::len(result), 0u); } #[test] fn test_lefts_empty() { let input: ~[Either] = ~[]; let result = lefts(input); - fail_unless!((vec::len(result) == 0u)); + assert_eq!(vec::len(result), 0u); } #[test] fn test_rights() { let input = ~[Left(10), Right(11), Left(12), Right(13), Left(14)]; let result = rights(input); - fail_unless!((result == ~[11, 13])); + assert_eq!(result, ~[11, 13]); } #[test] fn test_rights_none() { let input: ~[Either] = ~[Left(10), Left(10)]; let result = rights(input); - fail_unless!((vec::len(result) == 0u)); + assert_eq!(vec::len(result), 0u); } #[test] fn test_rights_empty() { let input: ~[Either] = ~[]; let result = rights(input); - fail_unless!((vec::len(result) == 0u)); + assert_eq!(vec::len(result), 0u); } #[test] fn test_partition() { let input = ~[Left(10), Right(11), Left(12), Right(13), Left(14)]; let (lefts, rights) = partition(input); - fail_unless!((lefts[0] == 10)); - fail_unless!((lefts[1] == 12)); - fail_unless!((lefts[2] == 14)); - fail_unless!((rights[0] == 11)); - fail_unless!((rights[1] == 13)); + assert_eq!(lefts[0], 10); + assert_eq!(lefts[1], 12); + assert_eq!(lefts[2], 14); + assert_eq!(rights[0], 11); + assert_eq!(rights[1], 13); } #[test] fn test_partition_no_lefts() { let input: ~[Either] = ~[Right(10), Right(11)]; let (lefts, rights) = partition(input); - fail_unless!((vec::len(lefts) == 0u)); - fail_unless!((vec::len(rights) == 2u)); + assert_eq!(vec::len(lefts), 0u); + assert_eq!(vec::len(rights), 2u); } #[test] fn test_partition_no_rights() { let input: ~[Either] = ~[Left(10), Left(11)]; let (lefts, rights) = partition(input); - fail_unless!((vec::len(lefts) == 2u)); - fail_unless!((vec::len(rights) == 0u)); + assert_eq!(vec::len(lefts), 2u); + assert_eq!(vec::len(rights), 0u); } #[test] fn test_partition_empty() { let input: ~[Either] = ~[]; let (lefts, rights) = partition(input); - fail_unless!((vec::len(lefts) == 0u)); - fail_unless!((vec::len(rights) == 0u)); + assert_eq!(vec::len(lefts), 0u); + assert_eq!(vec::len(rights), 0u); } // diff --git a/src/libcore/flate.rs b/src/libcore/flate.rs index c830648e9dffe..d9dc89097d03d 100644 --- a/src/libcore/flate.rs +++ b/src/libcore/flate.rs @@ -41,10 +41,10 @@ pub mod rustrt { } } -const lz_none : c_int = 0x0; // Huffman-coding only. -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" +static lz_none : c_int = 0x0; // Huffman-coding only. +static lz_fast : c_int = 0x1; // LZ with only one probe +static lz_norm : c_int = 0x80; // LZ with 128 probes, "normal" +static lz_best : c_int = 0xfff; // LZ with 4095 probes, "best" pub fn deflate_bytes(bytes: &[const u8]) -> ~[u8] { do vec::as_const_buf(bytes) |b, len| { diff --git a/src/libcore/from_str.rs b/src/libcore/from_str.rs index 166ba2252a9d4..ebf6d212466a5 100644 --- a/src/libcore/from_str.rs +++ b/src/libcore/from_str.rs @@ -13,5 +13,5 @@ use option::Option; pub trait FromStr { - static pure fn from_str(s: &str) -> Option; + fn from_str(s: &str) -> Option; } diff --git a/src/libcore/gc.rs b/src/libcore/gc.rs index 3449c5ff4ba45..6b25611466321 100644 --- a/src/libcore/gc.rs +++ b/src/libcore/gc.rs @@ -211,11 +211,11 @@ unsafe fn find_segment_for_frame(fp: *Word, segment: *StackSegment) type Memory = uint; -const task_local_heap: Memory = 1; -const exchange_heap: Memory = 2; -const stack: Memory = 4; +static task_local_heap: Memory = 1; +static exchange_heap: Memory = 2; +static stack: Memory = 4; -const need_cleanup: Memory = exchange_heap | stack; +static need_cleanup: Memory = exchange_heap | stack; // Walks stack, searching for roots of the requested type, and passes // each root to the visitor. diff --git a/src/libcore/hash.rs b/src/libcore/hash.rs index 7f2189df20e25..1bfa0e9522ddd 100644 --- a/src/libcore/hash.rs +++ b/src/libcore/hash.rs @@ -50,17 +50,17 @@ pub trait Hash { * function and require most types to only implement the * IterBytes trait, that feeds SipHash. */ - pure fn hash_keyed(&self, k0: u64, k1: u64) -> u64; + fn hash_keyed(&self, k0: u64, k1: u64) -> u64; } // When we have default methods, won't need this. pub trait HashUtil { - pure fn hash(&self) -> u64; + fn hash(&self) -> u64; } impl HashUtil for A { #[inline(always)] - pure fn hash(&self) -> u64 { self.hash_keyed(0,0) } + fn hash(&self) -> u64 { self.hash_keyed(0,0) } } /// Streaming hash-functions should implement this. @@ -75,7 +75,7 @@ pub trait Streaming { impl Hash for A { #[inline(always)] - pure fn hash_keyed(&self, k0: u64, k1: u64) -> u64 { + fn hash_keyed(&self, k0: u64, k1: u64) -> u64 { unsafe { let s = &State(k0, k1); for self.iter_bytes(true) |bytes| { @@ -86,9 +86,8 @@ impl Hash for A { } } -pure fn hash_keyed_2(a: &A, b: &B, - k0: u64, k1: u64) -> u64 { +fn hash_keyed_2(a: &A, b: &B, k0: u64, k1: u64) -> u64 { unsafe { let s = &State(k0, k1); for a.iter_bytes(true) |bytes| { s.input(bytes); } @@ -97,10 +96,9 @@ pure fn hash_keyed_2(a: &A, b: &B, c: &C, - k0: u64, k1: u64) -> u64 { +fn hash_keyed_3(a: &A, b: &B, c: &C, k0: u64, k1: u64) -> u64 { unsafe { let s = &State(k0, k1); for a.iter_bytes(true) |bytes| { s.input(bytes); } @@ -110,11 +108,11 @@ pure fn hash_keyed_3(a: &A, b: &B, c: &C, d: &D, - k0: u64, k1: u64) -> u64 { +fn hash_keyed_4(a: &A, b: &B, c: &C, d: &D, k0: u64, k1: u64) + -> u64 { unsafe { let s = &State(k0, k1); for a.iter_bytes(true) |bytes| { s.input(bytes); } @@ -125,12 +123,12 @@ pure fn hash_keyed_4(a: &A, b: &B, c: &C, d: &D, e: &E, - k0: u64, k1: u64) -> u64 { +fn hash_keyed_5(a: &A, b: &B, c: &C, d: &D, e: &E, + k0: u64, k1: u64) -> u64 { unsafe { let s = &State(k0, k1); for a.iter_bytes(true) |bytes| { s.input(bytes); } diff --git a/src/libcore/hashmap.rs b/src/libcore/hashmap.rs index 68a55792077e9..8c290553a4599 100644 --- a/src/libcore/hashmap.rs +++ b/src/libcore/hashmap.rs @@ -24,8 +24,9 @@ pub mod linear { use rand; use uint; use vec; + use util::unreachable; - const INITIAL_CAPACITY: uint = 32u; // 2^5 + static INITIAL_CAPACITY: uint = 32u; // 2^5 struct Bucket { hash: uint, @@ -48,7 +49,7 @@ pub mod linear { } #[inline(always)] - pure fn resize_at(capacity: uint) -> uint { + fn resize_at(capacity: uint) -> uint { ((capacity as float) * 3. / 4.) as uint } @@ -59,7 +60,7 @@ pub mod linear { initial_capacity) } - pure fn linear_map_with_capacity_and_keys( + fn linear_map_with_capacity_and_keys( k0: u64, k1: u64, initial_capacity: uint) -> LinearMap { LinearMap { @@ -72,21 +73,21 @@ pub mod linear { priv impl LinearMap { #[inline(always)] - pure fn to_bucket(&self, h: uint) -> uint { + fn to_bucket(&self, h: uint) -> uint { // A good hash function with entropy spread over all of the // bits is assumed. SipHash is more than good enough. h % self.buckets.len() } #[inline(always)] - pure fn next_bucket(&self, idx: uint, len_buckets: uint) -> uint { + fn next_bucket(&self, idx: uint, len_buckets: uint) -> uint { let n = (idx + 1) % len_buckets; debug!("next_bucket(%?, %?) = %?", idx, len_buckets, n); n } #[inline(always)] - pure fn bucket_sequence(&self, hash: uint, + fn bucket_sequence(&self, hash: uint, op: &fn(uint) -> bool) -> uint { let start_idx = self.to_bucket(hash); let len_buckets = self.buckets.len(); @@ -103,24 +104,24 @@ pub mod linear { } #[inline(always)] - pure fn bucket_for_key(&self, k: &K) -> SearchResult { + fn bucket_for_key(&self, k: &K) -> SearchResult { let hash = k.hash_keyed(self.k0, self.k1) as uint; self.bucket_for_key_with_hash(hash, k) } #[inline(always)] - pure fn bucket_for_key_equiv>( - &self, - k: &Q) - -> SearchResult { + fn bucket_for_key_equiv>(&self, + k: &Q) + -> SearchResult { let hash = k.hash_keyed(self.k0, self.k1) as uint; self.bucket_for_key_with_hash_equiv(hash, k) } #[inline(always)] - pure fn bucket_for_key_with_hash(&self, - hash: uint, - k: &K) -> SearchResult { + fn bucket_for_key_with_hash(&self, + hash: uint, + k: &K) + -> SearchResult { let _ = for self.bucket_sequence(hash) |i| { match self.buckets[i] { Some(ref bkt) => if bkt.hash == hash && *k == bkt.key { @@ -133,10 +134,10 @@ pub mod linear { } #[inline(always)] - pure fn bucket_for_key_with_hash_equiv>(&self, - hash: uint, - k: &Q) - -> SearchResult { + fn bucket_for_key_with_hash_equiv>(&self, + hash: uint, + k: &Q) + -> SearchResult { let _ = for self.bucket_sequence(hash) |i| { match self.buckets[i] { Some(ref bkt) => { @@ -185,13 +186,21 @@ pub mod linear { } #[inline(always)] - pure fn value_for_bucket(&self, idx: uint) -> &'self V { + fn value_for_bucket(&self, idx: uint) -> &'self V { match self.buckets[idx] { Some(ref bkt) => &bkt.value, None => fail!(~"LinearMap::find: internal logic error"), } } + #[inline(always)] + fn mut_value_for_bucket(&mut self, idx: uint) -> &'self mut V { + match self.buckets[idx] { + Some(ref mut bkt) => &mut bkt.value, + None => unreachable() + } + } + /// 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 @@ -273,7 +282,7 @@ pub mod linear { BaseIter<(&'self K, &'self V)> for LinearMap { /// Visit all key-value pairs - pure fn each(&self, blk: &fn(&(&'self K, &'self V)) -> bool) { + fn each(&self, blk: &fn(&(&'self K, &'self V)) -> bool) { for uint::range(0, self.buckets.len()) |i| { let mut broke = false; do self.buckets[i].map |bucket| { @@ -284,16 +293,16 @@ pub mod linear { if broke { break; } } } - pure fn size_hint(&self) -> Option { Some(self.len()) } + fn size_hint(&self) -> Option { Some(self.len()) } } impl Container for LinearMap { /// Return the number of elements in the map - pure fn len(&const self) -> uint { self.size } + fn len(&const self) -> uint { self.size } /// Return true if the map contains no elements - pure fn is_empty(&const self) -> bool { self.len() == 0 } + fn is_empty(&const self) -> bool { self.len() == 0 } } impl Mutable for LinearMap { @@ -308,7 +317,7 @@ pub mod linear { impl Map for LinearMap { /// Return true if the map contains a value for the specified key - pure fn contains_key(&self, k: &K) -> bool { + fn contains_key(&self, k: &K) -> bool { match self.bucket_for_key(k) { FoundEntry(_) => {true} TableFull | FoundHole(_) => {false} @@ -316,12 +325,12 @@ pub mod linear { } /// Visit all keys - pure fn each_key(&self, blk: &fn(k: &K) -> bool) { + fn each_key(&self, blk: &fn(k: &K) -> bool) { self.each(|&(k, _)| blk(k)) } /// Visit all values - pure fn each_value(&self, blk: &fn(v: &V) -> bool) { + fn each_value(&self, blk: &fn(v: &V) -> bool) { self.each(|&(_, v)| blk(v)) } @@ -338,14 +347,25 @@ pub mod linear { } } - /// Return the value corresponding to the key in the map - pure fn find(&self, k: &K) -> Option<&'self V> { + /// Return a reference to the value corresponding to the key + fn find(&self, k: &K) -> Option<&'self V> { match self.bucket_for_key(k) { FoundEntry(idx) => Some(self.value_for_bucket(idx)), TableFull | FoundHole(_) => None, } } + /// Return a mutable reference to the value corresponding to the key + fn find_mut(&mut self, k: &K) -> Option<&'self mut V> { + let idx = match self.bucket_for_key(k) { + FoundEntry(idx) => idx, + TableFull | FoundHole(_) => return None + }; + unsafe { // FIXME(#4903)---requires flow-sensitive borrow checker + Some(::cast::transmute_mut_region(self.mut_value_for_bucket(idx))) + } + } + /// Insert a key-value pair into the map. An existing value for a /// key is replaced by the new value. Return true if the key did /// not already exist in the map. @@ -373,7 +393,7 @@ pub mod linear { pub impl LinearMap { /// Create an empty LinearMap - static fn new() -> LinearMap { + fn new() -> LinearMap { linear_map_with_capacity(INITIAL_CAPACITY) } @@ -487,7 +507,7 @@ pub mod linear { } } - pure fn get(&self, k: &K) -> &'self V { + fn get(&self, k: &K) -> &'self V { match self.find(k) { Some(v) => v, None => fail!(fmt!("No entry found for key: %?", k)), @@ -496,10 +516,8 @@ pub mod linear { /// Return true if the map contains a value for the specified key, /// using equivalence - pure fn contains_key_equiv>( - &self, - key: &Q) - -> bool { + fn contains_key_equiv>(&self, key: &Q) + -> bool { match self.bucket_for_key_equiv(key) { FoundEntry(_) => {true} TableFull | FoundHole(_) => {false} @@ -508,8 +526,8 @@ pub mod linear { /// Return the value corresponding to the key in the map, using /// equivalence - pure fn find_equiv>(&self, k: &Q) - -> Option<&'self V> { + fn find_equiv>(&self, k: &Q) + -> Option<&'self V> { match self.bucket_for_key_equiv(k) { FoundEntry(idx) => Some(self.value_for_bucket(idx)), TableFull | FoundHole(_) => None, @@ -518,7 +536,7 @@ pub mod linear { } impl Eq for LinearMap { - pure fn eq(&self, other: &LinearMap) -> bool { + fn eq(&self, other: &LinearMap) -> bool { if self.len() != other.len() { return false; } for self.each |&(key, value)| { @@ -531,7 +549,7 @@ pub mod linear { true } - pure fn ne(&self, other: &LinearMap) -> bool { !self.eq(other) } + fn ne(&self, other: &LinearMap) -> bool { !self.eq(other) } } pub struct LinearSet { @@ -540,25 +558,21 @@ pub mod linear { impl BaseIter for LinearSet { /// Visit all values in order - pure fn each(&self, f: &fn(&T) -> bool) { self.map.each_key(f) } - pure fn size_hint(&self) -> Option { Some(self.len()) } + fn each(&self, f: &fn(&T) -> bool) { self.map.each_key(f) } + fn size_hint(&self) -> Option { Some(self.len()) } } impl Eq for LinearSet { - pure fn eq(&self, other: &LinearSet) -> bool { - self.map == other.map - } - pure fn ne(&self, other: &LinearSet) -> bool { - self.map != other.map - } + fn eq(&self, other: &LinearSet) -> bool { self.map == other.map } + fn ne(&self, other: &LinearSet) -> bool { self.map != other.map } } impl Container for LinearSet { /// Return the number of elements in the set - pure fn len(&const self) -> uint { self.map.len() } + fn len(&const self) -> uint { self.map.len() } /// Return true if the set contains no elements - pure fn is_empty(&const self) -> bool { self.map.is_empty() } + fn is_empty(&const self) -> bool { self.map.is_empty() } } impl Mutable for LinearSet { @@ -568,9 +582,7 @@ pub mod linear { impl Set for LinearSet { /// Return true if the set contains a value - pure fn contains(&self, value: &T) -> bool { - self.map.contains_key(value) - } + fn contains(&self, value: &T) -> bool { self.map.contains_key(value) } /// Add a value to the set. Return true if the value was not already /// present in the set. @@ -582,22 +594,22 @@ pub mod linear { /// Return true if the set has no elements in common with `other`. /// This is equivalent to checking for an empty intersection. - pure fn is_disjoint(&self, other: &LinearSet) -> bool { + fn is_disjoint(&self, other: &LinearSet) -> bool { iter::all(self, |v| !other.contains(v)) } /// Return true if the set is a subset of another - pure fn is_subset(&self, other: &LinearSet) -> bool { + fn is_subset(&self, other: &LinearSet) -> bool { iter::all(self, |v| other.contains(v)) } /// Return true if the set is a superset of another - pure fn is_superset(&self, other: &LinearSet) -> bool { + fn is_superset(&self, other: &LinearSet) -> bool { other.is_subset(self) } /// Visit the values representing the difference - pure fn difference(&self, other: &LinearSet, f: &fn(&T) -> bool) { + fn difference(&self, other: &LinearSet, f: &fn(&T) -> bool) { for self.each |v| { if !other.contains(v) { if !f(v) { return } @@ -606,16 +618,15 @@ pub mod linear { } /// Visit the values representing the symmetric difference - pure fn symmetric_difference(&self, other: &LinearSet, - f: &fn(&T) -> bool) { + fn symmetric_difference(&self, + other: &LinearSet, + f: &fn(&T) -> bool) { self.difference(other, f); other.difference(self, f); } /// Visit the values representing the intersection - pure fn intersection(&self, - other: &LinearSet, - f: &fn(&T) -> bool) { + fn intersection(&self, other: &LinearSet, f: &fn(&T) -> bool) { for self.each |v| { if other.contains(v) { if !f(v) { return } @@ -624,7 +635,7 @@ pub mod linear { } /// Visit the values representing the union - pure fn union(&self, other: &LinearSet, f: &fn(&T) -> bool) { + fn union(&self, other: &LinearSet, f: &fn(&T) -> bool) { for self.each |v| { if !f(v) { return } } @@ -639,7 +650,7 @@ pub mod linear { pub impl LinearSet { /// Create an empty LinearSet - static fn new() -> LinearSet { LinearSet{map: LinearMap::new()} } + fn new() -> LinearSet { LinearSet{map: LinearMap::new()} } /// Reserve space for at least `n` elements in the hash table. fn reserve_at_least(&mut self, n: uint) { @@ -664,6 +675,19 @@ pub mod linear { fail_unless!(*m.get(&2) == 4); } + #[test] + fn test_find_mut() { + let mut m = LinearMap::new(); + fail_unless!(m.insert(1, 12)); + fail_unless!(m.insert(2, 8)); + fail_unless!(m.insert(5, 14)); + let new = 100; + match m.find_mut(&5) { + None => fail!(), Some(x) => *x = new + } + assert_eq!(m.find(&5), Some(&new)); + } + #[test] pub fn test_insert_overwrite() { let mut m = LinearMap::new(); diff --git a/src/libcore/io.rs b/src/libcore/io.rs index 50e7a42b7b17c..fb305560ba333 100644 --- a/src/libcore/io.rs +++ b/src/libcore/io.rs @@ -21,7 +21,9 @@ use libc; use libc::{c_int, c_long, c_uint, c_void, size_t, ssize_t}; use libc::consts::os::posix88::*; use os; -use prelude::*; +use cast; +use path::Path; +use ops::Drop; use ptr; use result; use str; @@ -73,8 +75,6 @@ pub trait Reader { fn tell(&self) -> uint; } -#[cfg(stage1)] -#[cfg(stage2)] impl Reader for @Reader { fn read(&self, bytes: &mut [u8], len: uint) -> uint { self.read(bytes, len) @@ -99,8 +99,8 @@ pub trait ReaderUtil { /// Read len bytes into a new vec. fn read_bytes(&self, len: uint) -> ~[u8]; - /// Read up until a specified character (which is not returned) or EOF. - fn read_until(&self, c: char) -> ~str; + /// Read up until a specified character (which is optionally included) or EOF. + fn read_until(&self, c: char, include: bool) -> ~str; /// Read up until the first '\n' char (which is not returned), or EOF. fn read_line(&self) -> ~str; @@ -126,6 +126,9 @@ pub trait ReaderUtil { /// Iterate over every line until the iterator breaks or EOF. fn each_line(&self, it: &fn(&str) -> bool); + /// Read all the lines of the file into a vector. + fn read_lines(&self) -> ~[~str]; + /// Read n (between 1 and 8) little-endian unsigned integer bytes. fn read_le_uint_n(&self, nbytes: uint) -> u64; @@ -219,11 +222,14 @@ impl ReaderUtil for T { bytes } - fn read_until(&self, c: char) -> ~str { + fn read_until(&self, c: char, include: bool) -> ~str { let mut bytes = ~[]; loop { let ch = self.read_byte(); if ch == -1 || ch == c as int { + if include && ch == c as int { + bytes.push(ch as u8); + } break; } bytes.push(ch as u8); @@ -232,7 +238,7 @@ impl ReaderUtil for T { } fn read_line(&self) -> ~str { - self.read_until('\n') + self.read_until('\n', false) } fn read_chars(&self, n: uint) -> ~[char] { @@ -306,7 +312,7 @@ impl ReaderUtil for T { } fn read_c_str(&self) -> ~str { - self.read_until(0 as char) + self.read_until(0 as char, false) } fn read_whole_stream(&self) -> ~[u8] { @@ -329,7 +335,29 @@ impl ReaderUtil for T { fn each_line(&self, it: &fn(s: &str) -> bool) { while !self.eof() { - if !it(self.read_line()) { break; } + // include the \n, so that we can distinguish an entirely empty + // line read after "...\n", and the trailing empty line in + // "...\n\n". + let mut line = self.read_until('\n', true); + + // blank line at the end of the reader is ignored + if self.eof() && line.is_empty() { break; } + + // trim the \n, so that each_line is consistent with read_line + let n = str::len(line); + if line[n-1] == '\n' as u8 { + unsafe { str::raw::set_len(&mut line, n-1); } + } + + if !it(line) { break; } + } + } + + fn read_lines(&self) -> ~[~str] { + do vec::build |push| { + for self.each_line |line| { + push(str::from_slice(line)); + } } } @@ -618,11 +646,11 @@ impl Reader for BytesReader<'self> { fn tell(&self) -> uint { self.pos } } -pub pure fn with_bytes_reader(bytes: &[u8], f: &fn(@Reader) -> t) -> t { +pub fn with_bytes_reader(bytes: &[u8], f: &fn(@Reader) -> t) -> t { f(@BytesReader { bytes: bytes, pos: 0u } as @Reader) } -pub pure 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)) } @@ -630,7 +658,7 @@ pub pure fn with_str_reader(s: &str, f: &fn(@Reader) -> T) -> T { pub enum FileFlag { Append, Create, Truncate, NoFlag, } // What type of writer are we? -#[deriving_eq] +#[deriving(Eq)] pub enum WriterType { Screen, File } // FIXME (#2004): Seekable really should be orthogonal. @@ -655,8 +683,6 @@ pub trait Writer { fn get_type(&self) -> WriterType; } -#[cfg(stage1)] -#[cfg(stage2)] impl Writer for @Writer { fn write(&self, v: &[const u8]) { self.write(v) } fn seek(&self, a: int, b: SeekStyle) { self.seek(a, b) } @@ -986,7 +1012,7 @@ pub trait WriterUtil { impl WriterUtil for T { fn write_char(&self, ch: char) { - if ch as uint < 128u { + if (ch as uint) < 128u { self.write(&[ch as u8]); } else { self.write_str(str::from_char(ch)); @@ -1139,18 +1165,18 @@ impl Writer for BytesWriter { fn get_type(&self) -> WriterType { File } } -pub pure fn BytesWriter() -> BytesWriter { +pub fn BytesWriter() -> BytesWriter { BytesWriter { bytes: ~[], mut pos: 0u } } -pub pure fn with_bytes_writer(f: &fn(@Writer)) -> ~[u8] { +pub fn with_bytes_writer(f: &fn(@Writer)) -> ~[u8] { let wr = @BytesWriter(); f(wr as @Writer); let @BytesWriter{bytes, _} = wr; return bytes; } -pub pure fn with_str_writer(f: &fn(@Writer)) -> ~str { +pub fn with_str_writer(f: &fn(@Writer)) -> ~str { let mut v = with_bytes_writer(f); // FIXME (#3758): This should not be needed. @@ -1200,9 +1226,11 @@ pub fn read_whole_file(file: &Path) -> Result<~[u8], ~str> { // fsync related pub mod fsync { - use prelude::*; use io::{FILERes, FdRes, fd_t}; + use kinds::Copy; use libc; + use ops::Drop; + use option::{None, Option, Some}; use os; pub enum Level { @@ -1224,15 +1252,17 @@ pub mod fsync { arg: Arg, } + #[unsafe_destructor] impl Drop for Res { fn finalize(&self) { - match self.arg.opt_level { - None => (), - Some(level) => { - // fail hard if not succesful - fail_unless!(((self.arg.fsync_fn)(self.arg.val, level) != -1)); + match self.arg.opt_level { + None => (), + Some(level) => { + // fail hard if not succesful + fail_unless!(((self.arg.fsync_fn)(self.arg.val, level) + != -1)); + } } - } } } @@ -1333,6 +1363,21 @@ mod tests { } } + #[test] + fn test_read_lines() { + do io::with_str_reader(~"a\nb\nc\n") |inp| { + fail_unless!(inp.read_lines() == ~[~"a", ~"b", ~"c"]); + } + + do io::with_str_reader(~"a\nb\nc") |inp| { + fail_unless!(inp.read_lines() == ~[~"a", ~"b", ~"c"]); + } + + do io::with_str_reader(~"") |inp| { + fail_unless!(inp.read_lines().is_empty()); + } + } + #[test] fn test_readchars_wide() { let wide_test = ~"生锈的汤匙切肉汤hello生锈的汤匙切肉汤"; diff --git a/src/libcore/iter.rs b/src/libcore/iter.rs index 816dc6d22554f..f94c62d23ece3 100644 --- a/src/libcore/iter.rs +++ b/src/libcore/iter.rs @@ -23,12 +23,12 @@ use vec; pub type InitOp = &'self fn(uint) -> T; pub trait BaseIter { - pure fn each(&self, blk: &fn(v: &A) -> bool); - pure fn size_hint(&self) -> Option; + fn each(&self, blk: &fn(v: &A) -> bool); + fn size_hint(&self) -> Option; } pub trait ReverseIter: BaseIter { - pure fn each_reverse(&self, blk: &fn(&A) -> bool); + fn each_reverse(&self, blk: &fn(&A) -> bool); } pub trait MutableIter: BaseIter { @@ -36,41 +36,40 @@ pub trait MutableIter: BaseIter { } pub trait ExtendedIter { - pure fn eachi(&self, blk: &fn(uint, v: &A) -> bool); - pure fn all(&self, blk: &fn(&A) -> bool) -> bool; - pure fn any(&self, blk: &fn(&A) -> bool) -> bool; - pure fn foldl(&self, b0: B, blk: &fn(&B, &A) -> B) -> B; - pure fn position(&self, f: &fn(&A) -> bool) -> Option; - pure fn map_to_vec(&self, op: &fn(&A) -> B) -> ~[B]; - pure fn flat_map_to_vec>(&self, op: &fn(&A) -> IB) - -> ~[B]; + fn eachi(&self, blk: &fn(uint, v: &A) -> bool); + fn all(&self, blk: &fn(&A) -> bool) -> bool; + fn any(&self, blk: &fn(&A) -> bool) -> bool; + fn foldl(&self, b0: B, blk: &fn(&B, &A) -> B) -> B; + fn position(&self, f: &fn(&A) -> bool) -> Option; + fn map_to_vec(&self, op: &fn(&A) -> B) -> ~[B]; + fn flat_map_to_vec>(&self, op: &fn(&A) -> IB) -> ~[B]; } pub trait EqIter { - pure fn contains(&self, x: &A) -> bool; - pure fn count(&self, x: &A) -> uint; + fn contains(&self, x: &A) -> bool; + fn count(&self, x: &A) -> uint; } pub trait Times { - pure fn times(&self, it: &fn() -> bool); + fn times(&self, it: &fn() -> bool); } pub trait CopyableIter { - pure fn filter_to_vec(&self, pred: &fn(&A) -> bool) -> ~[A]; - pure fn to_vec(&self) -> ~[A]; - pure fn find(&self, p: &fn(&A) -> bool) -> Option; + fn filter_to_vec(&self, pred: &fn(&A) -> bool) -> ~[A]; + fn to_vec(&self) -> ~[A]; + fn find(&self, p: &fn(&A) -> bool) -> Option; } pub trait CopyableOrderedIter { - pure fn min(&self) -> A; - pure fn max(&self) -> A; + fn min(&self) -> A; + fn max(&self) -> A; } pub trait CopyableNonstrictIter { // Like "each", but copies out the value. If the receiver is mutated while // iterating over it, the semantics must not be memory-unsafe but are // otherwise undefined. - pure fn each_val(&const self, f: &fn(A) -> bool); + fn each_val(&const self, f: &fn(A) -> bool); } // A trait for sequences that can be built by imperatively pushing elements @@ -89,13 +88,11 @@ pub trait Buildable { * as an argument a function that will push an element * onto the sequence being constructed. */ - static pure fn build_sized(size: uint, - builder: &fn(push: &pure fn(A))) -> Self; + fn build_sized(size: uint, builder: &fn(push: &fn(A))) -> Self; } #[inline(always)] -pub pure fn eachi>(self: &IA, - blk: &fn(uint, &A) -> bool) { +pub fn eachi>(self: &IA, blk: &fn(uint, &A) -> bool) { let mut i = 0; for self.each |a| { if !blk(i, a) { break; } @@ -104,8 +101,7 @@ pub pure fn eachi>(self: &IA, } #[inline(always)] -pub pure fn all>(self: &IA, - blk: &fn(&A) -> bool) -> bool { +pub fn all>(self: &IA, blk: &fn(&A) -> bool) -> bool { for self.each |a| { if !blk(a) { return false; } } @@ -113,8 +109,7 @@ pub pure fn all>(self: &IA, } #[inline(always)] -pub pure fn any>(self: &IA, - blk: &fn(&A) -> bool) -> bool { +pub fn any>(self: &IA, blk: &fn(&A) -> bool) -> bool { for self.each |a| { if blk(a) { return true; } } @@ -122,8 +117,9 @@ pub pure fn any>(self: &IA, } #[inline(always)] -pub pure fn filter_to_vec>( - self: &IA, prd: &fn(&A) -> bool) -> ~[A] { +pub fn filter_to_vec>(self: &IA, + prd: &fn(&A) -> bool) + -> ~[A] { do vec::build_sized_opt(self.size_hint()) |push| { for self.each |a| { if prd(a) { push(*a); } @@ -132,9 +128,7 @@ pub pure fn filter_to_vec>( } #[inline(always)] -pub pure fn map_to_vec>(self: &IA, - op: &fn(&A) -> B) - -> ~[B] { +pub fn map_to_vec>(self: &IA, op: &fn(&A) -> B) -> ~[B] { do vec::build_sized_opt(self.size_hint()) |push| { for self.each |a| { push(op(a)); @@ -143,8 +137,9 @@ pub pure fn map_to_vec>(self: &IA, } #[inline(always)] -pub pure fn flat_map_to_vec,IB:BaseIter>( - self: &IA, op: &fn(&A) -> IB) -> ~[B] { +pub fn flat_map_to_vec,IB:BaseIter>(self: &IA, + op: &fn(&A) -> IB) + -> ~[B] { do vec::build |push| { for self.each |a| { for op(a).each |&b| { @@ -155,9 +150,8 @@ pub pure fn flat_map_to_vec,IB:BaseIter>( } #[inline(always)] -pub pure fn foldl>(self: &IA, b0: B, - blk: &fn(&B, &A) -> B) - -> B { +pub fn foldl>(self: &IA, b0: B, blk: &fn(&B, &A) -> B) + -> B { let mut b = b0; for self.each |a| { b = blk(&b, a); @@ -166,12 +160,12 @@ pub pure fn foldl>(self: &IA, b0: B, } #[inline(always)] -pub pure fn to_vec>(self: &IA) -> ~[A] { +pub fn to_vec>(self: &IA) -> ~[A] { foldl::(self, ~[], |r, a| vec::append(copy (*r), ~[*a])) } #[inline(always)] -pub pure fn contains>(self: &IA, x: &A) -> bool { +pub fn contains>(self: &IA, x: &A) -> bool { for self.each |a| { if *a == *x { return true; } } @@ -179,7 +173,7 @@ pub pure fn contains>(self: &IA, x: &A) -> bool { } #[inline(always)] -pub pure fn count>(self: &IA, x: &A) -> uint { +pub fn count>(self: &IA, x: &A) -> uint { do foldl(self, 0) |count, value| { if *value == *x { *count + 1 @@ -190,9 +184,8 @@ pub pure fn count>(self: &IA, x: &A) -> uint { } #[inline(always)] -pub pure fn position>(self: &IA, f: &fn(&A) -> bool) - -> Option -{ +pub fn position>(self: &IA, f: &fn(&A) -> bool) + -> Option { let mut i = 0; for self.each |a| { if f(a) { return Some(i); } @@ -206,7 +199,7 @@ pub pure fn position>(self: &IA, f: &fn(&A) -> bool) // it would have to be implemented with foldr, which is too inefficient. #[inline(always)] -pub pure fn repeat(times: uint, blk: &fn() -> bool) { +pub fn repeat(times: uint, blk: &fn() -> bool) { let mut i = 0; while i < times { if !blk() { break } @@ -215,7 +208,7 @@ pub pure fn repeat(times: uint, blk: &fn() -> bool) { } #[inline(always)] -pub pure fn min>(self: &IA) -> A { +pub fn min>(self: &IA) -> A { match do foldl::,IA>(self, None) |a, b| { match a { &Some(ref a_) if *a_ < *b => { @@ -230,7 +223,7 @@ pub pure fn min>(self: &IA) -> A { } #[inline(always)] -pub pure fn max>(self: &IA) -> A { +pub fn max>(self: &IA) -> A { match do foldl::,IA>(self, None) |a, b| { match a { &Some(ref a_) if *a_ > *b => { @@ -245,8 +238,8 @@ pub pure fn max>(self: &IA) -> A { } #[inline(always)] -pub pure fn find>(self: &IA, - f: &fn(&A) -> bool) -> Option { +pub fn find>(self: &IA, f: &fn(&A) -> bool) + -> Option { for self.each |i| { if f(i) { return Some(*i) } } @@ -266,8 +259,7 @@ pub pure fn find>(self: &IA, * onto the sequence being constructed. */ #[inline(always)] -pub pure fn build>(builder: &fn(push: &pure fn(A))) - -> B { +pub fn build>(builder: &fn(push: &fn(A))) -> B { Buildable::build_sized(4, builder) } @@ -285,10 +277,8 @@ pub pure fn build>(builder: &fn(push: &pure fn(A))) * onto the sequence being constructed. */ #[inline(always)] -pub pure fn build_sized_opt>( - size: Option, - builder: &fn(push: &pure fn(A))) -> B { - +pub fn build_sized_opt>(size: Option, + builder: &fn(push: &fn(A))) -> B { Buildable::build_sized(size.get_or_default(4), builder) } @@ -312,8 +302,7 @@ pub fn map,U,BU: Buildable>(v: &IT, f: &fn(&T) -> U) * to the value returned by the function `op`. */ #[inline(always)] -pub pure fn from_fn>(n_elts: uint, - op: InitOp) -> BT { +pub fn from_fn>(n_elts: uint, op: InitOp) -> BT { do Buildable::build_sized(n_elts) |push| { let mut i: uint = 0u; while i < n_elts { push(op(i)); i += 1u; } @@ -327,8 +316,7 @@ pub pure fn from_fn>(n_elts: uint, * to the value `t`. */ #[inline(always)] -pub pure fn from_elem>(n_elts: uint, - t: T) -> BT { +pub fn from_elem>(n_elts: uint, t: T) -> BT { do Buildable::build_sized(n_elts) |push| { let mut i: uint = 0; while i < n_elts { push(t); i += 1; } @@ -337,8 +325,8 @@ pub pure fn from_elem>(n_elts: uint, /// Appends two generic sequences. #[inline(always)] -pub pure fn append,BT:Buildable>( - lhs: &IT, rhs: &IT) -> BT { +pub 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| { @@ -350,8 +338,7 @@ pub pure fn append,BT:Buildable>( /// Copies a generic sequence, possibly converting it to a different /// type of sequence. #[inline(always)] -pub pure fn copy_seq,BT:Buildable>( - v: &IT) -> BT { +pub 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 6a3ed22cea9b9..47eece81ce1c9 100644 --- a/src/libcore/libc.rs +++ b/src/libcore/libc.rs @@ -230,8 +230,6 @@ pub mod types { pub type uintptr_t = uint; } pub mod posix88 { - use prelude::*; - pub type off_t = i32; pub type dev_t = u64; pub type ino_t = u32; @@ -734,52 +732,52 @@ pub mod consts { #[cfg(target_os = "win32")] 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; + pub static EXIT_FAILURE : int = 1; + pub static EXIT_SUCCESS : int = 0; + pub static RAND_MAX : int = 32767; + pub static EOF : int = -1; + pub static SEEK_SET : int = 0; + pub static SEEK_CUR : int = 1; + pub static SEEK_END : int = 2; + pub static _IOFBF : int = 0; + pub static _IONBF : int = 4; + pub static _IOLBF : int = 64; + pub static BUFSIZ : uint = 512_u; + pub static FOPEN_MAX : uint = 20_u; + pub static FILENAME_MAX : uint = 260_u; + pub static L_tmpnam : uint = 16_u; + pub static TMP_MAX : uint = 32767_u; } pub mod c99 { } 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 static O_RDONLY : int = 0; + pub static O_WRONLY : int = 1; + pub static O_RDWR : int = 2; + pub static O_APPEND : int = 8; + pub static O_CREAT : int = 256; + pub static O_EXCL : int = 1024; + pub static O_TRUNC : int = 512; + pub static S_IFIFO : int = 4096; + pub static S_IFCHR : int = 8192; + pub static S_IFBLK : int = 12288; + pub static S_IFDIR : int = 16384; + pub static S_IFREG : int = 32768; + pub static S_IFMT : int = 61440; + pub static S_IEXEC : int = 64; + pub static S_IWRITE : int = 128; + pub static S_IREAD : int = 256; + pub static S_IRWXU : int = 448; + pub static S_IXUSR : int = 64; + pub static S_IWUSR : int = 128; + pub static S_IRUSR : int = 256; + pub static F_OK : int = 0; + pub static R_OK : int = 4; + pub static W_OK : int = 2; + pub static X_OK : int = 1; + pub static STDIN_FILENO : int = 0; + pub static STDOUT_FILENO : int = 1; + pub static STDERR_FILENO : int = 2; } pub mod posix01 { } @@ -788,13 +786,13 @@ pub mod consts { pub mod bsd44 { } pub mod extra { - pub const O_TEXT : int = 16384; - pub const O_BINARY : int = 32768; - pub const O_NOINHERIT: int = 128; + pub static O_TEXT : int = 16384; + pub static O_BINARY : int = 32768; + pub static O_NOINHERIT: int = 128; - pub const ERROR_SUCCESS : int = 0; - pub const ERROR_INSUFFICIENT_BUFFER : int = 122; - pub const INVALID_HANDLE_VALUE: int = -1; + pub static ERROR_SUCCESS : int = 0; + pub static ERROR_INSUFFICIENT_BUFFER : int = 122; + pub static INVALID_HANDLE_VALUE: int = -1; } } @@ -803,56 +801,56 @@ pub mod consts { #[cfg(target_os = "android")] 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; + pub static EXIT_FAILURE : int = 1; + pub static EXIT_SUCCESS : int = 0; + pub static RAND_MAX : int = 2147483647; + pub static EOF : int = -1; + pub static SEEK_SET : int = 0; + pub static SEEK_CUR : int = 1; + pub static SEEK_END : int = 2; + pub static _IOFBF : int = 0; + pub static _IONBF : int = 2; + pub static _IOLBF : int = 1; + pub static BUFSIZ : uint = 8192_u; + pub static FOPEN_MAX : uint = 16_u; + pub static FILENAME_MAX : uint = 4096_u; + pub static L_tmpnam : uint = 20_u; + pub static TMP_MAX : uint = 238328_u; } pub mod c99 { } 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 static O_RDONLY : int = 0; + pub static O_WRONLY : int = 1; + pub static O_RDWR : int = 2; + pub static O_APPEND : int = 1024; + pub static O_CREAT : int = 64; + pub static O_EXCL : int = 128; + pub static O_TRUNC : int = 512; + pub static S_IFIFO : int = 4096; + pub static S_IFCHR : int = 8192; + pub static S_IFBLK : int = 24576; + pub static S_IFDIR : int = 16384; + pub static S_IFREG : int = 32768; + pub static S_IFMT : int = 61440; + pub static S_IEXEC : int = 64; + pub static S_IWRITE : int = 128; + pub static S_IREAD : int = 256; + pub static S_IRWXU : int = 448; + pub static S_IXUSR : int = 64; + pub static S_IWUSR : int = 128; + pub static S_IRUSR : int = 256; + pub static F_OK : int = 0; + pub static R_OK : int = 4; + pub static W_OK : int = 2; + pub static X_OK : int = 1; + pub static STDIN_FILENO : int = 0; + pub static STDOUT_FILENO : int = 1; + pub static STDERR_FILENO : int = 2; + pub static F_LOCK : int = 1; + pub static F_TEST : int = 3; + pub static F_TLOCK : int = 2; + pub static F_ULOCK : int = 0; } pub mod posix01 { } @@ -861,65 +859,65 @@ pub mod consts { pub mod bsd44 { } pub mod extra { - pub const O_RSYNC : int = 1052672; - pub const O_DSYNC : int = 4096; - pub const O_SYNC : int = 1052672; + pub static O_RSYNC : int = 1052672; + pub static O_DSYNC : int = 4096; + pub static O_SYNC : int = 1052672; } } #[cfg(target_os = "freebsd")] 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; + pub static EXIT_FAILURE : int = 1; + pub static EXIT_SUCCESS : int = 0; + pub static RAND_MAX : int = 2147483647; + pub static EOF : int = -1; + pub static SEEK_SET : int = 0; + pub static SEEK_CUR : int = 1; + pub static SEEK_END : int = 2; + pub static _IOFBF : int = 0; + pub static _IONBF : int = 2; + pub static _IOLBF : int = 1; + pub static BUFSIZ : uint = 1024_u; + pub static FOPEN_MAX : uint = 20_u; + pub static FILENAME_MAX : uint = 1024_u; + pub static L_tmpnam : uint = 1024_u; + pub static TMP_MAX : uint = 308915776_u; } pub mod c99 { } 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 static O_RDONLY : int = 0; + pub static O_WRONLY : int = 1; + pub static O_RDWR : int = 2; + pub static O_APPEND : int = 8; + pub static O_CREAT : int = 512; + pub static O_EXCL : int = 2048; + pub static O_TRUNC : int = 1024; + pub static S_IFIFO : int = 4096; + pub static S_IFCHR : int = 8192; + pub static S_IFBLK : int = 24576; + pub static S_IFDIR : int = 16384; + pub static S_IFREG : int = 32768; + pub static S_IFMT : int = 61440; + pub static S_IEXEC : int = 64; + pub static S_IWRITE : int = 128; + pub static S_IREAD : int = 256; + pub static S_IRWXU : int = 448; + pub static S_IXUSR : int = 64; + pub static S_IWUSR : int = 128; + pub static S_IRUSR : int = 256; + pub static F_OK : int = 0; + pub static R_OK : int = 4; + pub static W_OK : int = 2; + pub static X_OK : int = 1; + pub static STDIN_FILENO : int = 0; + pub static STDOUT_FILENO : int = 1; + pub static STDERR_FILENO : int = 2; + pub static F_LOCK : int = 1; + pub static F_TEST : int = 3; + pub static F_TLOCK : int = 2; + pub static F_ULOCK : int = 0; } pub mod posix01 { } @@ -928,66 +926,66 @@ pub mod consts { 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; + pub static O_SYNC : int = 128; + pub static CTL_KERN: int = 1; + pub static KERN_PROC: int = 14; + pub static KERN_PROC_PATHNAME: int = 12; } } #[cfg(target_os = "macos")] 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; + pub static EXIT_FAILURE : int = 1; + pub static EXIT_SUCCESS : int = 0; + pub static RAND_MAX : int = 2147483647; + pub static EOF : int = -1; + pub static SEEK_SET : int = 0; + pub static SEEK_CUR : int = 1; + pub static SEEK_END : int = 2; + pub static _IOFBF : int = 0; + pub static _IONBF : int = 2; + pub static _IOLBF : int = 1; + pub static BUFSIZ : uint = 1024_u; + pub static FOPEN_MAX : uint = 20_u; + pub static FILENAME_MAX : uint = 1024_u; + pub static L_tmpnam : uint = 1024_u; + pub static TMP_MAX : uint = 308915776_u; } pub mod c99 { } 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 static O_RDONLY : int = 0; + pub static O_WRONLY : int = 1; + pub static O_RDWR : int = 2; + pub static O_APPEND : int = 8; + pub static O_CREAT : int = 512; + pub static O_EXCL : int = 2048; + pub static O_TRUNC : int = 1024; + pub static S_IFIFO : int = 4096; + pub static S_IFCHR : int = 8192; + pub static S_IFBLK : int = 24576; + pub static S_IFDIR : int = 16384; + pub static S_IFREG : int = 32768; + pub static S_IFMT : int = 61440; + pub static S_IEXEC : int = 64; + pub static S_IWRITE : int = 128; + pub static S_IREAD : int = 256; + pub static S_IRWXU : int = 448; + pub static S_IXUSR : int = 64; + pub static S_IWUSR : int = 128; + pub static S_IRUSR : int = 256; + pub static F_OK : int = 0; + pub static R_OK : int = 4; + pub static W_OK : int = 2; + pub static X_OK : int = 1; + pub static STDIN_FILENO : int = 0; + pub static STDOUT_FILENO : int = 1; + pub static STDERR_FILENO : int = 2; + pub static F_LOCK : int = 1; + pub static F_TEST : int = 3; + pub static F_TLOCK : int = 2; + pub static F_ULOCK : int = 0; } pub mod posix01 { } @@ -996,9 +994,9 @@ pub mod consts { pub mod bsd44 { } pub mod extra { - pub const O_DSYNC : int = 4194304; - pub const O_SYNC : int = 128; - pub const F_FULLFSYNC : int = 51; + pub static O_DSYNC : int = 4194304; + pub static O_SYNC : int = 128; + pub static F_FULLFSYNC : int = 51; } } } diff --git a/src/libcore/managed.rs b/src/libcore/managed.rs index 1bef895ea0b72..4eda5e7b5e8c6 100644 --- a/src/libcore/managed.rs +++ b/src/libcore/managed.rs @@ -16,9 +16,9 @@ use ptr; pub mod raw { - pub const RC_EXCHANGE_UNIQUE : uint = (-1) as uint; - pub const RC_MANAGED_UNIQUE : uint = (-2) as uint; - pub const RC_IMMORTAL : uint = 0x77777777; + pub static RC_EXCHANGE_UNIQUE : uint = (-1) as uint; + pub static RC_MANAGED_UNIQUE : uint = (-2) as uint; + pub static RC_IMMORTAL : uint = 0x77777777; use intrinsic::TyDesc; @@ -37,35 +37,55 @@ pub mod raw { } #[inline(always)] -pub pure fn ptr_eq(a: @T, b: @T) -> bool { +pub 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)) } } #[inline(always)] -pub pure fn mut_ptr_eq(a: @mut T, b: @mut T) -> bool { +pub fn mut_ptr_eq(a: @mut T, b: @mut T) -> bool { //! Determine if two mutable shared boxes point to the same object unsafe { ptr::addr_of(&(*a)) == ptr::addr_of(&(*b)) } } #[cfg(notest)] -impl Eq for @const T { +impl Eq for @T { #[inline(always)] - pure fn eq(&self, other: &@const T) -> bool { *(*self) == *(*other) } + fn eq(&self, other: &@T) -> bool { *(*self) == *(*other) } #[inline(always)] - pure fn ne(&self, other: &@const T) -> bool { *(*self) != *(*other) } + fn ne(&self, other: &@T) -> bool { *(*self) != *(*other) } } #[cfg(notest)] -impl Ord for @const T { +impl Eq for @mut T { #[inline(always)] - pure fn lt(&self, other: &@const T) -> bool { *(*self) < *(*other) } + fn eq(&self, other: &@mut T) -> bool { *(*self) == *(*other) } #[inline(always)] - pure fn le(&self, other: &@const T) -> bool { *(*self) <= *(*other) } + fn ne(&self, other: &@mut T) -> bool { *(*self) != *(*other) } +} + +#[cfg(notest)] +impl Ord for @T { + #[inline(always)] + fn lt(&self, other: &@T) -> bool { *(*self) < *(*other) } + #[inline(always)] + fn le(&self, other: &@T) -> bool { *(*self) <= *(*other) } + #[inline(always)] + fn ge(&self, other: &@T) -> bool { *(*self) >= *(*other) } + #[inline(always)] + fn gt(&self, other: &@T) -> bool { *(*self) > *(*other) } +} + +#[cfg(notest)] +impl Ord for @mut T { + #[inline(always)] + fn lt(&self, other: &@mut T) -> bool { *(*self) < *(*other) } + #[inline(always)] + fn le(&self, other: &@mut T) -> bool { *(*self) <= *(*other) } #[inline(always)] - pure fn ge(&self, other: &@const T) -> bool { *(*self) >= *(*other) } + fn ge(&self, other: &@mut T) -> bool { *(*self) >= *(*other) } #[inline(always)] - pure fn gt(&self, other: &@const T) -> bool { *(*self) > *(*other) } + fn gt(&self, other: &@mut T) -> bool { *(*self) > *(*other) } } #[test] diff --git a/src/libcore/mutable.rs b/src/libcore/mutable.rs index d0aa6e050f53c..fc4e52891dd26 100644 --- a/src/libcore/mutable.rs +++ b/src/libcore/mutable.rs @@ -55,7 +55,7 @@ pub impl Data { } } - pure fn borrow_const(&self, op: &fn(t: &const T) -> R) -> R { + fn borrow_const(&self, op: &fn(t: &const T) -> R) -> R { op(&const self.value) } diff --git a/src/libcore/nil.rs b/src/libcore/nil.rs index 742e5a047d6ca..8c52ac9593a27 100644 --- a/src/libcore/nil.rs +++ b/src/libcore/nil.rs @@ -20,25 +20,25 @@ use cmp::{Eq, Ord, TotalOrd, Ordering, Equal}; #[cfg(notest)] impl Eq for () { #[inline(always)] - pure fn eq(&self, _other: &()) -> bool { true } + fn eq(&self, _other: &()) -> bool { true } #[inline(always)] - pure fn ne(&self, _other: &()) -> bool { false } + fn ne(&self, _other: &()) -> bool { false } } #[cfg(notest)] impl Ord for () { #[inline(always)] - pure fn lt(&self, _other: &()) -> bool { false } + fn lt(&self, _other: &()) -> bool { false } #[inline(always)] - pure fn le(&self, _other: &()) -> bool { true } + fn le(&self, _other: &()) -> bool { true } #[inline(always)] - pure fn ge(&self, _other: &()) -> bool { true } + fn ge(&self, _other: &()) -> bool { true } #[inline(always)] - pure fn gt(&self, _other: &()) -> bool { false } + fn gt(&self, _other: &()) -> bool { false } } #[cfg(notest)] impl TotalOrd for () { #[inline(always)] - pure fn cmp(&self, _other: &()) -> Ordering { Equal } + fn cmp(&self, _other: &()) -> Ordering { Equal } } diff --git a/src/libcore/num/cmath.rs b/src/libcore/num/cmath.rs index 2f9d4304cba70..378ebfa53a0c2 100644 --- a/src/libcore/num/cmath.rs +++ b/src/libcore/num/cmath.rs @@ -174,33 +174,33 @@ pub mod c_float_utils { // FIXME obtain machine float/math constants automatically (Issue #1986) 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: uint = -125u; - pub const max_exp: uint = 128u; - pub const min_10_exp: int = -37; - pub const max_10_exp: int = 38; - // FIXME (#1433): this is wrong, replace with hexadecimal (%a) constants + pub static radix: uint = 2u; + pub static mantissa_digits: uint = 24u; + pub static digits: uint = 6u; + pub static min_exp: uint = -125u; + pub static max_exp: uint = 128u; + pub static min_10_exp: int = -37; + pub static max_10_exp: int = 38; + // FIXME (#1433): this is wrong, replace with hexadecimal (%a) staticants // below. - pub const min_value: f32 = 1.175494e-38_f32; - pub const max_value: f32 = 3.402823e+38_f32; - pub const epsilon: f32 = 0.000000_f32; + pub static min_value: f32 = 1.175494e-38_f32; + pub static max_value: f32 = 3.402823e+38_f32; + pub static epsilon: f32 = 0.000000_f32; } 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: uint = -1021u; - pub const max_exp: uint = 1024u; - pub const min_10_exp: int = -307; - pub const max_10_exp: int = 308; - // FIXME (#1433): this is wrong, replace with hexadecimal (%a) constants + pub static radix: uint = 2u; + pub static mantissa_digits: uint = 53u; + pub static digits: uint = 15u; + pub static min_exp: uint = -1021u; + pub static max_exp: uint = 1024u; + pub static min_10_exp: int = -307; + pub static max_10_exp: int = 308; + // FIXME (#1433): this is wrong, replace with hexadecimal (%a) staticants // below. - pub const min_value: f64 = 2.225074e-308_f64; - pub const max_value: f64 = 1.797693e+308_f64; - pub const epsilon: f64 = 2.220446e-16_f64; + pub static min_value: f64 = 2.225074e-308_f64; + pub static max_value: f64 = 1.797693e+308_f64; + pub static epsilon: f64 = 2.220446e-16_f64; } /* @@ -208,61 +208,61 @@ pub mod c_double_targ_consts { FIXME use these once they can be parsed (see Issue #1433) 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; + pub static pi: c_float = 0x1.921fb6p+1_f32; + pub static div_1_pi: c_float = 0x1.45f306p-2_f32; + pub static div_2_pi: c_float = 0x1.45f306p-1_f32; + pub static div_pi_2: c_float = 0x1.921fb6p+0_f32; + pub static div_pi_4: c_float = 0x1.921fb6p-1_f32; + pub static div_2_sqrtpi: c_float = 0x1.20dd76p+0_f32; + pub static e: c_float = 0x1.5bf0a8p+1_f32; + pub static log2_e: c_float = 0x1.715476p+0_f32; + pub static log10_e: c_float = 0x1.bcb7b2p-2_f32; + pub static ln_2: c_float = 0x1.62e43p-1_f32; + pub static ln_10: c_float = 0x1.26bb1cp+1_f32; + pub static sqrt2: c_float = 0x1.6a09e6p+0_f32; + pub static div_1_sqrt2: c_float = 0x1.6a09e6p-1_f32; } 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; + pub static pi: c_double = 0x1.921fb54442d18p+1_f64; + pub static div_1_pi: c_double = 0x1.45f306dc9c883p-2_f64; + pub static div_2_pi: c_double = 0x1.45f306dc9c883p-1_f64; + pub static div_pi_2: c_double = 0x1.921fb54442d18p+0_f64; + pub static div_pi_4: c_double = 0x1.921fb54442d18p-1_f64; + pub static div_2_sqrtpi: c_double = 0x1.20dd750429b6dp+0_f64; + pub static e: c_double = 0x1.5bf0a8b145769p+1_f64; + pub static log2_e: c_double = 0x1.71547652b82fep+0_f64; + pub static log10_e: c_double = 0x1.bcb7b1526e50ep-2_f64; + pub static ln_2: c_double = 0x1.62e42fefa39efp-1_f64; + pub static ln_10: c_double = 0x1.26bb1bbb55516p+1_f64; + pub static sqrt2: c_double = 0x1.6a09e667f3bcdp+0_f64; + pub static div_1_sqrt2: c_double = 0x1.6a09e667f3bcdp-1_f64; } 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; + pub static radix: uint = 2u; + pub static mantissa_digits: uint = 24u; + pub static digits: uint = 6u; + pub static min_exp: int = -125; + pub static max_exp: int = 128; + pub static min_10_exp: int = -37; + pub static max_10_exp: int = 38; + pub static min_value: c_float = 0x1p-126_f32; + pub static max_value: c_float = 0x1.fffffep+127_f32; + pub static epsilon: c_float = 0x1p-23_f32; } 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; + pub static radix: uint = 2u; + pub static mantissa_digits: uint = 53u; + pub static digits: uint = 15u; + pub static min_exp: int = -1021; + pub static max_exp: int = 1024; + pub static min_10_exp: int = -307; + pub static max_10_exp: int = 308; + pub static min_value: c_double = 0x1p-1022_f64; + pub static max_value: c_double = 0x1.fffffffffffffp+1023_f64; + pub static epsilon: c_double = 0x1p-52_f64; } */ diff --git a/src/libcore/num/f32.rs b/src/libcore/num/f32.rs index 54521abea9ec0..4a8649fb66e78 100644 --- a/src/libcore/num/f32.rs +++ b/src/libcore/num/f32.rs @@ -33,7 +33,7 @@ macro_rules! delegate( ),* ) -> $rv:ty = $bound_name:path ) => ( - pub pure fn $name($( $arg : $arg_ty ),*) -> $rv { + pub fn $name($( $arg : $arg_ty ),*) -> $rv { unsafe { $bound_name($( $arg ),*) } @@ -102,64 +102,66 @@ delegate!(fn trunc(n: c_float) -> c_float = cmath::c_float_utils::trunc) // These are not defined inside consts:: for consistency with // the integer types -pub const NaN: f32 = 0.0_f32/0.0_f32; +pub static NaN: f32 = 0.0_f32/0.0_f32; -pub const infinity: f32 = 1.0_f32/0.0_f32; +pub static infinity: f32 = 1.0_f32/0.0_f32; -pub const neg_infinity: f32 = -1.0_f32/0.0_f32; +pub static neg_infinity: f32 = -1.0_f32/0.0_f32; #[inline(always)] -pub pure fn is_NaN(f: f32) -> bool { f != f } +pub fn is_NaN(f: f32) -> bool { f != f } #[inline(always)] -pub pure fn add(x: f32, y: f32) -> f32 { return x + y; } +pub fn add(x: f32, y: f32) -> f32 { return x + y; } #[inline(always)] -pub pure fn sub(x: f32, y: f32) -> f32 { return x - y; } +pub fn sub(x: f32, y: f32) -> f32 { return x - y; } #[inline(always)] -pub pure fn mul(x: f32, y: f32) -> f32 { return x * y; } +pub fn mul(x: f32, y: f32) -> f32 { return x * y; } #[inline(always)] -pub pure fn div(x: f32, y: f32) -> f32 { return x / y; } +pub fn div(x: f32, y: f32) -> f32 { return x / y; } #[inline(always)] -pub pure fn rem(x: f32, y: f32) -> f32 { return x % y; } +pub fn rem(x: f32, y: f32) -> f32 { return x % y; } #[inline(always)] -pub pure fn lt(x: f32, y: f32) -> bool { return x < y; } +pub fn lt(x: f32, y: f32) -> bool { return x < y; } #[inline(always)] -pub pure fn le(x: f32, y: f32) -> bool { return x <= y; } +pub fn le(x: f32, y: f32) -> bool { return x <= y; } #[inline(always)] -pub pure fn eq(x: f32, y: f32) -> bool { return x == y; } +pub fn eq(x: f32, y: f32) -> bool { return x == y; } #[inline(always)] -pub pure fn ne(x: f32, y: f32) -> bool { return x != y; } +pub fn ne(x: f32, y: f32) -> bool { return x != y; } #[inline(always)] -pub pure fn ge(x: f32, y: f32) -> bool { return x >= y; } +pub fn ge(x: f32, y: f32) -> bool { return x >= y; } #[inline(always)] -pub pure fn gt(x: f32, y: f32) -> bool { return x > y; } +pub fn gt(x: f32, y: f32) -> bool { return x > y; } /// Returns `x` rounded down #[inline(always)] -pub pure fn floor(x: f32) -> f32 { unsafe { floorf32(x) } } +pub fn floor(x: f32) -> f32 { unsafe { floorf32(x) } } // 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 #[inline(always)] -pub pure fn is_positive(x: f32) -> bool - { return x > 0.0f32 || (1.0f32/x) == infinity; } +pub fn is_positive(x: f32) -> bool { + x > 0.0f32 || (1.0f32/x) == infinity +} /// Returns true if `x` is a negative number, including -0.0f320 and -Infinity #[inline(always)] -pub pure fn is_negative(x: f32) -> bool - { return x < 0.0f32 || (1.0f32/x) == neg_infinity; } +pub fn is_negative(x: f32) -> bool { + x < 0.0f32 || (1.0f32/x) == neg_infinity +} /** * Returns true if `x` is a negative number, including -0.0f320 and -Infinity @@ -167,7 +169,7 @@ pub pure fn is_negative(x: f32) -> bool * This is the same as `f32::is_negative`. */ #[inline(always)] -pub pure fn is_nonpositive(x: f32) -> bool { +pub fn is_nonpositive(x: f32) -> bool { return x < 0.0f32 || (1.0f32/x) == neg_infinity; } @@ -177,25 +179,25 @@ pub pure fn is_nonpositive(x: f32) -> bool { * This is the same as `f32::is_positive`.) */ #[inline(always)] -pub pure fn is_nonnegative(x: f32) -> bool { +pub 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) #[inline(always)] -pub pure fn is_zero(x: f32) -> bool { +pub fn is_zero(x: f32) -> bool { return x == 0.0f32 || x == -0.0f32; } /// Returns true if `x`is an infinite number #[inline(always)] -pub pure fn is_infinite(x: f32) -> bool { +pub fn is_infinite(x: f32) -> bool { return x == infinity || x == neg_infinity; } /// Returns true if `x`is a finite number #[inline(always)] -pub pure fn is_finite(x: f32) -> bool { +pub fn is_finite(x: f32) -> bool { return !(is_NaN(x) || is_infinite(x)); } @@ -204,85 +206,85 @@ pub pure fn is_finite(x: f32) -> bool { /* Module: consts */ pub mod consts { // FIXME (requires Issue #1433 to fix): replace with mathematical - // constants from cmath. - /// Archimedes' constant - pub const pi: f32 = 3.14159265358979323846264338327950288_f32; + // staticants from cmath. + /// Archimedes' staticant + pub static pi: f32 = 3.14159265358979323846264338327950288_f32; /// pi/2.0 - pub const frac_pi_2: f32 = 1.57079632679489661923132169163975144_f32; + pub static frac_pi_2: f32 = 1.57079632679489661923132169163975144_f32; /// pi/4.0 - pub const frac_pi_4: f32 = 0.785398163397448309615660845819875721_f32; + pub static frac_pi_4: f32 = 0.785398163397448309615660845819875721_f32; /// 1.0/pi - pub const frac_1_pi: f32 = 0.318309886183790671537767526745028724_f32; + pub static frac_1_pi: f32 = 0.318309886183790671537767526745028724_f32; /// 2.0/pi - pub const frac_2_pi: f32 = 0.636619772367581343075535053490057448_f32; + pub static frac_2_pi: f32 = 0.636619772367581343075535053490057448_f32; /// 2.0/sqrt(pi) - pub const frac_2_sqrtpi: f32 = 1.12837916709551257389615890312154517_f32; + pub static frac_2_sqrtpi: f32 = 1.12837916709551257389615890312154517_f32; /// sqrt(2.0) - pub const sqrt2: f32 = 1.41421356237309504880168872420969808_f32; + pub static sqrt2: f32 = 1.41421356237309504880168872420969808_f32; /// 1.0/sqrt(2.0) - pub const frac_1_sqrt2: f32 = 0.707106781186547524400844362104849039_f32; + pub static frac_1_sqrt2: f32 = 0.707106781186547524400844362104849039_f32; /// Euler's number - pub const e: f32 = 2.71828182845904523536028747135266250_f32; + pub static e: f32 = 2.71828182845904523536028747135266250_f32; /// log2(e) - pub const log2_e: f32 = 1.44269504088896340735992468100189214_f32; + pub static log2_e: f32 = 1.44269504088896340735992468100189214_f32; /// log10(e) - pub const log10_e: f32 = 0.434294481903251827651128918916605082_f32; + pub static log10_e: f32 = 0.434294481903251827651128918916605082_f32; /// ln(2.0) - pub const ln_2: f32 = 0.693147180559945309417232121458176568_f32; + pub static ln_2: f32 = 0.693147180559945309417232121458176568_f32; /// ln(10.0) - pub const ln_10: f32 = 2.30258509299404568401799145468436421_f32; + pub static ln_10: f32 = 2.30258509299404568401799145468436421_f32; } #[inline(always)] -pub pure fn signbit(x: f32) -> int { +pub fn signbit(x: f32) -> int { if is_negative(x) { return 1; } else { return 0; } } #[inline(always)] -pub pure fn logarithm(n: f32, b: f32) -> f32 { +pub fn logarithm(n: f32, b: f32) -> f32 { return log2(n) / log2(b); } #[cfg(notest)] impl cmp::Eq for f32 { #[inline(always)] - pure fn eq(&self, other: &f32) -> bool { (*self) == (*other) } + fn eq(&self, other: &f32) -> bool { (*self) == (*other) } #[inline(always)] - pure fn ne(&self, other: &f32) -> bool { (*self) != (*other) } + fn ne(&self, other: &f32) -> bool { (*self) != (*other) } } #[cfg(notest)] impl cmp::Ord for f32 { #[inline(always)] - pure fn lt(&self, other: &f32) -> bool { (*self) < (*other) } + fn lt(&self, other: &f32) -> bool { (*self) < (*other) } #[inline(always)] - pure fn le(&self, other: &f32) -> bool { (*self) <= (*other) } + fn le(&self, other: &f32) -> bool { (*self) <= (*other) } #[inline(always)] - pure fn ge(&self, other: &f32) -> bool { (*self) >= (*other) } + fn ge(&self, other: &f32) -> bool { (*self) >= (*other) } #[inline(always)] - pure fn gt(&self, other: &f32) -> bool { (*self) > (*other) } + fn gt(&self, other: &f32) -> bool { (*self) > (*other) } } impl num::Zero for f32 { #[inline(always)] - static pure fn zero() -> f32 { 0.0 } + fn zero() -> f32 { 0.0 } } impl num::One for f32 { #[inline(always)] - static pure fn one() -> f32 { 1.0 } + fn one() -> f32 { 1.0 } } impl NumCast for f32 { @@ -290,53 +292,53 @@ impl NumCast for f32 { * Cast `n` to an `f32` */ #[inline(always)] - static pure fn from(n: N) -> f32 { n.to_f32() } + fn from(n: N) -> f32 { n.to_f32() } - #[inline(always)] pure fn to_u8(&self) -> u8 { *self as u8 } - #[inline(always)] pure fn to_u16(&self) -> u16 { *self as u16 } - #[inline(always)] pure fn to_u32(&self) -> u32 { *self as u32 } - #[inline(always)] pure fn to_u64(&self) -> u64 { *self as u64 } - #[inline(always)] pure fn to_uint(&self) -> uint { *self as uint } + #[inline(always)] fn to_u8(&self) -> u8 { *self as u8 } + #[inline(always)] fn to_u16(&self) -> u16 { *self as u16 } + #[inline(always)] fn to_u32(&self) -> u32 { *self as u32 } + #[inline(always)] fn to_u64(&self) -> u64 { *self as u64 } + #[inline(always)] fn to_uint(&self) -> uint { *self as uint } - #[inline(always)] pure fn to_i8(&self) -> i8 { *self as i8 } - #[inline(always)] pure fn to_i16(&self) -> i16 { *self as i16 } - #[inline(always)] pure fn to_i32(&self) -> i32 { *self as i32 } - #[inline(always)] pure fn to_i64(&self) -> i64 { *self as i64 } - #[inline(always)] pure fn to_int(&self) -> int { *self as int } + #[inline(always)] fn to_i8(&self) -> i8 { *self as i8 } + #[inline(always)] fn to_i16(&self) -> i16 { *self as i16 } + #[inline(always)] fn to_i32(&self) -> i32 { *self as i32 } + #[inline(always)] fn to_i64(&self) -> i64 { *self as i64 } + #[inline(always)] fn to_int(&self) -> int { *self as int } - #[inline(always)] pure fn to_f32(&self) -> f32 { *self } - #[inline(always)] pure fn to_f64(&self) -> f64 { *self as f64 } - #[inline(always)] pure fn to_float(&self) -> float { *self as float } + #[inline(always)] fn to_f32(&self) -> f32 { *self } + #[inline(always)] fn to_f64(&self) -> f64 { *self as f64 } + #[inline(always)] fn to_float(&self) -> float { *self as float } } #[cfg(notest)] impl ops::Add for f32 { - pure fn add(&self, other: &f32) -> f32 { *self + *other } + fn add(&self, other: &f32) -> f32 { *self + *other } } #[cfg(notest)] impl ops::Sub for f32 { - pure fn sub(&self, other: &f32) -> f32 { *self - *other } + fn sub(&self, other: &f32) -> f32 { *self - *other } } #[cfg(notest)] impl ops::Mul for f32 { - pure fn mul(&self, other: &f32) -> f32 { *self * *other } + fn mul(&self, other: &f32) -> f32 { *self * *other } } #[cfg(notest)] impl ops::Div for f32 { - pure fn div(&self, other: &f32) -> f32 { *self / *other } + fn div(&self, other: &f32) -> f32 { *self / *other } } #[cfg(notest)] impl ops::Modulo for f32 { - pure fn modulo(&self, other: &f32) -> f32 { *self % *other } + fn modulo(&self, other: &f32) -> f32 { *self % *other } } #[cfg(notest)] impl ops::Neg for f32 { - pure fn neg(&self) -> f32 { -*self } + fn neg(&self) -> f32 { -*self } } impl num::Round for f32 { #[inline(always)] - pure fn round(&self, mode: num::RoundMode) -> f32 { + fn round(&self, mode: num::RoundMode) -> f32 { match mode { num::RoundDown => floor(*self), num::RoundUp => ceil(*self), @@ -348,11 +350,11 @@ impl num::Round for f32 { } #[inline(always)] - pure fn floor(&self) -> f32 { floor(*self) } + fn floor(&self) -> f32 { floor(*self) } #[inline(always)] - pure fn ceil(&self) -> f32 { ceil(*self) } + fn ceil(&self) -> f32 { ceil(*self) } #[inline(always)] - pure fn fract(&self) -> f32 { + fn fract(&self) -> f32 { if is_negative(*self) { (*self) - ceil(*self) } else { @@ -373,7 +375,7 @@ impl num::Round for f32 { * * num - The float value */ #[inline(always)] -pub pure fn to_str(num: f32) -> ~str { +pub fn to_str(num: f32) -> ~str { let (r, _) = strconv::to_str_common( &num, 10u, true, strconv::SignNeg, strconv::DigAll); r @@ -387,7 +389,7 @@ pub pure fn to_str(num: f32) -> ~str { * * num - The float value */ #[inline(always)] -pub pure fn to_str_hex(num: f32) -> ~str { +pub fn to_str_hex(num: f32) -> ~str { let (r, _) = strconv::to_str_common( &num, 16u, true, strconv::SignNeg, strconv::DigAll); r @@ -408,7 +410,7 @@ pub pure fn to_str_hex(num: f32) -> ~str { * are expected, use `to_str_radix_special()` instead. */ #[inline(always)] -pub pure fn to_str_radix(num: f32, rdx: uint) -> ~str { +pub fn to_str_radix(num: f32, rdx: uint) -> ~str { let (r, special) = strconv::to_str_common( &num, rdx, true, strconv::SignNeg, strconv::DigAll); if special { fail!(~"number has a special value, \ @@ -426,7 +428,7 @@ pub pure fn to_str_radix(num: f32, rdx: uint) -> ~str { * * radix - The base to use */ #[inline(always)] -pub pure fn to_str_radix_special(num: f32, rdx: uint) -> (~str, bool) { +pub fn to_str_radix_special(num: f32, rdx: uint) -> (~str, bool) { strconv::to_str_common(&num, rdx, true, strconv::SignNeg, strconv::DigAll) } @@ -441,7 +443,7 @@ pub pure fn to_str_radix_special(num: f32, rdx: uint) -> (~str, bool) { * * digits - The number of significant digits */ #[inline(always)] -pub pure fn to_str_exact(num: f32, dig: uint) -> ~str { +pub fn to_str_exact(num: f32, dig: uint) -> ~str { let (r, _) = strconv::to_str_common( &num, 10u, true, strconv::SignNeg, strconv::DigExact(dig)); r @@ -457,7 +459,7 @@ pub pure fn to_str_exact(num: f32, dig: uint) -> ~str { * * digits - The number of significant digits */ #[inline(always)] -pub pure fn to_str_digits(num: f32, dig: uint) -> ~str { +pub fn to_str_digits(num: f32, dig: uint) -> ~str { let (r, _) = strconv::to_str_common( &num, 10u, true, strconv::SignNeg, strconv::DigMax(dig)); r @@ -465,12 +467,12 @@ pub pure fn to_str_digits(num: f32, dig: uint) -> ~str { impl to_str::ToStr for f32 { #[inline(always)] - pure fn to_str(&self) -> ~str { to_str_digits(*self, 8) } + fn to_str(&self) -> ~str { to_str_digits(*self, 8) } } impl num::ToStrRadix for f32 { #[inline(always)] - pure fn to_str_radix(&self, rdx: uint) -> ~str { + fn to_str_radix(&self, rdx: uint) -> ~str { to_str_radix(*self, rdx) } } @@ -503,7 +505,7 @@ impl num::ToStrRadix for f32 { * `Some(n)` where `n` is the floating-point number represented by `num`. */ #[inline(always)] -pub pure fn from_str(num: &str) -> Option { +pub fn from_str(num: &str) -> Option { strconv::from_str_common(num, 10u, true, true, true, strconv::ExpDec, false) } @@ -536,7 +538,7 @@ pub pure fn from_str(num: &str) -> Option { * `Some(n)` where `n` is the floating-point number represented by `[num]`. */ #[inline(always)] -pub pure fn from_str_hex(num: &str) -> Option { +pub fn from_str_hex(num: &str) -> Option { strconv::from_str_common(num, 16u, true, true, true, strconv::ExpBin, false) } @@ -561,19 +563,19 @@ pub pure fn from_str_hex(num: &str) -> Option { * `Some(n)` where `n` is the floating-point number represented by `num`. */ #[inline(always)] -pub pure fn from_str_radix(num: &str, rdx: uint) -> Option { +pub fn from_str_radix(num: &str, rdx: uint) -> Option { strconv::from_str_common(num, rdx, true, true, false, strconv::ExpNone, false) } impl from_str::FromStr for f32 { #[inline(always)] - static pure fn from_str(val: &str) -> Option { from_str(val) } + fn from_str(val: &str) -> Option { from_str(val) } } impl num::FromStrRadix for f32 { #[inline(always)] - static pure fn from_str_radix(val: &str, rdx: uint) -> Option { + fn from_str_radix(val: &str, rdx: uint) -> Option { from_str_radix(val, rdx) } } diff --git a/src/libcore/num/f64.rs b/src/libcore/num/f64.rs index a2cf629dc9f36..8107110e977d8 100644 --- a/src/libcore/num/f64.rs +++ b/src/libcore/num/f64.rs @@ -34,7 +34,7 @@ macro_rules! delegate( ),* ) -> $rv:ty = $bound_name:path ) => ( - pub pure fn $name($( $arg : $arg_ty ),*) -> $rv { + pub fn $name($( $arg : $arg_ty ),*) -> $rv { unsafe { $bound_name($( $arg ),*) } @@ -113,72 +113,72 @@ delegate!(fn yn(i: c_int, n: c_double) -> c_double = // These are not defined inside consts:: for consistency with // the integer types -pub const radix: uint = 2u; +pub static radix: uint = 2u; -pub const mantissa_digits: uint = 53u; -pub const digits: uint = 15u; +pub static mantissa_digits: uint = 53u; +pub static digits: uint = 15u; -pub const epsilon: f64 = 2.2204460492503131e-16_f64; +pub static epsilon: f64 = 2.2204460492503131e-16_f64; -pub const min_value: f64 = 2.2250738585072014e-308_f64; -pub const max_value: f64 = 1.7976931348623157e+308_f64; +pub static min_value: f64 = 2.2250738585072014e-308_f64; +pub static max_value: f64 = 1.7976931348623157e+308_f64; -pub const min_exp: int = -1021; -pub const max_exp: int = 1024; +pub static min_exp: int = -1021; +pub static max_exp: int = 1024; -pub const min_10_exp: int = -307; -pub const max_10_exp: int = 308; +pub static min_10_exp: int = -307; +pub static max_10_exp: int = 308; -pub const NaN: f64 = 0.0_f64/0.0_f64; +pub static NaN: f64 = 0.0_f64/0.0_f64; -pub const infinity: f64 = 1.0_f64/0.0_f64; +pub static infinity: f64 = 1.0_f64/0.0_f64; -pub const neg_infinity: f64 = -1.0_f64/0.0_f64; +pub static neg_infinity: f64 = -1.0_f64/0.0_f64; #[inline(always)] -pub pure fn is_NaN(f: f64) -> bool { f != f } +pub fn is_NaN(f: f64) -> bool { f != f } #[inline(always)] -pub pure fn add(x: f64, y: f64) -> f64 { return x + y; } +pub fn add(x: f64, y: f64) -> f64 { return x + y; } #[inline(always)] -pub pure fn sub(x: f64, y: f64) -> f64 { return x - y; } +pub fn sub(x: f64, y: f64) -> f64 { return x - y; } #[inline(always)] -pub pure fn mul(x: f64, y: f64) -> f64 { return x * y; } +pub fn mul(x: f64, y: f64) -> f64 { return x * y; } #[inline(always)] -pub pure fn div(x: f64, y: f64) -> f64 { return x / y; } +pub fn div(x: f64, y: f64) -> f64 { return x / y; } #[inline(always)] -pub pure fn rem(x: f64, y: f64) -> f64 { return x % y; } +pub fn rem(x: f64, y: f64) -> f64 { return x % y; } #[inline(always)] -pub pure fn lt(x: f64, y: f64) -> bool { return x < y; } +pub fn lt(x: f64, y: f64) -> bool { return x < y; } #[inline(always)] -pub pure fn le(x: f64, y: f64) -> bool { return x <= y; } +pub fn le(x: f64, y: f64) -> bool { return x <= y; } #[inline(always)] -pub pure fn eq(x: f64, y: f64) -> bool { return x == y; } +pub fn eq(x: f64, y: f64) -> bool { return x == y; } #[inline(always)] -pub pure fn ne(x: f64, y: f64) -> bool { return x != y; } +pub fn ne(x: f64, y: f64) -> bool { return x != y; } #[inline(always)] -pub pure fn ge(x: f64, y: f64) -> bool { return x >= y; } +pub fn ge(x: f64, y: f64) -> bool { return x >= y; } #[inline(always)] -pub pure fn gt(x: f64, y: f64) -> bool { return x > y; } +pub fn gt(x: f64, y: f64) -> bool { return x > y; } /// Returns true if `x` is a positive number, including +0.0f640 and +Infinity #[inline(always)] -pub pure fn is_positive(x: f64) -> bool +pub 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 #[inline(always)] -pub pure fn is_negative(x: f64) -> bool +pub fn is_negative(x: f64) -> bool { return x < 0.0f64 || (1.0f64/x) == neg_infinity; } /** @@ -187,7 +187,7 @@ pub pure fn is_negative(x: f64) -> bool * This is the same as `f64::is_negative`. */ #[inline(always)] -pub pure fn is_nonpositive(x: f64) -> bool { +pub fn is_nonpositive(x: f64) -> bool { return x < 0.0f64 || (1.0f64/x) == neg_infinity; } @@ -197,31 +197,31 @@ pub pure fn is_nonpositive(x: f64) -> bool { * This is the same as `f64::positive`. */ #[inline(always)] -pub pure fn is_nonnegative(x: f64) -> bool { +pub 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) #[inline(always)] -pub pure fn is_zero(x: f64) -> bool { +pub fn is_zero(x: f64) -> bool { return x == 0.0f64 || x == -0.0f64; } /// Returns true if `x`is an infinite number #[inline(always)] -pub pure fn is_infinite(x: f64) -> bool { +pub fn is_infinite(x: f64) -> bool { return x == infinity || x == neg_infinity; } /// Returns true if `x` is a finite number #[inline(always)] -pub pure fn is_finite(x: f64) -> bool { +pub fn is_finite(x: f64) -> bool { return !(is_NaN(x) || is_infinite(x)); } /// Returns `x` rounded down #[inline(always)] -pub pure fn floor(x: f64) -> f64 { unsafe { floorf64(x) } } +pub fn floor(x: f64) -> f64 { unsafe { floorf64(x) } } // FIXME (#1999): add is_normal, is_subnormal, and fpclassify @@ -230,73 +230,73 @@ pub mod consts { // FIXME (requires Issue #1433 to fix): replace with mathematical // constants from cmath. /// Archimedes' constant - pub const pi: f64 = 3.14159265358979323846264338327950288_f64; + pub static pi: f64 = 3.14159265358979323846264338327950288_f64; /// pi/2.0 - pub const frac_pi_2: f64 = 1.57079632679489661923132169163975144_f64; + pub static frac_pi_2: f64 = 1.57079632679489661923132169163975144_f64; /// pi/4.0 - pub const frac_pi_4: f64 = 0.785398163397448309615660845819875721_f64; + pub static frac_pi_4: f64 = 0.785398163397448309615660845819875721_f64; /// 1.0/pi - pub const frac_1_pi: f64 = 0.318309886183790671537767526745028724_f64; + pub static frac_1_pi: f64 = 0.318309886183790671537767526745028724_f64; /// 2.0/pi - pub const frac_2_pi: f64 = 0.636619772367581343075535053490057448_f64; + pub static frac_2_pi: f64 = 0.636619772367581343075535053490057448_f64; /// 2.0/sqrt(pi) - pub const frac_2_sqrtpi: f64 = 1.12837916709551257389615890312154517_f64; + pub static frac_2_sqrtpi: f64 = 1.12837916709551257389615890312154517_f64; /// sqrt(2.0) - pub const sqrt2: f64 = 1.41421356237309504880168872420969808_f64; + pub static sqrt2: f64 = 1.41421356237309504880168872420969808_f64; /// 1.0/sqrt(2.0) - pub const frac_1_sqrt2: f64 = 0.707106781186547524400844362104849039_f64; + pub static frac_1_sqrt2: f64 = 0.707106781186547524400844362104849039_f64; /// Euler's number - pub const e: f64 = 2.71828182845904523536028747135266250_f64; + pub static e: f64 = 2.71828182845904523536028747135266250_f64; /// log2(e) - pub const log2_e: f64 = 1.44269504088896340735992468100189214_f64; + pub static log2_e: f64 = 1.44269504088896340735992468100189214_f64; /// log10(e) - pub const log10_e: f64 = 0.434294481903251827651128918916605082_f64; + pub static log10_e: f64 = 0.434294481903251827651128918916605082_f64; /// ln(2.0) - pub const ln_2: f64 = 0.693147180559945309417232121458176568_f64; + pub static ln_2: f64 = 0.693147180559945309417232121458176568_f64; /// ln(10.0) - pub const ln_10: f64 = 2.30258509299404568401799145468436421_f64; + pub static ln_10: f64 = 2.30258509299404568401799145468436421_f64; } #[inline(always)] -pub pure fn signbit(x: f64) -> int { +pub fn signbit(x: f64) -> int { if is_negative(x) { return 1; } else { return 0; } } #[inline(always)] -pub pure fn logarithm(n: f64, b: f64) -> f64 { +pub fn logarithm(n: f64, b: f64) -> f64 { return log2(n) / log2(b); } #[cfg(notest)] impl cmp::Eq for f64 { #[inline(always)] - pure fn eq(&self, other: &f64) -> bool { (*self) == (*other) } + fn eq(&self, other: &f64) -> bool { (*self) == (*other) } #[inline(always)] - pure fn ne(&self, other: &f64) -> bool { (*self) != (*other) } + fn ne(&self, other: &f64) -> bool { (*self) != (*other) } } #[cfg(notest)] impl cmp::Ord for f64 { #[inline(always)] - pure fn lt(&self, other: &f64) -> bool { (*self) < (*other) } + fn lt(&self, other: &f64) -> bool { (*self) < (*other) } #[inline(always)] - pure fn le(&self, other: &f64) -> bool { (*self) <= (*other) } + fn le(&self, other: &f64) -> bool { (*self) <= (*other) } #[inline(always)] - pure fn ge(&self, other: &f64) -> bool { (*self) >= (*other) } + fn ge(&self, other: &f64) -> bool { (*self) >= (*other) } #[inline(always)] - pure fn gt(&self, other: &f64) -> bool { (*self) > (*other) } + fn gt(&self, other: &f64) -> bool { (*self) > (*other) } } impl NumCast for f64 { @@ -304,63 +304,63 @@ impl NumCast for f64 { * Cast `n` to an `f64` */ #[inline(always)] - static pure fn from(n: N) -> f64 { n.to_f64() } + fn from(n: N) -> f64 { n.to_f64() } - #[inline(always)] pure fn to_u8(&self) -> u8 { *self as u8 } - #[inline(always)] pure fn to_u16(&self) -> u16 { *self as u16 } - #[inline(always)] pure fn to_u32(&self) -> u32 { *self as u32 } - #[inline(always)] pure fn to_u64(&self) -> u64 { *self as u64 } - #[inline(always)] pure fn to_uint(&self) -> uint { *self as uint } + #[inline(always)] fn to_u8(&self) -> u8 { *self as u8 } + #[inline(always)] fn to_u16(&self) -> u16 { *self as u16 } + #[inline(always)] fn to_u32(&self) -> u32 { *self as u32 } + #[inline(always)] fn to_u64(&self) -> u64 { *self as u64 } + #[inline(always)] fn to_uint(&self) -> uint { *self as uint } - #[inline(always)] pure fn to_i8(&self) -> i8 { *self as i8 } - #[inline(always)] pure fn to_i16(&self) -> i16 { *self as i16 } - #[inline(always)] pure fn to_i32(&self) -> i32 { *self as i32 } - #[inline(always)] pure fn to_i64(&self) -> i64 { *self as i64 } - #[inline(always)] pure fn to_int(&self) -> int { *self as int } + #[inline(always)] fn to_i8(&self) -> i8 { *self as i8 } + #[inline(always)] fn to_i16(&self) -> i16 { *self as i16 } + #[inline(always)] fn to_i32(&self) -> i32 { *self as i32 } + #[inline(always)] fn to_i64(&self) -> i64 { *self as i64 } + #[inline(always)] fn to_int(&self) -> int { *self as int } - #[inline(always)] pure fn to_f32(&self) -> f32 { *self as f32 } - #[inline(always)] pure fn to_f64(&self) -> f64 { *self } - #[inline(always)] pure fn to_float(&self) -> float { *self as float } + #[inline(always)] fn to_f32(&self) -> f32 { *self as f32 } + #[inline(always)] fn to_f64(&self) -> f64 { *self } + #[inline(always)] fn to_float(&self) -> float { *self as float } } impl num::Zero for f64 { #[inline(always)] - static pure fn zero() -> f64 { 0.0 } + fn zero() -> f64 { 0.0 } } impl num::One for f64 { #[inline(always)] - static pure fn one() -> f64 { 1.0 } + fn one() -> f64 { 1.0 } } #[cfg(notest)] impl ops::Add for f64 { - pure fn add(&self, other: &f64) -> f64 { *self + *other } + fn add(&self, other: &f64) -> f64 { *self + *other } } #[cfg(notest)] impl ops::Sub for f64 { - pure fn sub(&self, other: &f64) -> f64 { *self - *other } + fn sub(&self, other: &f64) -> f64 { *self - *other } } #[cfg(notest)] impl ops::Mul for f64 { - pure fn mul(&self, other: &f64) -> f64 { *self * *other } + fn mul(&self, other: &f64) -> f64 { *self * *other } } #[cfg(notest)] impl ops::Div for f64 { - pure fn div(&self, other: &f64) -> f64 { *self / *other } + fn div(&self, other: &f64) -> f64 { *self / *other } } #[cfg(notest)] impl ops::Modulo for f64 { - pure fn modulo(&self, other: &f64) -> f64 { *self % *other } + fn modulo(&self, other: &f64) -> f64 { *self % *other } } #[cfg(notest)] impl ops::Neg for f64 { - pure fn neg(&self) -> f64 { -*self } + fn neg(&self) -> f64 { -*self } } impl num::Round for f64 { #[inline(always)] - pure fn round(&self, mode: num::RoundMode) -> f64 { + fn round(&self, mode: num::RoundMode) -> f64 { match mode { num::RoundDown => floor(*self), num::RoundUp => ceil(*self), @@ -372,11 +372,11 @@ impl num::Round for f64 { } #[inline(always)] - pure fn floor(&self) -> f64 { floor(*self) } + fn floor(&self) -> f64 { floor(*self) } #[inline(always)] - pure fn ceil(&self) -> f64 { ceil(*self) } + fn ceil(&self) -> f64 { ceil(*self) } #[inline(always)] - pure fn fract(&self) -> f64 { + fn fract(&self) -> f64 { if is_negative(*self) { (*self) - ceil(*self) } else { @@ -397,7 +397,7 @@ impl num::Round for f64 { * * num - The float value */ #[inline(always)] -pub pure fn to_str(num: f64) -> ~str { +pub fn to_str(num: f64) -> ~str { let (r, _) = strconv::to_str_common( &num, 10u, true, strconv::SignNeg, strconv::DigAll); r @@ -411,7 +411,7 @@ pub pure fn to_str(num: f64) -> ~str { * * num - The float value */ #[inline(always)] -pub pure fn to_str_hex(num: f64) -> ~str { +pub fn to_str_hex(num: f64) -> ~str { let (r, _) = strconv::to_str_common( &num, 16u, true, strconv::SignNeg, strconv::DigAll); r @@ -432,7 +432,7 @@ pub pure fn to_str_hex(num: f64) -> ~str { * are expected, use `to_str_radix_special()` instead. */ #[inline(always)] -pub pure fn to_str_radix(num: f64, rdx: uint) -> ~str { +pub fn to_str_radix(num: f64, rdx: uint) -> ~str { let (r, special) = strconv::to_str_common( &num, rdx, true, strconv::SignNeg, strconv::DigAll); if special { fail!(~"number has a special value, \ @@ -450,7 +450,7 @@ pub pure fn to_str_radix(num: f64, rdx: uint) -> ~str { * * radix - The base to use */ #[inline(always)] -pub pure fn to_str_radix_special(num: f64, rdx: uint) -> (~str, bool) { +pub fn to_str_radix_special(num: f64, rdx: uint) -> (~str, bool) { strconv::to_str_common(&num, rdx, true, strconv::SignNeg, strconv::DigAll) } @@ -465,7 +465,7 @@ pub pure fn to_str_radix_special(num: f64, rdx: uint) -> (~str, bool) { * * digits - The number of significant digits */ #[inline(always)] -pub pure fn to_str_exact(num: f64, dig: uint) -> ~str { +pub fn to_str_exact(num: f64, dig: uint) -> ~str { let (r, _) = strconv::to_str_common( &num, 10u, true, strconv::SignNeg, strconv::DigExact(dig)); r @@ -481,7 +481,7 @@ pub pure fn to_str_exact(num: f64, dig: uint) -> ~str { * * digits - The number of significant digits */ #[inline(always)] -pub pure fn to_str_digits(num: f64, dig: uint) -> ~str { +pub fn to_str_digits(num: f64, dig: uint) -> ~str { let (r, _) = strconv::to_str_common( &num, 10u, true, strconv::SignNeg, strconv::DigMax(dig)); r @@ -489,12 +489,12 @@ pub pure fn to_str_digits(num: f64, dig: uint) -> ~str { impl to_str::ToStr for f64 { #[inline(always)] - pure fn to_str(&self) -> ~str { to_str_digits(*self, 8) } + fn to_str(&self) -> ~str { to_str_digits(*self, 8) } } impl num::ToStrRadix for f64 { #[inline(always)] - pure fn to_str_radix(&self, rdx: uint) -> ~str { + fn to_str_radix(&self, rdx: uint) -> ~str { to_str_radix(*self, rdx) } } @@ -527,7 +527,7 @@ impl num::ToStrRadix for f64 { * `Some(n)` where `n` is the floating-point number represented by `num`. */ #[inline(always)] -pub pure fn from_str(num: &str) -> Option { +pub fn from_str(num: &str) -> Option { strconv::from_str_common(num, 10u, true, true, true, strconv::ExpDec, false) } @@ -560,7 +560,7 @@ pub pure fn from_str(num: &str) -> Option { * `Some(n)` where `n` is the floating-point number represented by `[num]`. */ #[inline(always)] -pub pure fn from_str_hex(num: &str) -> Option { +pub fn from_str_hex(num: &str) -> Option { strconv::from_str_common(num, 16u, true, true, true, strconv::ExpBin, false) } @@ -585,19 +585,19 @@ pub pure fn from_str_hex(num: &str) -> Option { * `Some(n)` where `n` is the floating-point number represented by `num`. */ #[inline(always)] -pub pure fn from_str_radix(num: &str, rdx: uint) -> Option { +pub fn from_str_radix(num: &str, rdx: uint) -> Option { strconv::from_str_common(num, rdx, true, true, false, strconv::ExpNone, false) } impl from_str::FromStr for f64 { #[inline(always)] - static pure fn from_str(val: &str) -> Option { from_str(val) } + fn from_str(val: &str) -> Option { from_str(val) } } impl num::FromStrRadix for f64 { #[inline(always)] - static pure fn from_str_radix(val: &str, rdx: uint) -> Option { + fn from_str_radix(val: &str, rdx: uint) -> Option { from_str_radix(val, rdx) } } diff --git a/src/libcore/num/float.rs b/src/libcore/num/float.rs index 1cceddf51a1d3..65a846c6db149 100644 --- a/src/libcore/num/float.rs +++ b/src/libcore/num/float.rs @@ -41,54 +41,54 @@ pub use f64::{modf, pow, round, sinh, tanh, tgamma, trunc}; pub use f64::signbit; pub use f64::{j0, j1, jn, y0, y1, yn}; -pub const NaN: float = 0.0/0.0; +pub static NaN: float = 0.0/0.0; -pub const infinity: float = 1.0/0.0; +pub static infinity: float = 1.0/0.0; -pub const neg_infinity: float = -1.0/0.0; +pub static neg_infinity: float = -1.0/0.0; /* Module: consts */ pub mod consts { // FIXME (requires Issue #1433 to fix): replace with mathematical - // constants from cmath. - /// Archimedes' constant - pub const pi: float = 3.14159265358979323846264338327950288; + // staticants from cmath. + /// Archimedes' staticant + pub static pi: float = 3.14159265358979323846264338327950288; /// pi/2.0 - pub const frac_pi_2: float = 1.57079632679489661923132169163975144; + pub static frac_pi_2: float = 1.57079632679489661923132169163975144; /// pi/4.0 - pub const frac_pi_4: float = 0.785398163397448309615660845819875721; + pub static frac_pi_4: float = 0.785398163397448309615660845819875721; /// 1.0/pi - pub const frac_1_pi: float = 0.318309886183790671537767526745028724; + pub static frac_1_pi: float = 0.318309886183790671537767526745028724; /// 2.0/pi - pub const frac_2_pi: float = 0.636619772367581343075535053490057448; + pub static frac_2_pi: float = 0.636619772367581343075535053490057448; /// 2.0/sqrt(pi) - pub const frac_2_sqrtpi: float = 1.12837916709551257389615890312154517; + pub static frac_2_sqrtpi: float = 1.12837916709551257389615890312154517; /// sqrt(2.0) - pub const sqrt2: float = 1.41421356237309504880168872420969808; + pub static sqrt2: float = 1.41421356237309504880168872420969808; /// 1.0/sqrt(2.0) - pub const frac_1_sqrt2: float = 0.707106781186547524400844362104849039; + pub static frac_1_sqrt2: float = 0.707106781186547524400844362104849039; /// Euler's number - pub const e: float = 2.71828182845904523536028747135266250; + pub static e: float = 2.71828182845904523536028747135266250; /// log2(e) - pub const log2_e: float = 1.44269504088896340735992468100189214; + pub static log2_e: float = 1.44269504088896340735992468100189214; /// log10(e) - pub const log10_e: float = 0.434294481903251827651128918916605082; + pub static log10_e: float = 0.434294481903251827651128918916605082; /// ln(2.0) - pub const ln_2: float = 0.693147180559945309417232121458176568; + pub static ln_2: float = 0.693147180559945309417232121458176568; /// ln(10.0) - pub const ln_10: float = 2.30258509299404568401799145468436421; + pub static ln_10: float = 2.30258509299404568401799145468436421; } /* @@ -103,7 +103,7 @@ pub mod consts { * * num - The float value */ #[inline(always)] -pub pure fn to_str(num: float) -> ~str { +pub fn to_str(num: float) -> ~str { let (r, _) = strconv::to_str_common( &num, 10u, true, strconv::SignNeg, strconv::DigAll); r @@ -117,7 +117,7 @@ pub pure fn to_str(num: float) -> ~str { * * num - The float value */ #[inline(always)] -pub pure fn to_str_hex(num: float) -> ~str { +pub fn to_str_hex(num: float) -> ~str { let (r, _) = strconv::to_str_common( &num, 16u, true, strconv::SignNeg, strconv::DigAll); r @@ -138,7 +138,7 @@ pub pure fn to_str_hex(num: float) -> ~str { * are expected, use `to_str_radix_special()` instead. */ #[inline(always)] -pub pure fn to_str_radix(num: float, radix: uint) -> ~str { +pub fn to_str_radix(num: float, radix: uint) -> ~str { let (r, special) = strconv::to_str_common( &num, radix, true, strconv::SignNeg, strconv::DigAll); if special { fail!(~"number has a special value, \ @@ -156,7 +156,7 @@ pub pure fn to_str_radix(num: float, radix: uint) -> ~str { * * radix - The base to use */ #[inline(always)] -pub pure fn to_str_radix_special(num: float, radix: uint) -> (~str, bool) { +pub fn to_str_radix_special(num: float, radix: uint) -> (~str, bool) { strconv::to_str_common(&num, radix, true, strconv::SignNeg, strconv::DigAll) } @@ -171,7 +171,7 @@ pub pure fn to_str_radix_special(num: float, radix: uint) -> (~str, bool) { * * digits - The number of significant digits */ #[inline(always)] -pub pure fn to_str_exact(num: float, digits: uint) -> ~str { +pub fn to_str_exact(num: float, digits: uint) -> ~str { let (r, _) = strconv::to_str_common( &num, 10u, true, strconv::SignNeg, strconv::DigExact(digits)); r @@ -193,7 +193,7 @@ pub fn test_to_str_exact_do_decimal() { * * digits - The number of significant digits */ #[inline(always)] -pub pure fn to_str_digits(num: float, digits: uint) -> ~str { +pub fn to_str_digits(num: float, digits: uint) -> ~str { let (r, _) = strconv::to_str_common( &num, 10u, true, strconv::SignNeg, strconv::DigMax(digits)); r @@ -201,12 +201,12 @@ pub pure fn to_str_digits(num: float, digits: uint) -> ~str { impl to_str::ToStr for float { #[inline(always)] - pure fn to_str(&self) -> ~str { to_str_digits(*self, 8) } + fn to_str(&self) -> ~str { to_str_digits(*self, 8) } } impl num::ToStrRadix for float { #[inline(always)] - pure fn to_str_radix(&self, radix: uint) -> ~str { + fn to_str_radix(&self, radix: uint) -> ~str { to_str_radix(*self, radix) } } @@ -239,7 +239,7 @@ impl num::ToStrRadix for float { * `Some(n)` where `n` is the floating-point number represented by `num`. */ #[inline(always)] -pub pure fn from_str(num: &str) -> Option { +pub fn from_str(num: &str) -> Option { strconv::from_str_common(num, 10u, true, true, true, strconv::ExpDec, false) } @@ -272,7 +272,7 @@ pub pure fn from_str(num: &str) -> Option { * `Some(n)` where `n` is the floating-point number represented by `[num]`. */ #[inline(always)] -pub pure fn from_str_hex(num: &str) -> Option { +pub fn from_str_hex(num: &str) -> Option { strconv::from_str_common(num, 16u, true, true, true, strconv::ExpBin, false) } @@ -297,19 +297,19 @@ pub pure fn from_str_hex(num: &str) -> Option { * `Some(n)` where `n` is the floating-point number represented by `num`. */ #[inline(always)] -pub pure fn from_str_radix(num: &str, radix: uint) -> Option { +pub fn from_str_radix(num: &str, radix: uint) -> Option { strconv::from_str_common(num, radix, true, true, false, strconv::ExpNone, false) } impl from_str::FromStr for float { #[inline(always)] - static pure fn from_str(val: &str) -> Option { from_str(val) } + fn from_str(val: &str) -> Option { from_str(val) } } impl num::FromStrRadix for float { #[inline(always)] - static pure fn from_str_radix(val: &str, radix: uint) -> Option { + fn from_str_radix(val: &str, radix: uint) -> Option { from_str_radix(val, radix) } } @@ -330,7 +330,7 @@ impl num::FromStrRadix for float { * * `NaN` if both `x` and `pow` are `0u`, otherwise `x^pow` */ -pub pure 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; @@ -351,69 +351,69 @@ pub pure fn pow_with_uint(base: uint, pow: uint) -> float { } #[inline(always)] -pub pure fn is_positive(x: float) -> bool { f64::is_positive(x as f64) } +pub fn is_positive(x: float) -> bool { f64::is_positive(x as f64) } #[inline(always)] -pub pure fn is_negative(x: float) -> bool { f64::is_negative(x as f64) } +pub fn is_negative(x: float) -> bool { f64::is_negative(x as f64) } #[inline(always)] -pub pure fn is_nonpositive(x: float) -> bool { f64::is_nonpositive(x as f64) } +pub fn is_nonpositive(x: float) -> bool { f64::is_nonpositive(x as f64) } #[inline(always)] -pub pure fn is_nonnegative(x: float) -> bool { f64::is_nonnegative(x as f64) } +pub fn is_nonnegative(x: float) -> bool { f64::is_nonnegative(x as f64) } #[inline(always)] -pub pure fn is_zero(x: float) -> bool { f64::is_zero(x as f64) } +pub fn is_zero(x: float) -> bool { f64::is_zero(x as f64) } #[inline(always)] -pub pure fn is_infinite(x: float) -> bool { f64::is_infinite(x as f64) } +pub fn is_infinite(x: float) -> bool { f64::is_infinite(x as f64) } #[inline(always)] -pub pure fn is_finite(x: float) -> bool { f64::is_finite(x as f64) } +pub fn is_finite(x: float) -> bool { f64::is_finite(x as f64) } #[inline(always)] -pub pure fn is_NaN(x: float) -> bool { f64::is_NaN(x as f64) } +pub fn is_NaN(x: float) -> bool { f64::is_NaN(x as f64) } #[inline(always)] -pub pure fn abs(x: float) -> float { +pub fn abs(x: float) -> float { unsafe { f64::abs(x as f64) as float } } #[inline(always)] -pub pure fn sqrt(x: float) -> float { +pub fn sqrt(x: float) -> float { unsafe { f64::sqrt(x as f64) as float } } #[inline(always)] -pub pure fn atan(x: float) -> float { +pub fn atan(x: float) -> float { unsafe { f64::atan(x as f64) as float } } #[inline(always)] -pub pure fn sin(x: float) -> float { +pub fn sin(x: float) -> float { unsafe { f64::sin(x as f64) as float } } #[inline(always)] -pub pure fn cos(x: float) -> float { +pub fn cos(x: float) -> float { unsafe { f64::cos(x as f64) as float } } #[inline(always)] -pub pure fn tan(x: float) -> float { +pub fn tan(x: float) -> float { unsafe { f64::tan(x as f64) as float } } #[cfg(notest)] impl Eq for float { - pure fn eq(&self, other: &float) -> bool { (*self) == (*other) } - pure fn ne(&self, other: &float) -> bool { (*self) != (*other) } + fn eq(&self, other: &float) -> bool { (*self) == (*other) } + fn ne(&self, other: &float) -> bool { (*self) != (*other) } } #[cfg(notest)] impl Ord for float { - pure fn lt(&self, other: &float) -> bool { (*self) < (*other) } - pure fn le(&self, other: &float) -> bool { (*self) <= (*other) } - pure fn ge(&self, other: &float) -> bool { (*self) >= (*other) } - pure fn gt(&self, other: &float) -> bool { (*self) > (*other) } + fn lt(&self, other: &float) -> bool { (*self) < (*other) } + fn le(&self, other: &float) -> bool { (*self) <= (*other) } + fn ge(&self, other: &float) -> bool { (*self) >= (*other) } + fn gt(&self, other: &float) -> bool { (*self) > (*other) } } impl num::Zero for float { #[inline(always)] - static pure fn zero() -> float { 0.0 } + fn zero() -> float { 0.0 } } impl num::One for float { #[inline(always)] - static pure fn one() -> float { 1.0 } + fn one() -> float { 1.0 } } impl NumCast for float { @@ -421,28 +421,28 @@ impl NumCast for float { * Cast `n` to a `float` */ #[inline(always)] - static pure fn from(n: N) -> float { n.to_float() } + fn from(n: N) -> float { n.to_float() } - #[inline(always)] pure fn to_u8(&self) -> u8 { *self as u8 } - #[inline(always)] pure fn to_u16(&self) -> u16 { *self as u16 } - #[inline(always)] pure fn to_u32(&self) -> u32 { *self as u32 } - #[inline(always)] pure fn to_u64(&self) -> u64 { *self as u64 } - #[inline(always)] pure fn to_uint(&self) -> uint { *self as uint } + #[inline(always)] fn to_u8(&self) -> u8 { *self as u8 } + #[inline(always)] fn to_u16(&self) -> u16 { *self as u16 } + #[inline(always)] fn to_u32(&self) -> u32 { *self as u32 } + #[inline(always)] fn to_u64(&self) -> u64 { *self as u64 } + #[inline(always)] fn to_uint(&self) -> uint { *self as uint } - #[inline(always)] pure fn to_i8(&self) -> i8 { *self as i8 } - #[inline(always)] pure fn to_i16(&self) -> i16 { *self as i16 } - #[inline(always)] pure fn to_i32(&self) -> i32 { *self as i32 } - #[inline(always)] pure fn to_i64(&self) -> i64 { *self as i64 } - #[inline(always)] pure fn to_int(&self) -> int { *self as int } + #[inline(always)] fn to_i8(&self) -> i8 { *self as i8 } + #[inline(always)] fn to_i16(&self) -> i16 { *self as i16 } + #[inline(always)] fn to_i32(&self) -> i32 { *self as i32 } + #[inline(always)] fn to_i64(&self) -> i64 { *self as i64 } + #[inline(always)] fn to_int(&self) -> int { *self as int } - #[inline(always)] pure fn to_f32(&self) -> f32 { *self as f32 } - #[inline(always)] pure fn to_f64(&self) -> f64 { *self as f64 } - #[inline(always)] pure fn to_float(&self) -> float { *self } + #[inline(always)] fn to_f32(&self) -> f32 { *self as f32 } + #[inline(always)] fn to_f64(&self) -> f64 { *self as f64 } + #[inline(always)] fn to_float(&self) -> float { *self } } impl num::Round for float { #[inline(always)] - pure fn round(&self, mode: num::RoundMode) -> float { + fn round(&self, mode: num::RoundMode) -> float { match mode { num::RoundDown => f64::floor(*self as f64) as float, @@ -460,11 +460,11 @@ impl num::Round for float { } #[inline(always)] - pure fn floor(&self) -> float { f64::floor(*self as f64) as float} + fn floor(&self) -> float { f64::floor(*self as f64) as float} #[inline(always)] - pure fn ceil(&self) -> float { f64::ceil(*self as f64) as float} + fn ceil(&self) -> float { f64::ceil(*self as f64) as float} #[inline(always)] - pure fn fract(&self) -> float { + fn fract(&self) -> float { if is_negative(*self) { (*self) - (f64::ceil(*self as f64) as float) } else { @@ -475,27 +475,27 @@ impl num::Round for float { #[cfg(notest)] impl ops::Add for float { - pure fn add(&self, other: &float) -> float { *self + *other } + fn add(&self, other: &float) -> float { *self + *other } } #[cfg(notest)] impl ops::Sub for float { - pure fn sub(&self, other: &float) -> float { *self - *other } + fn sub(&self, other: &float) -> float { *self - *other } } #[cfg(notest)] impl ops::Mul for float { - pure fn mul(&self, other: &float) -> float { *self * *other } + fn mul(&self, other: &float) -> float { *self * *other } } #[cfg(notest)] impl ops::Div for float { - pure fn div(&self, other: &float) -> float { *self / *other } + fn div(&self, other: &float) -> float { *self / *other } } #[cfg(notest)] impl ops::Modulo for float { - pure fn modulo(&self, other: &float) -> float { *self % *other } + fn modulo(&self, other: &float) -> float { *self % *other } } #[cfg(notest)] impl ops::Neg for float { - pure fn neg(&self) -> float { -*self } + fn neg(&self) -> float { -*self } } #[test] diff --git a/src/libcore/num/int-template.rs b/src/libcore/num/int-template.rs index cef8542823a67..af56d3e63051a 100644 --- a/src/libcore/num/int-template.rs +++ b/src/libcore/num/int-template.rs @@ -21,20 +21,20 @@ use prelude::*; pub use cmp::{min, max}; -pub const bits : uint = inst::bits; -pub const bytes : uint = (inst::bits / 8); +pub static bits : uint = inst::bits; +pub static 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; +pub static min_value: T = (-1 as T) << (bits - 1); +pub static max_value: T = min_value - 1 as T; #[inline(always)] -pub pure fn add(x: T, y: T) -> T { x + y } +pub fn add(x: T, y: T) -> T { x + y } #[inline(always)] -pub pure fn sub(x: T, y: T) -> T { x - y } +pub fn sub(x: T, y: T) -> T { x - y } #[inline(always)] -pub pure fn mul(x: T, y: T) -> T { x * y } +pub fn mul(x: T, y: T) -> T { x * y } #[inline(always)] -pub pure fn div(x: T, y: T) -> T { x / y } +pub fn div(x: T, y: T) -> T { x / y } /** * Returns the remainder of y / x. @@ -57,29 +57,29 @@ pub pure fn div(x: T, y: T) -> T { x / y } * */ #[inline(always)] -pub pure fn rem(x: T, y: T) -> T { x % y } +pub fn rem(x: T, y: T) -> T { x % y } #[inline(always)] -pub pure fn lt(x: T, y: T) -> bool { x < y } +pub fn lt(x: T, y: T) -> bool { x < y } #[inline(always)] -pub pure fn le(x: T, y: T) -> bool { x <= y } +pub fn le(x: T, y: T) -> bool { x <= y } #[inline(always)] -pub pure fn eq(x: T, y: T) -> bool { x == y } +pub fn eq(x: T, y: T) -> bool { x == y } #[inline(always)] -pub pure fn ne(x: T, y: T) -> bool { x != y } +pub fn ne(x: T, y: T) -> bool { x != y } #[inline(always)] -pub pure fn ge(x: T, y: T) -> bool { x >= y } +pub fn ge(x: T, y: T) -> bool { x >= y } #[inline(always)] -pub pure fn gt(x: T, y: T) -> bool { x > y } +pub fn gt(x: T, y: T) -> bool { x > y } #[inline(always)] -pub pure fn is_positive(x: T) -> bool { x > 0 as T } +pub fn is_positive(x: T) -> bool { x > 0 as T } #[inline(always)] -pub pure fn is_negative(x: T) -> bool { x < 0 as T } +pub fn is_negative(x: T) -> bool { x < 0 as T } #[inline(always)] -pub pure fn is_nonpositive(x: T) -> bool { x <= 0 as T } +pub fn is_nonpositive(x: T) -> bool { x <= 0 as T } #[inline(always)] -pub pure fn is_nonnegative(x: T) -> bool { x >= 0 as T } +pub fn is_nonnegative(x: T) -> bool { x >= 0 as T } /** * Iterate over the range [`lo`..`hi`) @@ -100,7 +100,7 @@ pub pure fn is_nonnegative(x: T) -> bool { x >= 0 as T } */ #[inline(always)] /// Iterate over the range [`start`,`start`+`step`..`stop`) -pub pure fn range_step(start: T, stop: T, step: T, it: &fn(T) -> bool) { +pub fn range_step(start: T, stop: T, step: T, it: &fn(T) -> bool) { let mut i = start; if step == 0 { fail!(~"range_step called with step == 0"); @@ -119,116 +119,116 @@ pub pure fn range_step(start: T, stop: T, step: T, it: &fn(T) -> bool) { #[inline(always)] /// Iterate over the range [`lo`..`hi`) -pub pure fn range(lo: T, hi: T, it: &fn(T) -> bool) { +pub fn range(lo: T, hi: T, it: &fn(T) -> bool) { range_step(lo, hi, 1 as T, it); } #[inline(always)] /// Iterate over the range [`hi`..`lo`) -pub pure fn range_rev(hi: T, lo: T, it: &fn(T) -> bool) { +pub fn range_rev(hi: T, lo: T, it: &fn(T) -> bool) { range_step(hi, lo, -1 as T, it); } /// Computes the bitwise complement #[inline(always)] -pub pure fn compl(i: T) -> T { +pub fn compl(i: T) -> T { -1 as T ^ i } /// Computes the absolute value #[inline(always)] -pub pure fn abs(i: T) -> T { +pub fn abs(i: T) -> T { if is_negative(i) { -i } else { i } } #[cfg(notest)] impl Ord for T { #[inline(always)] - pure fn lt(&self, other: &T) -> bool { return (*self) < (*other); } + fn lt(&self, other: &T) -> bool { return (*self) < (*other); } #[inline(always)] - pure fn le(&self, other: &T) -> bool { return (*self) <= (*other); } + fn le(&self, other: &T) -> bool { return (*self) <= (*other); } #[inline(always)] - pure fn ge(&self, other: &T) -> bool { return (*self) >= (*other); } + fn ge(&self, other: &T) -> bool { return (*self) >= (*other); } #[inline(always)] - pure fn gt(&self, other: &T) -> bool { return (*self) > (*other); } + fn gt(&self, other: &T) -> bool { return (*self) > (*other); } } #[cfg(notest)] impl Eq for T { #[inline(always)] - pure fn eq(&self, other: &T) -> bool { return (*self) == (*other); } + fn eq(&self, other: &T) -> bool { return (*self) == (*other); } #[inline(always)] - pure fn ne(&self, other: &T) -> bool { return (*self) != (*other); } + fn ne(&self, other: &T) -> bool { return (*self) != (*other); } } impl num::Zero for T { #[inline(always)] - static pure fn zero() -> T { 0 } + fn zero() -> T { 0 } } impl num::One for T { #[inline(always)] - static pure fn one() -> T { 1 } + fn one() -> T { 1 } } #[cfg(notest)] impl ops::Add for T { - pure fn add(&self, other: &T) -> T { *self + *other } + fn add(&self, other: &T) -> T { *self + *other } } #[cfg(notest)] impl ops::Sub for T { - pure fn sub(&self, other: &T) -> T { *self - *other } + fn sub(&self, other: &T) -> T { *self - *other } } #[cfg(notest)] impl ops::Mul for T { - pure fn mul(&self, other: &T) -> T { *self * *other } + fn mul(&self, other: &T) -> T { *self * *other } } #[cfg(notest)] impl ops::Div for T { - pure fn div(&self, other: &T) -> T { *self / *other } + fn div(&self, other: &T) -> T { *self / *other } } #[cfg(notest)] impl ops::Modulo for T { - pure fn modulo(&self, other: &T) -> T { *self % *other } + fn modulo(&self, other: &T) -> T { *self % *other } } #[cfg(notest)] impl ops::Neg for T { - pure fn neg(&self) -> T { -*self } + fn neg(&self) -> T { -*self } } // String conversion functions and impl str -> num /// Parse a string as a number in base 10. #[inline(always)] -pub pure fn from_str(s: &str) -> Option { +pub fn from_str(s: &str) -> Option { strconv::from_str_common(s, 10u, true, false, false, strconv::ExpNone, false) } /// Parse a string as a number in the given base. #[inline(always)] -pub pure fn from_str_radix(s: &str, radix: uint) -> Option { +pub fn from_str_radix(s: &str, radix: uint) -> Option { strconv::from_str_common(s, radix, true, false, false, strconv::ExpNone, false) } /// Parse a byte slice as a number in the given base. #[inline(always)] -pub pure fn parse_bytes(buf: &[u8], radix: uint) -> Option { +pub fn parse_bytes(buf: &[u8], radix: uint) -> Option { strconv::from_str_bytes_common(buf, radix, true, false, false, strconv::ExpNone, false) } impl FromStr for T { #[inline(always)] - static pure fn from_str(s: &str) -> Option { + fn from_str(s: &str) -> Option { from_str(s) } } impl FromStrRadix for T { #[inline(always)] - static pure fn from_str_radix(&self, s: &str, radix: uint) -> Option { + fn from_str_radix(s: &str, radix: uint) -> Option { from_str_radix(s, radix) } } @@ -237,7 +237,7 @@ impl FromStrRadix for T { /// Convert to a string as a byte slice in a given base. #[inline(always)] -pub pure 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 { let (buf, _) = strconv::to_str_bytes_common(&n, radix, false, strconv::SignNeg, strconv::DigAll); f(buf) @@ -245,7 +245,7 @@ pub pure fn to_str_bytes(n: T, radix: uint, f: &fn(v: &[u8]) -> U) -> U { /// Convert to a string in base 10. #[inline(always)] -pub pure fn to_str(num: T) -> ~str { +pub fn to_str(num: T) -> ~str { let (buf, _) = strconv::to_str_common(&num, 10u, false, strconv::SignNeg, strconv::DigAll); buf @@ -253,7 +253,7 @@ pub pure fn to_str(num: T) -> ~str { /// Convert to a string in a given base. #[inline(always)] -pub pure fn to_str_radix(num: T, radix: uint) -> ~str { +pub fn to_str_radix(num: T, radix: uint) -> ~str { let (buf, _) = strconv::to_str_common(&num, radix, false, strconv::SignNeg, strconv::DigAll); buf @@ -261,14 +261,14 @@ pub pure fn to_str_radix(num: T, radix: uint) -> ~str { impl ToStr for T { #[inline(always)] - pure fn to_str(&self) -> ~str { + fn to_str(&self) -> ~str { to_str(*self) } } impl ToStrRadix for T { #[inline(always)] - pure fn to_str_radix(&self, radix: uint) -> ~str { + fn to_str_radix(&self, radix: uint) -> ~str { to_str_radix(*self, radix) } } diff --git a/src/libcore/num/int-template/i16.rs b/src/libcore/num/int-template/i16.rs index 3c4ca532be764..965b6f86a53d6 100644 --- a/src/libcore/num/int-template/i16.rs +++ b/src/libcore/num/int-template/i16.rs @@ -14,7 +14,7 @@ use num::NumCast; mod inst { pub type T = i16; - pub const bits: uint = ::u16::bits; + pub static bits: uint = ::u16::bits; } impl NumCast for i16 { @@ -22,23 +22,23 @@ impl NumCast for i16 { * Cast `n` to a `i16` */ #[inline(always)] - static pure fn from(n: N) -> i16 { n.to_i16() } + fn from(n: N) -> i16 { n.to_i16() } - #[inline(always)] pure fn to_u8(&self) -> u8 { *self as u8 } - #[inline(always)] pure fn to_u16(&self) -> u16 { *self as u16 } - #[inline(always)] pure fn to_u32(&self) -> u32 { *self as u32 } - #[inline(always)] pure fn to_u64(&self) -> u64 { *self as u64 } - #[inline(always)] pure fn to_uint(&self) -> uint { *self as uint } + #[inline(always)] fn to_u8(&self) -> u8 { *self as u8 } + #[inline(always)] fn to_u16(&self) -> u16 { *self as u16 } + #[inline(always)] fn to_u32(&self) -> u32 { *self as u32 } + #[inline(always)] fn to_u64(&self) -> u64 { *self as u64 } + #[inline(always)] fn to_uint(&self) -> uint { *self as uint } - #[inline(always)] pure fn to_i8(&self) -> i8 { *self as i8 } - #[inline(always)] pure fn to_i16(&self) -> i16 { *self } - #[inline(always)] pure fn to_i32(&self) -> i32 { *self as i32 } - #[inline(always)] pure fn to_i64(&self) -> i64 { *self as i64 } - #[inline(always)] pure fn to_int(&self) -> int { *self as int } + #[inline(always)] fn to_i8(&self) -> i8 { *self as i8 } + #[inline(always)] fn to_i16(&self) -> i16 { *self } + #[inline(always)] fn to_i32(&self) -> i32 { *self as i32 } + #[inline(always)] fn to_i64(&self) -> i64 { *self as i64 } + #[inline(always)] fn to_int(&self) -> int { *self as int } - #[inline(always)] pure fn to_f32(&self) -> f32 { *self as f32 } - #[inline(always)] pure fn to_f64(&self) -> f64 { *self as f64 } - #[inline(always)] pure fn to_float(&self) -> float { *self as float } + #[inline(always)] fn to_f32(&self) -> f32 { *self as f32 } + #[inline(always)] fn to_f64(&self) -> f64 { *self as f64 } + #[inline(always)] fn to_float(&self) -> float { *self as float } } #[test] diff --git a/src/libcore/num/int-template/i32.rs b/src/libcore/num/int-template/i32.rs index 30eb4437d5701..030bc9c3fdefe 100644 --- a/src/libcore/num/int-template/i32.rs +++ b/src/libcore/num/int-template/i32.rs @@ -14,7 +14,7 @@ use num::NumCast; mod inst { pub type T = i32; - pub const bits: uint = ::u32::bits; + pub static bits: uint = ::u32::bits; } impl NumCast for i32 { @@ -22,23 +22,23 @@ impl NumCast for i32 { * Cast `n` to a `i32` */ #[inline(always)] - static pure fn from(n: N) -> i32 { n.to_i32() } + fn from(n: N) -> i32 { n.to_i32() } - #[inline(always)] pure fn to_u8(&self) -> u8 { *self as u8 } - #[inline(always)] pure fn to_u16(&self) -> u16 { *self as u16 } - #[inline(always)] pure fn to_u32(&self) -> u32 { *self as u32 } - #[inline(always)] pure fn to_u64(&self) -> u64 { *self as u64 } - #[inline(always)] pure fn to_uint(&self) -> uint { *self as uint } + #[inline(always)] fn to_u8(&self) -> u8 { *self as u8 } + #[inline(always)] fn to_u16(&self) -> u16 { *self as u16 } + #[inline(always)] fn to_u32(&self) -> u32 { *self as u32 } + #[inline(always)] fn to_u64(&self) -> u64 { *self as u64 } + #[inline(always)] fn to_uint(&self) -> uint { *self as uint } - #[inline(always)] pure fn to_i8(&self) -> i8 { *self as i8 } - #[inline(always)] pure fn to_i16(&self) -> i16 { *self as i16 } - #[inline(always)] pure fn to_i32(&self) -> i32 { *self } - #[inline(always)] pure fn to_i64(&self) -> i64 { *self as i64 } - #[inline(always)] pure fn to_int(&self) -> int { *self as int } + #[inline(always)] fn to_i8(&self) -> i8 { *self as i8 } + #[inline(always)] fn to_i16(&self) -> i16 { *self as i16 } + #[inline(always)] fn to_i32(&self) -> i32 { *self } + #[inline(always)] fn to_i64(&self) -> i64 { *self as i64 } + #[inline(always)] fn to_int(&self) -> int { *self as int } - #[inline(always)] pure fn to_f32(&self) -> f32 { *self as f32 } - #[inline(always)] pure fn to_f64(&self) -> f64 { *self as f64 } - #[inline(always)] pure fn to_float(&self) -> float { *self as float } + #[inline(always)] fn to_f32(&self) -> f32 { *self as f32 } + #[inline(always)] fn to_f64(&self) -> f64 { *self as f64 } + #[inline(always)] fn to_float(&self) -> float { *self as float } } #[test] diff --git a/src/libcore/num/int-template/i64.rs b/src/libcore/num/int-template/i64.rs index 61736cf958743..283de94e9d80e 100644 --- a/src/libcore/num/int-template/i64.rs +++ b/src/libcore/num/int-template/i64.rs @@ -14,7 +14,7 @@ use num::NumCast; mod inst { pub type T = i64; - pub const bits: uint = ::u64::bits; + pub static bits: uint = ::u64::bits; } impl NumCast for i64 { @@ -22,23 +22,23 @@ impl NumCast for i64 { * Cast `n` to a `i64` */ #[inline(always)] - static pure fn from(n: N) -> i64 { n.to_i64() } + fn from(n: N) -> i64 { n.to_i64() } - #[inline(always)] pure fn to_u8(&self) -> u8 { *self as u8 } - #[inline(always)] pure fn to_u16(&self) -> u16 { *self as u16 } - #[inline(always)] pure fn to_u32(&self) -> u32 { *self as u32 } - #[inline(always)] pure fn to_u64(&self) -> u64 { *self as u64 } - #[inline(always)] pure fn to_uint(&self) -> uint { *self as uint } + #[inline(always)] fn to_u8(&self) -> u8 { *self as u8 } + #[inline(always)] fn to_u16(&self) -> u16 { *self as u16 } + #[inline(always)] fn to_u32(&self) -> u32 { *self as u32 } + #[inline(always)] fn to_u64(&self) -> u64 { *self as u64 } + #[inline(always)] fn to_uint(&self) -> uint { *self as uint } - #[inline(always)] pure fn to_i8(&self) -> i8 { *self as i8 } - #[inline(always)] pure fn to_i16(&self) -> i16 { *self as i16 } - #[inline(always)] pure fn to_i32(&self) -> i32 { *self as i32 } - #[inline(always)] pure fn to_i64(&self) -> i64 { *self } - #[inline(always)] pure fn to_int(&self) -> int { *self as int } + #[inline(always)] fn to_i8(&self) -> i8 { *self as i8 } + #[inline(always)] fn to_i16(&self) -> i16 { *self as i16 } + #[inline(always)] fn to_i32(&self) -> i32 { *self as i32 } + #[inline(always)] fn to_i64(&self) -> i64 { *self } + #[inline(always)] fn to_int(&self) -> int { *self as int } - #[inline(always)] pure fn to_f32(&self) -> f32 { *self as f32 } - #[inline(always)] pure fn to_f64(&self) -> f64 { *self as f64 } - #[inline(always)] pure fn to_float(&self) -> float { *self as float } + #[inline(always)] fn to_f32(&self) -> f32 { *self as f32 } + #[inline(always)] fn to_f64(&self) -> f64 { *self as f64 } + #[inline(always)] fn to_float(&self) -> float { *self as float } } #[test] diff --git a/src/libcore/num/int-template/i8.rs b/src/libcore/num/int-template/i8.rs index e70811adff1c0..2f2de358337b7 100644 --- a/src/libcore/num/int-template/i8.rs +++ b/src/libcore/num/int-template/i8.rs @@ -14,7 +14,7 @@ use num::NumCast; mod inst { pub type T = i8; - pub const bits: uint = ::u8::bits; + pub static bits: uint = ::u8::bits; } impl NumCast for i8 { @@ -22,23 +22,23 @@ impl NumCast for i8 { * Cast `n` to a `i8` */ #[inline(always)] - static pure fn from(n: N) -> i8 { n.to_i8() } + fn from(n: N) -> i8 { n.to_i8() } - #[inline(always)] pure fn to_u8(&self) -> u8 { *self as u8 } - #[inline(always)] pure fn to_u16(&self) -> u16 { *self as u16 } - #[inline(always)] pure fn to_u32(&self) -> u32 { *self as u32 } - #[inline(always)] pure fn to_u64(&self) -> u64 { *self as u64 } - #[inline(always)] pure fn to_uint(&self) -> uint { *self as uint } + #[inline(always)] fn to_u8(&self) -> u8 { *self as u8 } + #[inline(always)] fn to_u16(&self) -> u16 { *self as u16 } + #[inline(always)] fn to_u32(&self) -> u32 { *self as u32 } + #[inline(always)] fn to_u64(&self) -> u64 { *self as u64 } + #[inline(always)] fn to_uint(&self) -> uint { *self as uint } - #[inline(always)] pure fn to_i8(&self) -> i8 { *self } - #[inline(always)] pure fn to_i16(&self) -> i16 { *self as i16 } - #[inline(always)] pure fn to_i32(&self) -> i32 { *self as i32 } - #[inline(always)] pure fn to_i64(&self) -> i64 { *self as i64 } - #[inline(always)] pure fn to_int(&self) -> int { *self as int } + #[inline(always)] fn to_i8(&self) -> i8 { *self } + #[inline(always)] fn to_i16(&self) -> i16 { *self as i16 } + #[inline(always)] fn to_i32(&self) -> i32 { *self as i32 } + #[inline(always)] fn to_i64(&self) -> i64 { *self as i64 } + #[inline(always)] fn to_int(&self) -> int { *self as int } - #[inline(always)] pure fn to_f32(&self) -> f32 { *self as f32 } - #[inline(always)] pure fn to_f64(&self) -> f64 { *self as f64 } - #[inline(always)] pure fn to_float(&self) -> float { *self as float } + #[inline(always)] fn to_f32(&self) -> f32 { *self as f32 } + #[inline(always)] fn to_f64(&self) -> f64 { *self as f64 } + #[inline(always)] fn to_float(&self) -> float { *self as float } } #[test] diff --git a/src/libcore/num/int-template/int.rs b/src/libcore/num/int-template/int.rs index f007cc5b119fb..3c89492c7e48e 100644 --- a/src/libcore/num/int-template/int.rs +++ b/src/libcore/num/int-template/int.rs @@ -16,10 +16,10 @@ pub use self::inst::pow; mod inst { pub type T = int; - pub const bits: uint = ::uint::bits; + pub static bits: uint = ::uint::bits; /// Returns `base` raised to the power of `exponent` - pub pure fn pow(base: int, exponent: uint) -> int { + pub fn pow(base: int, exponent: uint) -> int { if exponent == 0u { //Not mathemtically true if ~[base == 0] return 1; @@ -63,23 +63,23 @@ impl NumCast for int { * Cast `n` to a `int` */ #[inline(always)] - static pure fn from(n: N) -> int { n.to_int() } + fn from(n: N) -> int { n.to_int() } - #[inline(always)] pure fn to_u8(&self) -> u8 { *self as u8 } - #[inline(always)] pure fn to_u16(&self) -> u16 { *self as u16 } - #[inline(always)] pure fn to_u32(&self) -> u32 { *self as u32 } - #[inline(always)] pure fn to_u64(&self) -> u64 { *self as u64 } - #[inline(always)] pure fn to_uint(&self) -> uint { *self as uint } + #[inline(always)] fn to_u8(&self) -> u8 { *self as u8 } + #[inline(always)] fn to_u16(&self) -> u16 { *self as u16 } + #[inline(always)] fn to_u32(&self) -> u32 { *self as u32 } + #[inline(always)] fn to_u64(&self) -> u64 { *self as u64 } + #[inline(always)] fn to_uint(&self) -> uint { *self as uint } - #[inline(always)] pure fn to_i8(&self) -> i8 { *self as i8 } - #[inline(always)] pure fn to_i16(&self) -> i16 { *self as i16 } - #[inline(always)] pure fn to_i32(&self) -> i32 { *self as i32 } - #[inline(always)] pure fn to_i64(&self) -> i64 { *self as i64 } - #[inline(always)] pure fn to_int(&self) -> int { *self } + #[inline(always)] fn to_i8(&self) -> i8 { *self as i8 } + #[inline(always)] fn to_i16(&self) -> i16 { *self as i16 } + #[inline(always)] fn to_i32(&self) -> i32 { *self as i32 } + #[inline(always)] fn to_i64(&self) -> i64 { *self as i64 } + #[inline(always)] fn to_int(&self) -> int { *self } - #[inline(always)] pure fn to_f32(&self) -> f32 { *self as f32 } - #[inline(always)] pure fn to_f64(&self) -> f64 { *self as f64 } - #[inline(always)] pure fn to_float(&self) -> float { *self as float } + #[inline(always)] fn to_f32(&self) -> f32 { *self as f32 } + #[inline(always)] fn to_f64(&self) -> f64 { *self as f64 } + #[inline(always)] fn to_float(&self) -> float { *self as float } } #[test] diff --git a/src/libcore/num/num.rs b/src/libcore/num/num.rs index a462aed8be0d1..32d48aac0b342 100644 --- a/src/libcore/num/num.rs +++ b/src/libcore/num/num.rs @@ -17,28 +17,28 @@ use kinds::Copy; pub mod strconv; pub trait IntConvertible { - pure fn to_int(&self) -> int; - static pure fn from_int(n: int) -> Self; + fn to_int(&self) -> int; + fn from_int(n: int) -> Self; } pub trait Zero { - static pure fn zero() -> Self; + fn zero() -> Self; } pub trait One { - static pure fn one() -> Self; + fn one() -> Self; } -pub pure fn abs>(v: T) -> T { +pub fn abs>(v: T) -> T { if v < Zero::zero() { v.neg() } else { v } } pub trait Round { - pure fn round(&self, mode: RoundMode) -> Self; + fn round(&self, mode: RoundMode) -> Self; - pure fn floor(&self) -> Self; - pure fn ceil(&self) -> Self; - pure fn fract(&self) -> Self; + fn floor(&self) -> Self; + fn ceil(&self) -> Self; + fn fract(&self) -> Self; } pub enum RoundMode { @@ -59,7 +59,7 @@ pub enum RoundMode { * ~~~ */ #[inline(always)] -pub pure fn cast(n: T) -> U { +pub fn cast(n: T) -> U { NumCast::from(n) } @@ -67,31 +67,31 @@ pub pure fn cast(n: T) -> U { * An interface for generic numeric type casts */ pub trait NumCast { - static pure fn from(n: T) -> Self; - - pure fn to_u8(&self) -> u8; - pure fn to_u16(&self) -> u16; - pure fn to_u32(&self) -> u32; - pure fn to_u64(&self) -> u64; - pure fn to_uint(&self) -> uint; - - pure fn to_i8(&self) -> i8; - pure fn to_i16(&self) -> i16; - pure fn to_i32(&self) -> i32; - pure fn to_i64(&self) -> i64; - pure fn to_int(&self) -> int; - - pure fn to_f32(&self) -> f32; - pure fn to_f64(&self) -> f64; - pure fn to_float(&self) -> float; + fn from(n: T) -> Self; + + fn to_u8(&self) -> u8; + fn to_u16(&self) -> u16; + fn to_u32(&self) -> u32; + fn to_u64(&self) -> u64; + fn to_uint(&self) -> uint; + + fn to_i8(&self) -> i8; + fn to_i16(&self) -> i16; + fn to_i32(&self) -> i32; + fn to_i64(&self) -> i64; + fn to_int(&self) -> int; + + fn to_f32(&self) -> f32; + fn to_f64(&self) -> f64; + fn to_float(&self) -> float; } pub trait ToStrRadix { - pub pure fn to_str_radix(&self, radix: uint) -> ~str; + pub fn to_str_radix(&self, radix: uint) -> ~str; } pub trait FromStrRadix { - static pub pure fn from_str_radix(str: &str, radix: uint) -> Option; + pub fn from_str_radix(str: &str, radix: uint) -> Option; } // Generic math functions: @@ -109,7 +109,7 @@ pub trait FromStrRadix { * - If code written to use this function doesn't care about it, it's * probably assuming that `x^0` always equals `1`. */ -pub pure fn pow_with_uint+Mul>( +pub fn pow_with_uint+Mul>( radix: uint, pow: uint) -> T { let _0: T = Zero::zero(); let _1: T = One::one(); diff --git a/src/libcore/num/strconv.rs b/src/libcore/num/strconv.rs index 50fc1b03ccc2e..26f0582bfb2ba 100644 --- a/src/libcore/num/strconv.rs +++ b/src/libcore/num/strconv.rs @@ -37,12 +37,12 @@ pub enum SignFormat { } #[inline(always)] -pure fn is_NaN(num: &T) -> bool { +fn is_NaN(num: &T) -> bool { *num != *num } #[inline(always)] -pure fn is_inf(num: &T) -> bool { +fn is_inf(num: &T) -> bool { match NumStrConv::inf() { None => false, Some(n) => *num == n @@ -50,7 +50,7 @@ pure fn is_inf(num: &T) -> bool { } #[inline(always)] -pure fn is_neg_inf(num: &T) -> bool { +fn is_neg_inf(num: &T) -> bool { match NumStrConv::neg_inf() { None => false, Some(n) => *num == n @@ -58,7 +58,7 @@ pure fn is_neg_inf(num: &T) -> bool { } #[inline(always)] -pure fn is_neg_zero>(num: &T) -> bool { +fn is_neg_zero>(num: &T) -> bool { let _0: T = Zero::zero(); let _1: T = One::one(); @@ -66,35 +66,35 @@ pure fn is_neg_zero>(num: &T) -> bool { } pub trait NumStrConv { - static pure fn NaN() -> Option; - static pure fn inf() -> Option; - static pure fn neg_inf() -> Option; - static pure fn neg_zero() -> Option; + fn NaN() -> Option; + fn inf() -> Option; + fn neg_inf() -> Option; + fn neg_zero() -> Option; - pure fn round_to_zero(&self) -> Self; - pure fn fractional_part(&self) -> Self; + fn round_to_zero(&self) -> Self; + fn fractional_part(&self) -> Self; } macro_rules! impl_NumStrConv_Floating (($t:ty) => ( impl NumStrConv for $t { #[inline(always)] - static pure fn NaN() -> Option<$t> { Some( 0.0 / 0.0) } + fn NaN() -> Option<$t> { Some( 0.0 / 0.0) } #[inline(always)] - static pure fn inf() -> Option<$t> { Some( 1.0 / 0.0) } + fn inf() -> Option<$t> { Some( 1.0 / 0.0) } #[inline(always)] - static pure fn neg_inf() -> Option<$t> { Some(-1.0 / 0.0) } + fn neg_inf() -> Option<$t> { Some(-1.0 / 0.0) } #[inline(always)] - static pure fn neg_zero() -> Option<$t> { Some(-0.0 ) } + fn neg_zero() -> Option<$t> { Some(-0.0 ) } #[inline(always)] - pure fn round_to_zero(&self) -> $t { + fn round_to_zero(&self) -> $t { ( if *self < 0.0 { f64::ceil(*self as f64) } else { f64::floor(*self as f64) } ) as $t } #[inline(always)] - pure fn fractional_part(&self) -> $t { + fn fractional_part(&self) -> $t { *self - self.round_to_zero() } } @@ -102,13 +102,13 @@ macro_rules! impl_NumStrConv_Floating (($t:ty) => ( macro_rules! impl_NumStrConv_Integer (($t:ty) => ( impl NumStrConv for $t { - #[inline(always)] static pure fn NaN() -> Option<$t> { None } - #[inline(always)] static pure fn inf() -> Option<$t> { None } - #[inline(always)] static pure fn neg_inf() -> Option<$t> { None } - #[inline(always)] static pure fn neg_zero() -> Option<$t> { None } + #[inline(always)] fn NaN() -> Option<$t> { None } + #[inline(always)] fn inf() -> Option<$t> { None } + #[inline(always)] fn neg_inf() -> Option<$t> { None } + #[inline(always)] fn neg_zero() -> Option<$t> { None } - #[inline(always)] pure fn round_to_zero(&self) -> $t { *self } - #[inline(always)] pure fn fractional_part(&self) -> $t { 0 } + #[inline(always)] fn round_to_zero(&self) -> $t { *self } + #[inline(always)] fn fractional_part(&self) -> $t { 0 } } )) @@ -161,11 +161,11 @@ impl_NumStrConv_Integer!(u64) * # Failure * - Fails if `radix` < 2 or `radix` > 36. */ -pub pure fn to_str_bytes_common+Neg+Modulo+Mul>( num: &T, radix: uint, negative_zero: bool, sign: SignFormat, digits: SignificantDigits) -> (~[u8], bool) { - if radix as int < 2 { + if (radix as int) < 2 { fail!(fmt!("to_str_bytes_common: radix %? to low, \ must lie in the range [2, 36]", radix)); } else if radix as int > 36 { @@ -364,14 +364,14 @@ pub pure fn to_str_bytes_common+Neg+Modulo+Mul>( num: &T, radix: uint, negative_zero: bool, sign: SignFormat, digits: SignificantDigits) -> (~str, bool) { @@ -394,9 +394,9 @@ pub pure fn to_str_common+ +pub fn from_str_bytes_common+ Mul+Sub+Neg+Add+ NumStrConv>( buf: &[u8], radix: uint, negative: bool, fractional: bool, @@ -455,10 +455,10 @@ pub pure fn from_str_bytes_common+ _ if special && radix >= DIGIT_I_RADIX // first digit of 'inf' => fail!(fmt!("from_str_bytes_common: radix %? incompatible with \ special values 'inf' and 'NaN'", radix)), - _ if radix as int < 2 + _ if (radix as int) < 2 => fail!(fmt!("from_str_bytes_common: radix %? to low, \ must lie in the range [2, 36]", radix)), - _ if radix as int > 36 + _ if (radix as int) > 36 => fail!(fmt!("from_str_bytes_common: radix %? to high, \ must lie in the range [2, 36]", radix)), _ => () @@ -606,7 +606,7 @@ pub pure fn from_str_bytes_common+ // parse remaining bytes as decimal integer, // skipping the exponent char let exp: Option = from_str_bytes_common( - buf.view(i+1, len), 10, true, false, false, ExpNone, false); + buf.slice(i+1, len), 10, true, false, false, ExpNone, false); match exp { Some(exp_pow) => { @@ -628,7 +628,7 @@ pub pure fn from_str_bytes_common+ * `from_str_bytes_common()`, for details see there. */ #[inline(always)] -pub pure fn from_str_common+Mul+ +pub fn from_str_common+Mul+ Sub+Neg+Add+NumStrConv>( buf: &str, radix: uint, negative: bool, fractional: bool, special: bool, exponent: ExponentFormat, empty_zero: bool diff --git a/src/libcore/num/uint-template.rs b/src/libcore/num/uint-template.rs index 9abbfb03d7a56..41d90cc24826b 100644 --- a/src/libcore/num/uint-template.rs +++ b/src/libcore/num/uint-template.rs @@ -23,51 +23,51 @@ use prelude::*; pub use cmp::{min, max}; -pub const bits : uint = inst::bits; -pub const bytes : uint = (inst::bits / 8); +pub static bits : uint = inst::bits; +pub static bytes : uint = (inst::bits / 8); -pub const min_value: T = 0 as T; -pub const max_value: T = 0 as T - 1 as T; +pub static min_value: T = 0 as T; +pub static max_value: T = 0 as T - 1 as T; #[inline(always)] -pub pure fn add(x: T, y: T) -> T { x + y } +pub fn add(x: T, y: T) -> T { x + y } #[inline(always)] -pub pure fn sub(x: T, y: T) -> T { x - y } +pub fn sub(x: T, y: T) -> T { x - y } #[inline(always)] -pub pure fn mul(x: T, y: T) -> T { x * y } +pub fn mul(x: T, y: T) -> T { x * y } #[inline(always)] -pub pure fn div(x: T, y: T) -> T { x / y } +pub fn div(x: T, y: T) -> T { x / y } #[inline(always)] -pub pure fn rem(x: T, y: T) -> T { x % y } +pub fn rem(x: T, y: T) -> T { x % y } #[inline(always)] -pub pure fn lt(x: T, y: T) -> bool { x < y } +pub fn lt(x: T, y: T) -> bool { x < y } #[inline(always)] -pub pure fn le(x: T, y: T) -> bool { x <= y } +pub fn le(x: T, y: T) -> bool { x <= y } #[inline(always)] -pub pure fn eq(x: T, y: T) -> bool { x == y } +pub fn eq(x: T, y: T) -> bool { x == y } #[inline(always)] -pub pure fn ne(x: T, y: T) -> bool { x != y } +pub fn ne(x: T, y: T) -> bool { x != y } #[inline(always)] -pub pure fn ge(x: T, y: T) -> bool { x >= y } +pub fn ge(x: T, y: T) -> bool { x >= y } #[inline(always)] -pub pure fn gt(x: T, y: T) -> bool { x > y } +pub fn gt(x: T, y: T) -> bool { x > y } #[inline(always)] -pub pure fn is_positive(x: T) -> bool { x > 0 as T } +pub fn is_positive(x: T) -> bool { x > 0 as T } #[inline(always)] -pub pure fn is_negative(x: T) -> bool { x < 0 as T } +pub fn is_negative(x: T) -> bool { x < 0 as T } #[inline(always)] -pub pure fn is_nonpositive(x: T) -> bool { x <= 0 as T } +pub fn is_nonpositive(x: T) -> bool { x <= 0 as T } #[inline(always)] -pub pure fn is_nonnegative(x: T) -> bool { x >= 0 as T } +pub fn is_nonnegative(x: T) -> bool { x >= 0 as T } #[inline(always)] /** * Iterate over the range [`start`,`start`+`step`..`stop`) * */ -pub pure fn range_step(start: T, +pub fn range_step(start: T, stop: T, step: T_SIGNED, it: &fn(T) -> bool) { @@ -91,110 +91,110 @@ pub pure fn range_step(start: T, #[inline(always)] /// Iterate over the range [`lo`..`hi`) -pub pure fn range(lo: T, hi: T, it: &fn(T) -> bool) { +pub fn range(lo: T, hi: T, it: &fn(T) -> bool) { range_step(lo, hi, 1 as T_SIGNED, it); } #[inline(always)] /// Iterate over the range [`hi`..`lo`) -pub pure fn range_rev(hi: T, lo: T, it: &fn(T) -> bool) { +pub fn range_rev(hi: T, lo: T, it: &fn(T) -> bool) { range_step(hi, lo, -1 as T_SIGNED, it); } /// Computes the bitwise complement #[inline(always)] -pub pure fn compl(i: T) -> T { +pub fn compl(i: T) -> T { max_value ^ i } #[cfg(notest)] impl Ord for T { #[inline(always)] - pure fn lt(&self, other: &T) -> bool { (*self) < (*other) } + fn lt(&self, other: &T) -> bool { (*self) < (*other) } #[inline(always)] - pure fn le(&self, other: &T) -> bool { (*self) <= (*other) } + fn le(&self, other: &T) -> bool { (*self) <= (*other) } #[inline(always)] - pure fn ge(&self, other: &T) -> bool { (*self) >= (*other) } + fn ge(&self, other: &T) -> bool { (*self) >= (*other) } #[inline(always)] - pure fn gt(&self, other: &T) -> bool { (*self) > (*other) } + fn gt(&self, other: &T) -> bool { (*self) > (*other) } } #[cfg(notest)] impl Eq for T { #[inline(always)] - pure fn eq(&self, other: &T) -> bool { return (*self) == (*other); } + fn eq(&self, other: &T) -> bool { return (*self) == (*other); } #[inline(always)] - pure fn ne(&self, other: &T) -> bool { return (*self) != (*other); } + fn ne(&self, other: &T) -> bool { return (*self) != (*other); } } impl num::Zero for T { #[inline(always)] - static pure fn zero() -> T { 0 } + fn zero() -> T { 0 } } impl num::One for T { #[inline(always)] - static pure fn one() -> T { 1 } + fn one() -> T { 1 } } #[cfg(notest)] impl ops::Add for T { - pure fn add(&self, other: &T) -> T { *self + *other } + fn add(&self, other: &T) -> T { *self + *other } } #[cfg(notest)] impl ops::Sub for T { - pure fn sub(&self, other: &T) -> T { *self - *other } + fn sub(&self, other: &T) -> T { *self - *other } } #[cfg(notest)] impl ops::Mul for T { - pure fn mul(&self, other: &T) -> T { *self * *other } + fn mul(&self, other: &T) -> T { *self * *other } } #[cfg(notest)] impl ops::Div for T { - pure fn div(&self, other: &T) -> T { *self / *other } + fn div(&self, other: &T) -> T { *self / *other } } #[cfg(notest)] impl ops::Modulo for T { - pure fn modulo(&self, other: &T) -> T { *self % *other } + fn modulo(&self, other: &T) -> T { *self % *other } } #[cfg(notest)] impl ops::Neg for T { - pure fn neg(&self) -> T { -*self } + fn neg(&self) -> T { -*self } } // String conversion functions and impl str -> num /// Parse a string as a number in base 10. #[inline(always)] -pub pure fn from_str(s: &str) -> Option { +pub fn from_str(s: &str) -> Option { strconv::from_str_common(s, 10u, false, false, false, strconv::ExpNone, false) } /// Parse a string as a number in the given base. #[inline(always)] -pub pure fn from_str_radix(s: &str, radix: uint) -> Option { +pub fn from_str_radix(s: &str, radix: uint) -> Option { strconv::from_str_common(s, radix, false, false, false, strconv::ExpNone, false) } /// Parse a byte slice as a number in the given base. #[inline(always)] -pub pure fn parse_bytes(buf: &[u8], radix: uint) -> Option { +pub fn parse_bytes(buf: &[u8], radix: uint) -> Option { strconv::from_str_bytes_common(buf, radix, false, false, false, strconv::ExpNone, false) } impl FromStr for T { #[inline(always)] - static pure fn from_str(s: &str) -> Option { + fn from_str(s: &str) -> Option { from_str(s) } } impl FromStrRadix for T { #[inline(always)] - static pure fn from_str_radix(&self, s: &str, radix: uint) -> Option { + fn from_str_radix(s: &str, radix: uint) -> Option { from_str_radix(s, radix) } } @@ -203,7 +203,7 @@ impl FromStrRadix for T { /// Convert to a string as a byte slice in a given base. #[inline(always)] -pub pure 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 { let (buf, _) = strconv::to_str_bytes_common(&n, radix, false, strconv::SignNeg, strconv::DigAll); f(buf) @@ -211,7 +211,7 @@ pub pure fn to_str_bytes(n: T, radix: uint, f: &fn(v: &[u8]) -> U) -> U { /// Convert to a string in base 10. #[inline(always)] -pub pure fn to_str(num: T) -> ~str { +pub fn to_str(num: T) -> ~str { let (buf, _) = strconv::to_str_common(&num, 10u, false, strconv::SignNeg, strconv::DigAll); buf @@ -219,7 +219,7 @@ pub pure fn to_str(num: T) -> ~str { /// Convert to a string in a given base. #[inline(always)] -pub pure fn to_str_radix(num: T, radix: uint) -> ~str { +pub fn to_str_radix(num: T, radix: uint) -> ~str { let (buf, _) = strconv::to_str_common(&num, radix, false, strconv::SignNeg, strconv::DigAll); buf @@ -227,14 +227,14 @@ pub pure fn to_str_radix(num: T, radix: uint) -> ~str { impl ToStr for T { #[inline(always)] - pure fn to_str(&self) -> ~str { + fn to_str(&self) -> ~str { to_str(*self) } } impl ToStrRadix for T { #[inline(always)] - pure fn to_str_radix(&self, radix: uint) -> ~str { + fn to_str_radix(&self, radix: uint) -> ~str { to_str_radix(*self, radix) } } diff --git a/src/libcore/num/uint-template/u16.rs b/src/libcore/num/uint-template/u16.rs index 16a1d6209295a..c73313ac0f34f 100644 --- a/src/libcore/num/uint-template/u16.rs +++ b/src/libcore/num/uint-template/u16.rs @@ -16,7 +16,7 @@ mod inst { pub type T = u16; #[allow(non_camel_case_types)] pub type T_SIGNED = i16; - pub const bits: uint = 16; + pub static bits: uint = 16; } impl NumCast for u16 { @@ -24,23 +24,23 @@ impl NumCast for u16 { * Cast `n` to a `u16` */ #[inline(always)] - static pure fn from(n: N) -> u16 { n.to_u16() } + fn from(n: N) -> u16 { n.to_u16() } - #[inline(always)] pure fn to_u8(&self) -> u8 { *self as u8 } - #[inline(always)] pure fn to_u16(&self) -> u16 { *self } - #[inline(always)] pure fn to_u32(&self) -> u32 { *self as u32 } - #[inline(always)] pure fn to_u64(&self) -> u64 { *self as u64 } - #[inline(always)] pure fn to_uint(&self) -> uint { *self as uint } + #[inline(always)] fn to_u8(&self) -> u8 { *self as u8 } + #[inline(always)] fn to_u16(&self) -> u16 { *self } + #[inline(always)] fn to_u32(&self) -> u32 { *self as u32 } + #[inline(always)] fn to_u64(&self) -> u64 { *self as u64 } + #[inline(always)] fn to_uint(&self) -> uint { *self as uint } - #[inline(always)] pure fn to_i8(&self) -> i8 { *self as i8 } - #[inline(always)] pure fn to_i16(&self) -> i16 { *self as i16 } - #[inline(always)] pure fn to_i32(&self) -> i32 { *self as i32 } - #[inline(always)] pure fn to_i64(&self) -> i64 { *self as i64 } - #[inline(always)] pure fn to_int(&self) -> int { *self as int } + #[inline(always)] fn to_i8(&self) -> i8 { *self as i8 } + #[inline(always)] fn to_i16(&self) -> i16 { *self as i16 } + #[inline(always)] fn to_i32(&self) -> i32 { *self as i32 } + #[inline(always)] fn to_i64(&self) -> i64 { *self as i64 } + #[inline(always)] fn to_int(&self) -> int { *self as int } - #[inline(always)] pure fn to_f32(&self) -> f32 { *self as f32 } - #[inline(always)] pure fn to_f64(&self) -> f64 { *self as f64 } - #[inline(always)] pure fn to_float(&self) -> float { *self as float } + #[inline(always)] fn to_f32(&self) -> f32 { *self as f32 } + #[inline(always)] fn to_f64(&self) -> f64 { *self as f64 } + #[inline(always)] fn to_float(&self) -> float { *self as float } } #[test] diff --git a/src/libcore/num/uint-template/u32.rs b/src/libcore/num/uint-template/u32.rs index cf92feb6427f4..eb63f1a370aec 100644 --- a/src/libcore/num/uint-template/u32.rs +++ b/src/libcore/num/uint-template/u32.rs @@ -16,7 +16,7 @@ mod inst { pub type T = u32; #[allow(non_camel_case_types)] pub type T_SIGNED = i32; - pub const bits: uint = 32; + pub static bits: uint = 32; } impl NumCast for u32 { @@ -24,23 +24,23 @@ impl NumCast for u32 { * Cast `n` to a `u32` */ #[inline(always)] - static pure fn from(n: N) -> u32 { n.to_u32() } + fn from(n: N) -> u32 { n.to_u32() } - #[inline(always)] pure fn to_u8(&self) -> u8 { *self as u8 } - #[inline(always)] pure fn to_u16(&self) -> u16 { *self as u16 } - #[inline(always)] pure fn to_u32(&self) -> u32 { *self } - #[inline(always)] pure fn to_u64(&self) -> u64 { *self as u64 } - #[inline(always)] pure fn to_uint(&self) -> uint { *self as uint } + #[inline(always)] fn to_u8(&self) -> u8 { *self as u8 } + #[inline(always)] fn to_u16(&self) -> u16 { *self as u16 } + #[inline(always)] fn to_u32(&self) -> u32 { *self } + #[inline(always)] fn to_u64(&self) -> u64 { *self as u64 } + #[inline(always)] fn to_uint(&self) -> uint { *self as uint } - #[inline(always)] pure fn to_i8(&self) -> i8 { *self as i8 } - #[inline(always)] pure fn to_i16(&self) -> i16 { *self as i16 } - #[inline(always)] pure fn to_i32(&self) -> i32 { *self as i32 } - #[inline(always)] pure fn to_i64(&self) -> i64 { *self as i64 } - #[inline(always)] pure fn to_int(&self) -> int { *self as int } + #[inline(always)] fn to_i8(&self) -> i8 { *self as i8 } + #[inline(always)] fn to_i16(&self) -> i16 { *self as i16 } + #[inline(always)] fn to_i32(&self) -> i32 { *self as i32 } + #[inline(always)] fn to_i64(&self) -> i64 { *self as i64 } + #[inline(always)] fn to_int(&self) -> int { *self as int } - #[inline(always)] pure fn to_f32(&self) -> f32 { *self as f32 } - #[inline(always)] pure fn to_f64(&self) -> f64 { *self as f64 } - #[inline(always)] pure fn to_float(&self) -> float { *self as float } + #[inline(always)] fn to_f32(&self) -> f32 { *self as f32 } + #[inline(always)] fn to_f64(&self) -> f64 { *self as f64 } + #[inline(always)] fn to_float(&self) -> float { *self as float } } #[test] diff --git a/src/libcore/num/uint-template/u64.rs b/src/libcore/num/uint-template/u64.rs index 269d8e185f37b..799421dc9767f 100644 --- a/src/libcore/num/uint-template/u64.rs +++ b/src/libcore/num/uint-template/u64.rs @@ -16,7 +16,7 @@ mod inst { pub type T = u64; #[allow(non_camel_case_types)] pub type T_SIGNED = i64; - pub const bits: uint = 64; + pub static bits: uint = 64; } impl NumCast for u64 { @@ -24,23 +24,23 @@ impl NumCast for u64 { * Cast `n` to a `u64` */ #[inline(always)] - static pure fn from(n: N) -> u64 { n.to_u64() } + fn from(n: N) -> u64 { n.to_u64() } - #[inline(always)] pure fn to_u8(&self) -> u8 { *self as u8 } - #[inline(always)] pure fn to_u16(&self) -> u16 { *self as u16 } - #[inline(always)] pure fn to_u32(&self) -> u32 { *self as u32 } - #[inline(always)] pure fn to_u64(&self) -> u64 { *self } - #[inline(always)] pure fn to_uint(&self) -> uint { *self as uint } + #[inline(always)] fn to_u8(&self) -> u8 { *self as u8 } + #[inline(always)] fn to_u16(&self) -> u16 { *self as u16 } + #[inline(always)] fn to_u32(&self) -> u32 { *self as u32 } + #[inline(always)] fn to_u64(&self) -> u64 { *self } + #[inline(always)] fn to_uint(&self) -> uint { *self as uint } - #[inline(always)] pure fn to_i8(&self) -> i8 { *self as i8 } - #[inline(always)] pure fn to_i16(&self) -> i16 { *self as i16 } - #[inline(always)] pure fn to_i32(&self) -> i32 { *self as i32 } - #[inline(always)] pure fn to_i64(&self) -> i64 { *self as i64 } - #[inline(always)] pure fn to_int(&self) -> int { *self as int } + #[inline(always)] fn to_i8(&self) -> i8 { *self as i8 } + #[inline(always)] fn to_i16(&self) -> i16 { *self as i16 } + #[inline(always)] fn to_i32(&self) -> i32 { *self as i32 } + #[inline(always)] fn to_i64(&self) -> i64 { *self as i64 } + #[inline(always)] fn to_int(&self) -> int { *self as int } - #[inline(always)] pure fn to_f32(&self) -> f32 { *self as f32 } - #[inline(always)] pure fn to_f64(&self) -> f64 { *self as f64 } - #[inline(always)] pure fn to_float(&self) -> float { *self as float } + #[inline(always)] fn to_f32(&self) -> f32 { *self as f32 } + #[inline(always)] fn to_f64(&self) -> f64 { *self as f64 } + #[inline(always)] fn to_float(&self) -> float { *self as float } } #[test] diff --git a/src/libcore/num/uint-template/u8.rs b/src/libcore/num/uint-template/u8.rs index 44428abdb4ff0..b173d29510c04 100644 --- a/src/libcore/num/uint-template/u8.rs +++ b/src/libcore/num/uint-template/u8.rs @@ -18,12 +18,12 @@ mod inst { pub type T = u8; #[allow(non_camel_case_types)] pub type T_SIGNED = i8; - pub const bits: uint = 8; + pub static 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; - pub pure fn is_ascii(x: T) -> bool { return 0 as T == x & 128 as T; } + pub fn is_ascii(x: T) -> bool { return 0 as T == x & 128 as T; } } impl NumCast for u8 { @@ -31,23 +31,23 @@ impl NumCast for u8 { * Cast `n` to a `u8` */ #[inline(always)] - static pure fn from(n: N) -> u8 { n.to_u8() } + fn from(n: N) -> u8 { n.to_u8() } - #[inline(always)] pure fn to_u8(&self) -> u8 { *self } - #[inline(always)] pure fn to_u16(&self) -> u16 { *self as u16 } - #[inline(always)] pure fn to_u32(&self) -> u32 { *self as u32 } - #[inline(always)] pure fn to_u64(&self) -> u64 { *self as u64 } - #[inline(always)] pure fn to_uint(&self) -> uint { *self as uint } + #[inline(always)] fn to_u8(&self) -> u8 { *self } + #[inline(always)] fn to_u16(&self) -> u16 { *self as u16 } + #[inline(always)] fn to_u32(&self) -> u32 { *self as u32 } + #[inline(always)] fn to_u64(&self) -> u64 { *self as u64 } + #[inline(always)] fn to_uint(&self) -> uint { *self as uint } - #[inline(always)] pure fn to_i8(&self) -> i8 { *self as i8 } - #[inline(always)] pure fn to_i16(&self) -> i16 { *self as i16 } - #[inline(always)] pure fn to_i32(&self) -> i32 { *self as i32 } - #[inline(always)] pure fn to_i64(&self) -> i64 { *self as i64 } - #[inline(always)] pure fn to_int(&self) -> int { *self as int } + #[inline(always)] fn to_i8(&self) -> i8 { *self as i8 } + #[inline(always)] fn to_i16(&self) -> i16 { *self as i16 } + #[inline(always)] fn to_i32(&self) -> i32 { *self as i32 } + #[inline(always)] fn to_i64(&self) -> i64 { *self as i64 } + #[inline(always)] fn to_int(&self) -> int { *self as int } - #[inline(always)] pure fn to_f32(&self) -> f32 { *self as f32 } - #[inline(always)] pure fn to_f64(&self) -> f64 { *self as f64 } - #[inline(always)] pure fn to_float(&self) -> float { *self as float } + #[inline(always)] fn to_f32(&self) -> f32 { *self as f32 } + #[inline(always)] fn to_f64(&self) -> f64 { *self as f64 } + #[inline(always)] fn to_float(&self) -> float { *self as float } } #[test] diff --git a/src/libcore/num/uint-template/uint.rs b/src/libcore/num/uint-template/uint.rs index f73ff4442ceee..741e0f36a333b 100644 --- a/src/libcore/num/uint-template/uint.rs +++ b/src/libcore/num/uint-template/uint.rs @@ -28,10 +28,10 @@ pub mod inst { #[cfg(target_arch = "x86")] #[cfg(target_arch = "arm")] #[cfg(target_arch = "mips")] - pub const bits: uint = 32; + pub static bits: uint = 32; #[cfg(target_arch = "x86_64")] - pub const bits: uint = 64; + pub static bits: uint = 64; /** * Divide two numbers, return the result, rounded up. @@ -45,7 +45,7 @@ pub mod inst { * * The smallest integer `q` such that `x/y <= q`. */ - pub pure fn div_ceil(x: uint, y: uint) -> uint { + pub fn div_ceil(x: uint, y: uint) -> uint { let div = x / y; if x % y == 0u { div } else { div + 1u } @@ -63,7 +63,7 @@ pub mod inst { * * The integer `q` closest to `x/y`. */ - pub pure fn div_round(x: uint, y: uint) -> uint { + pub fn div_round(x: uint, y: uint) -> uint { let div = x / y; if x % y * 2u < y { div } else { div + 1u } @@ -84,7 +84,7 @@ pub mod inst { * The smallest integer `q` such that `x/y <= q`. This * is either `x/y` or `x/y + 1`. */ - pub pure fn div_floor(x: uint, y: uint) -> uint { return x / y; } + pub fn div_floor(x: uint, y: uint) -> uint { return x / y; } /** * Iterate over the range [`lo`..`hi`), or stop when requested @@ -101,7 +101,7 @@ pub mod inst { * `true` If execution proceeded correctly, `false` if it was interrupted, * that is if `it` returned `false` at any point. */ - pub pure fn iterate(lo: uint, hi: uint, it: &fn(uint) -> bool) -> bool { + pub fn iterate(lo: uint, hi: uint, it: &fn(uint) -> bool) -> bool { let mut i = lo; while i < hi { if (!it(i)) { return false; } @@ -122,7 +122,7 @@ pub mod inst { * use with integer literals of inferred integer-type as * the self-value (eg. `for 100.times { ... }`). */ - pure fn times(&self, it: &fn() -> bool) { + fn times(&self, it: &fn() -> bool) { let mut i = *self; while i > 0 { if !it() { break } @@ -133,7 +133,7 @@ pub mod inst { /// Returns the smallest power of 2 greater than or equal to `n` #[inline(always)] - pub pure 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; @@ -215,23 +215,23 @@ impl NumCast for uint { * Cast `n` to a `uint` */ #[inline(always)] - static pure fn from(n: N) -> uint { n.to_uint() } + fn from(n: N) -> uint { n.to_uint() } - #[inline(always)] pure fn to_u8(&self) -> u8 { *self as u8 } - #[inline(always)] pure fn to_u16(&self) -> u16 { *self as u16 } - #[inline(always)] pure fn to_u32(&self) -> u32 { *self as u32 } - #[inline(always)] pure fn to_u64(&self) -> u64 { *self as u64 } - #[inline(always)] pure fn to_uint(&self) -> uint { *self } + #[inline(always)] fn to_u8(&self) -> u8 { *self as u8 } + #[inline(always)] fn to_u16(&self) -> u16 { *self as u16 } + #[inline(always)] fn to_u32(&self) -> u32 { *self as u32 } + #[inline(always)] fn to_u64(&self) -> u64 { *self as u64 } + #[inline(always)] fn to_uint(&self) -> uint { *self } - #[inline(always)] pure fn to_i8(&self) -> i8 { *self as i8 } - #[inline(always)] pure fn to_i16(&self) -> i16 { *self as i16 } - #[inline(always)] pure fn to_i32(&self) -> i32 { *self as i32 } - #[inline(always)] pure fn to_i64(&self) -> i64 { *self as i64 } - #[inline(always)] pure fn to_int(&self) -> int { *self as int } + #[inline(always)] fn to_i8(&self) -> i8 { *self as i8 } + #[inline(always)] fn to_i16(&self) -> i16 { *self as i16 } + #[inline(always)] fn to_i32(&self) -> i32 { *self as i32 } + #[inline(always)] fn to_i64(&self) -> i64 { *self as i64 } + #[inline(always)] fn to_int(&self) -> int { *self as int } - #[inline(always)] pure fn to_f32(&self) -> f32 { *self as f32 } - #[inline(always)] pure fn to_f64(&self) -> f64 { *self as f64 } - #[inline(always)] pure fn to_float(&self) -> float { *self as float } + #[inline(always)] fn to_f32(&self) -> f32 { *self as f32 } + #[inline(always)] fn to_f64(&self) -> f64 { *self as f64 } + #[inline(always)] fn to_float(&self) -> float { *self as float } } #[test] diff --git a/src/libcore/ops.rs b/src/libcore/ops.rs index aaa4ab3fecfee..2f7fe1e4aa8bf 100644 --- a/src/libcore/ops.rs +++ b/src/libcore/ops.rs @@ -17,65 +17,65 @@ pub trait Drop { #[lang="add"] pub trait Add { - pure fn add(&self, rhs: &RHS) -> Result; + fn add(&self, rhs: &RHS) -> Result; } #[lang="sub"] pub trait Sub { - pure fn sub(&self, rhs: &RHS) -> Result; + fn sub(&self, rhs: &RHS) -> Result; } #[lang="mul"] pub trait Mul { - pure fn mul(&self, rhs: &RHS) -> Result; + fn mul(&self, rhs: &RHS) -> Result; } #[lang="div"] pub trait Div { - pure fn div(&self, rhs: &RHS) -> Result; + fn div(&self, rhs: &RHS) -> Result; } #[lang="modulo"] pub trait Modulo { - pure fn modulo(&self, rhs: &RHS) -> Result; + fn modulo(&self, rhs: &RHS) -> Result; } #[lang="neg"] pub trait Neg { - pure fn neg(&self) -> Result; + fn neg(&self) -> Result; } #[lang="not"] pub trait Not { - pure fn not(&self) -> Result; + fn not(&self) -> Result; } #[lang="bitand"] pub trait BitAnd { - pure fn bitand(&self, rhs: &RHS) -> Result; + fn bitand(&self, rhs: &RHS) -> Result; } #[lang="bitor"] pub trait BitOr { - pure fn bitor(&self, rhs: &RHS) -> Result; + fn bitor(&self, rhs: &RHS) -> Result; } #[lang="bitxor"] pub trait BitXor { - pure fn bitxor(&self, rhs: &RHS) -> Result; + fn bitxor(&self, rhs: &RHS) -> Result; } #[lang="shl"] pub trait Shl { - pure fn shl(&self, rhs: &RHS) -> Result; + fn shl(&self, rhs: &RHS) -> Result; } #[lang="shr"] pub trait Shr { - pure fn shr(&self, rhs: &RHS) -> Result; + fn shr(&self, rhs: &RHS) -> Result; } #[lang="index"] pub trait Index { - pure fn index(&self, index: Index) -> Result; + fn index(&self, index: Index) -> Result; } diff --git a/src/libcore/option.rs b/src/libcore/option.rs index 5e5396ea12114..bb636636953b3 100644 --- a/src/libcore/option.rs +++ b/src/libcore/option.rs @@ -52,14 +52,14 @@ use iter::{BaseIter, MutableIter}; #[cfg(test)] use str; /// The option type -#[deriving_eq] +#[deriving(Clone, Eq)] pub enum Option { None, Some(T), } impl Ord for Option { - pure fn lt(&self, other: &Option) -> bool { + fn lt(&self, other: &Option) -> bool { match (self, other) { (&None, &None) => false, (&None, &Some(_)) => true, @@ -68,7 +68,7 @@ impl Ord for Option { } } - pure fn le(&self, other: &Option) -> bool { + fn le(&self, other: &Option) -> bool { match (self, other) { (&None, &None) => true, (&None, &Some(_)) => true, @@ -77,18 +77,18 @@ impl Ord for Option { } } - pure fn ge(&self, other: &Option) -> bool { + fn ge(&self, other: &Option) -> bool { ! (self < other) } - pure fn gt(&self, other: &Option) -> bool { + fn gt(&self, other: &Option) -> bool { ! (self <= other) } } impl> Add, Option> for Option { #[inline(always)] - pure fn add(&self, other: &Option) -> Option { + fn add(&self, other: &Option) -> Option { match (*self, *other) { (None, None) => None, (_, None) => *self, @@ -99,7 +99,7 @@ impl> Add, Option> for Option { } #[inline(always)] -pub pure fn get(opt: Option) -> T { +pub fn get(opt: Option) -> T { /*! Gets the value out of an option @@ -122,7 +122,7 @@ pub pure fn get(opt: Option) -> T { } #[inline(always)] -pub pure fn get_ref(opt: &'r Option) -> &'r T { +pub fn get_ref(opt: &'r Option) -> &'r T { /*! Gets an immutable reference to the value inside an option. @@ -143,7 +143,7 @@ pub pure fn get_ref(opt: &'r Option) -> &'r T { } } -pub pure fn get_mut_ref(opt: &'r mut Option) -> &'r mut T { +pub fn get_mut_ref(opt: &'r mut Option) -> &'r mut T { /*! Gets a mutable reference to the value inside an option. @@ -165,14 +165,14 @@ pub pure fn get_mut_ref(opt: &'r mut Option) -> &'r mut T { } #[inline(always)] -pub pure fn map(opt: &'r Option, f: &fn(x: &'r T) -> U) -> Option { +pub fn map(opt: &'r Option, f: &fn(x: &'r T) -> U) -> Option { //! Maps a `some` value by reference from one type to another match *opt { Some(ref x) => Some(f(x)), None => None } } #[inline(always)] -pub pure fn map_consume(opt: Option, +pub fn map_consume(opt: Option, f: &fn(v: T) -> U) -> Option { /*! * As `map`, but consumes the option and gives `f` ownership to avoid @@ -182,7 +182,7 @@ pub pure fn map_consume(opt: Option, } #[inline(always)] -pub pure fn chain(opt: Option, +pub fn chain(opt: Option, f: &fn(t: T) -> Option) -> Option { /*! * Update an optional value by optionally running its content through a @@ -196,7 +196,7 @@ pub pure fn chain(opt: Option, } #[inline(always)] -pub pure fn chain_ref(opt: &Option, +pub fn chain_ref(opt: &Option, f: &fn(x: &T) -> Option) -> Option { /*! * Update an optional value by optionally running its content by reference @@ -207,7 +207,7 @@ pub pure fn chain_ref(opt: &Option, } #[inline(always)] -pub pure fn or(opta: Option, optb: Option) -> Option { +pub fn or(opta: Option, optb: Option) -> Option { /*! * Returns the leftmost Some() value, or None if both are None. */ @@ -218,7 +218,7 @@ pub pure fn or(opta: Option, optb: Option) -> Option { } #[inline(always)] -pub pure fn while_some(x: Option, blk: &fn(v: T) -> Option) { +pub 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; @@ -228,35 +228,35 @@ pub pure fn while_some(x: Option, blk: &fn(v: T) -> Option) { } #[inline(always)] -pub pure fn is_none(opt: &const Option) -> bool { +pub fn is_none(opt: &const Option) -> bool { //! Returns true if the option equals `none` match *opt { None => true, Some(_) => false } } #[inline(always)] -pub pure fn is_some(opt: &const Option) -> bool { +pub fn is_some(opt: &const Option) -> bool { //! Returns true if the option contains some value !is_none(opt) } #[inline(always)] -pub pure fn get_or_zero(opt: Option) -> T { +pub fn get_or_zero(opt: Option) -> T { //! Returns the contained value or zero (for this type) match opt { Some(copy x) => x, None => Zero::zero() } } #[inline(always)] -pub pure fn get_or_default(opt: Option, def: T) -> T { +pub fn get_or_default(opt: Option, def: T) -> T { //! Returns the contained value or a default match opt { Some(copy x) => x, None => def } } #[inline(always)] -pub pure fn map_default(opt: &'r Option, def: U, +pub fn map_default(opt: &'r Option, def: U, f: &fn(&'r T) -> U) -> U { //! Applies a function to the contained value or returns a default @@ -264,7 +264,7 @@ pub pure fn map_default(opt: &'r Option, def: U, } #[inline(always)] -pub pure fn unwrap(opt: Option) -> T { +pub fn unwrap(opt: Option) -> T { /*! Moves a value out of an option type and returns it. @@ -302,7 +302,7 @@ pub fn swap_unwrap(opt: &mut Option) -> T { } #[inline(always)] -pub pure fn expect(opt: Option, reason: &str) -> T { +pub fn expect(opt: Option, reason: &str) -> T { //! As unwrap, but with a specified failure message. match opt { Some(val) => val, @@ -313,12 +313,12 @@ pub pure fn expect(opt: Option, reason: &str) -> T { impl BaseIter for Option { /// Performs an operation on the contained value by reference #[inline(always)] - pure fn each(&self, f: &fn(x: &'self T) -> bool) { + fn each(&self, f: &fn(x: &'self T) -> bool) { match *self { None => (), Some(ref t) => { f(t); } } } #[inline(always)] - pure fn size_hint(&self) -> Option { + fn size_hint(&self) -> Option { if self.is_some() { Some(1) } else { Some(0) } } } @@ -333,42 +333,42 @@ impl MutableIter for Option { pub impl Option { /// Returns true if the option equals `none` #[inline(always)] - pure fn is_none(&const self) -> bool { is_none(self) } + fn is_none(&const self) -> bool { is_none(self) } /// Returns true if the option contains some value #[inline(always)] - pure fn is_some(&const self) -> bool { is_some(self) } + fn is_some(&const self) -> bool { is_some(self) } /** * Update an optional value by optionally running its content by reference * through a function that returns an option. */ #[inline(always)] - pure fn chain_ref(&self, f: &fn(x: &T) -> Option) -> Option { + fn chain_ref(&self, f: &fn(x: &T) -> Option) -> Option { chain_ref(self, f) } /// Maps a `some` value from one type to another by reference #[inline(always)] - pure fn map(&self, f: &fn(&'self T) -> U) -> Option { map(self, f) } + fn map(&self, f: &fn(&'self T) -> U) -> Option { map(self, f) } /// As `map`, but consumes the option and gives `f` ownership to avoid /// copying. #[inline(always)] - pure fn map_consume(self, f: &fn(v: T) -> U) -> Option { + fn map_consume(self, f: &fn(v: T) -> U) -> Option { map_consume(self, f) } /// Applies a function to the contained value or returns a default #[inline(always)] - pure fn map_default(&self, def: U, f: &fn(&'self T) -> U) -> U { + fn map_default(&self, def: U, f: &fn(&'self T) -> U) -> U { map_default(self, def, f) } /// As `map_default`, but consumes the option and gives `f` /// ownership to avoid copying. #[inline(always)] - pure fn map_consume_default(self, def: U, f: &fn(v: T) -> U) -> U { + fn map_consume_default(self, def: U, f: &fn(v: T) -> U) -> U { match self { None => def, Some(v) => f(v) } } @@ -403,7 +403,7 @@ pub impl Option { case explicitly. */ #[inline(always)] - pure fn get_ref(&self) -> &'self T { get_ref(self) } + fn get_ref(&self) -> &'self T { get_ref(self) } /** Gets a mutable reference to the value inside an option. @@ -420,7 +420,7 @@ pub impl Option { case explicitly. */ #[inline(always)] - pure fn get_mut_ref(&mut self) -> &'self mut T { get_mut_ref(self) } + fn get_mut_ref(&mut self) -> &'self mut T { get_mut_ref(self) } /** * Gets the value out of an option without copying. @@ -430,7 +430,7 @@ pub impl Option { * Fails if the value equals `none` */ #[inline(always)] - pure fn unwrap(self) -> T { unwrap(self) } + fn unwrap(self) -> T { unwrap(self) } /** * The option dance. Moves a value out of an option type and returns it, @@ -452,7 +452,7 @@ pub impl Option { * Fails if the value equals `none` */ #[inline(always)] - pure fn expect(self, reason: &str) -> T { expect(self, reason) } + fn expect(self, reason: &str) -> T { expect(self, reason) } } pub impl Option { @@ -471,21 +471,21 @@ pub impl Option { case explicitly. */ #[inline(always)] - pure fn get(self) -> T { get(self) } + fn get(self) -> T { get(self) } #[inline(always)] - pure fn get_or_default(self, def: T) -> T { get_or_default(self, def) } + fn get_or_default(self, def: T) -> T { get_or_default(self, def) } /// Applies a function zero or more times until the result is none. #[inline(always)] - pure fn while_some(self, blk: &fn(v: T) -> Option) { + fn while_some(self, blk: &fn(v: T) -> Option) { while_some(self, blk) } } pub impl Option { #[inline(always)] - pure fn get_or_zero(self) -> T { get_or_zero(self) } + fn get_or_zero(self) -> T { get_or_zero(self) } } #[test] @@ -514,6 +514,7 @@ fn test_unwrap_resource() { i: @mut int, } + #[unsafe_destructor] impl ::ops::Drop for R { fn finalize(&self) { *(self.i) += 1; } } diff --git a/src/libcore/os.rs b/src/libcore/os.rs index 17ec9df9d5690..3c2dbf7ea15bc 100644 --- a/src/libcore/os.rs +++ b/src/libcore/os.rs @@ -65,8 +65,8 @@ pub mod rustrt { } } -pub const TMPBUF_SZ : uint = 1000u; -const BUF_BYTES : uint = 2048u; +pub static TMPBUF_SZ : uint = 1000u; +static BUF_BYTES : uint = 2048u; pub fn getcwd() -> Path { let buf = [0 as libc::c_char, ..BUF_BYTES]; @@ -1013,8 +1013,8 @@ pub fn last_os_error() -> ~str { args: *c_void) -> DWORD; } - const FORMAT_MESSAGE_FROM_SYSTEM: DWORD = 0x00001000; - const FORMAT_MESSAGE_IGNORE_INSERTS: DWORD = 0x00000200; + static FORMAT_MESSAGE_FROM_SYSTEM: DWORD = 0x00001000; + static FORMAT_MESSAGE_IGNORE_INSERTS: DWORD = 0x00000200; let mut buf = [0 as c_char, ..TMPBUF_SZ]; @@ -1170,11 +1170,11 @@ pub mod consts { pub use os::consts::windows::*; pub mod unix { - pub const FAMILY: &'static str = "unix"; + pub static FAMILY: &'static str = "unix"; } pub mod windows { - pub const FAMILY: &'static str = "windows"; + pub static FAMILY: &'static str = "windows"; } #[cfg(target_os = "macos")] @@ -1193,38 +1193,38 @@ pub mod consts { pub use os::consts::win32::*; pub mod macos { - pub const SYSNAME: &'static str = "macos"; - pub const DLL_PREFIX: &'static str = "lib"; - pub const DLL_SUFFIX: &'static str = ".dylib"; - pub const EXE_SUFFIX: &'static str = ""; + pub static SYSNAME: &'static str = "macos"; + pub static DLL_PREFIX: &'static str = "lib"; + pub static DLL_SUFFIX: &'static str = ".dylib"; + pub static EXE_SUFFIX: &'static str = ""; } pub mod freebsd { - pub const SYSNAME: &'static str = "freebsd"; - pub const DLL_PREFIX: &'static str = "lib"; - pub const DLL_SUFFIX: &'static str = ".so"; - pub const EXE_SUFFIX: &'static str = ""; + pub static SYSNAME: &'static str = "freebsd"; + pub static DLL_PREFIX: &'static str = "lib"; + pub static DLL_SUFFIX: &'static str = ".so"; + pub static EXE_SUFFIX: &'static str = ""; } pub mod linux { - pub const SYSNAME: &'static str = "linux"; - pub const DLL_PREFIX: &'static str = "lib"; - pub const DLL_SUFFIX: &'static str = ".so"; - pub const EXE_SUFFIX: &'static str = ""; + pub static SYSNAME: &'static str = "linux"; + pub static DLL_PREFIX: &'static str = "lib"; + pub static DLL_SUFFIX: &'static str = ".so"; + pub static EXE_SUFFIX: &'static str = ""; } pub mod android { - pub const SYSNAME: &'static str = "android"; - pub const DLL_PREFIX: &'static str = "lib"; - pub const DLL_SUFFIX: &'static str = ".so"; - pub const EXE_SUFFIX: &'static str = ""; + pub static SYSNAME: &'static str = "android"; + pub static DLL_PREFIX: &'static str = "lib"; + pub static DLL_SUFFIX: &'static str = ".so"; + pub static EXE_SUFFIX: &'static str = ""; } pub mod win32 { - pub const SYSNAME: &'static str = "win32"; - pub const DLL_PREFIX: &'static str = ""; - pub const DLL_SUFFIX: &'static str = ".dll"; - pub const EXE_SUFFIX: &'static str = ".exe"; + pub static SYSNAME: &'static str = "win32"; + pub static DLL_PREFIX: &'static str = ""; + pub static DLL_SUFFIX: &'static str = ".dll"; + pub static EXE_SUFFIX: &'static str = ".exe"; } @@ -1241,16 +1241,16 @@ pub mod consts { use os::consts::mips::*; pub mod x86 { - pub const ARCH: &'static str = "x86"; + pub static ARCH: &'static str = "x86"; } pub mod x86_64 { - pub const ARCH: &'static str = "x86_64"; + pub static ARCH: &'static str = "x86_64"; } pub mod arm { - pub const ARCH: &'static str = "arm"; + pub static ARCH: &'static str = "arm"; } pub mod mips { - pub const ARCH: &'static str = "mips"; + pub static ARCH: &'static str = "mips"; } } diff --git a/src/libcore/owned.rs b/src/libcore/owned.rs index 486ce44147a2d..c483ec79e21d9 100644 --- a/src/libcore/owned.rs +++ b/src/libcore/owned.rs @@ -15,20 +15,20 @@ #[cfg(notest)] impl Eq for ~T { #[inline(always)] - pure fn eq(&self, other: &~T) -> bool { *(*self) == *(*other) } + fn eq(&self, other: &~T) -> bool { *(*self) == *(*other) } #[inline(always)] - pure fn ne(&self, other: &~T) -> bool { *(*self) != *(*other) } + fn ne(&self, other: &~T) -> bool { *(*self) != *(*other) } } #[cfg(notest)] impl Ord for ~T { #[inline(always)] - pure fn lt(&self, other: &~T) -> bool { *(*self) < *(*other) } + fn lt(&self, other: &~T) -> bool { *(*self) < *(*other) } #[inline(always)] - pure fn le(&self, other: &~T) -> bool { *(*self) <= *(*other) } + fn le(&self, other: &~T) -> bool { *(*self) <= *(*other) } #[inline(always)] - pure fn ge(&self, other: &~T) -> bool { *(*self) >= *(*other) } + fn ge(&self, other: &~T) -> bool { *(*self) >= *(*other) } #[inline(always)] - pure fn gt(&self, other: &~T) -> bool { *(*self) > *(*other) } + fn gt(&self, other: &~T) -> bool { *(*self) > *(*other) } } diff --git a/src/libcore/path.rs b/src/libcore/path.rs index c688607400719..76aaf14d4ac6c 100644 --- a/src/libcore/path.rs +++ b/src/libcore/path.rs @@ -20,7 +20,7 @@ use option::{None, Option, Some}; use str; use to_str::ToStr; -#[deriving_eq] +#[deriving(Clone, Eq)] pub struct WindowsPath { host: Option<~str>, device: Option<~str>, @@ -28,52 +28,52 @@ pub struct WindowsPath { components: ~[~str], } -pub pure fn WindowsPath(s: &str) -> WindowsPath { +pub fn WindowsPath(s: &str) -> WindowsPath { GenericPath::from_str(s) } -#[deriving_eq] +#[deriving(Clone, Eq)] pub struct PosixPath { is_absolute: bool, components: ~[~str], } -pub pure fn PosixPath(s: &str) -> PosixPath { +pub fn PosixPath(s: &str) -> PosixPath { GenericPath::from_str(s) } pub trait GenericPath { - static pure fn from_str(&str) -> Self; + fn from_str(&str) -> Self; - pure fn dirname(&self) -> ~str; - pure fn filename(&self) -> Option<~str>; - pure fn filestem(&self) -> Option<~str>; - pure fn filetype(&self) -> Option<~str>; + fn dirname(&self) -> ~str; + fn filename(&self) -> Option<~str>; + fn filestem(&self) -> Option<~str>; + fn filetype(&self) -> Option<~str>; - pure fn with_dirname(&self, (&str)) -> Self; - pure fn with_filename(&self, (&str)) -> Self; - pure fn with_filestem(&self, (&str)) -> Self; - pure fn with_filetype(&self, (&str)) -> Self; + fn with_dirname(&self, (&str)) -> Self; + fn with_filename(&self, (&str)) -> Self; + fn with_filestem(&self, (&str)) -> Self; + fn with_filetype(&self, (&str)) -> Self; - pure fn dir_path(&self) -> Self; - pure fn file_path(&self) -> Self; + fn dir_path(&self) -> Self; + fn file_path(&self) -> Self; - pure fn push(&self, (&str)) -> Self; - pure fn push_rel(&self, (&Self)) -> Self; - pure fn push_many(&self, (&[~str])) -> Self; - pure fn pop(&self) -> Self; + fn push(&self, (&str)) -> Self; + fn push_rel(&self, (&Self)) -> Self; + fn push_many(&self, (&[~str])) -> Self; + fn pop(&self) -> Self; - pure fn unsafe_join(&self, (&Self)) -> Self; - pure fn is_restricted(&self) -> bool; + fn unsafe_join(&self, (&Self)) -> Self; + fn is_restricted(&self) -> bool; - pure fn normalize(&self) -> Self; + fn normalize(&self) -> Self; } #[cfg(windows)] pub type Path = WindowsPath; #[cfg(windows)] -pub pure fn Path(s: &str) -> Path { +pub fn Path(s: &str) -> Path { WindowsPath(s) } @@ -81,7 +81,7 @@ pub pure fn Path(s: &str) -> Path { pub type Path = PosixPath; #[cfg(unix)] -pub pure fn Path(s: &str) -> Path { +pub fn Path(s: &str) -> Path { PosixPath(s) } @@ -367,7 +367,7 @@ pub impl Path { } impl ToStr for PosixPath { - pure fn to_str(&self) -> ~str { + fn to_str(&self) -> ~str { let mut s = ~""; if self.is_absolute { s += "/"; @@ -380,14 +380,14 @@ impl ToStr for PosixPath { // PosixPath and WindowsPath, most of their methods are common. impl GenericPath for PosixPath { - static pure fn from_str(s: &str) -> PosixPath { + fn from_str(s: &str) -> PosixPath { let mut components = str::split_nonempty(s, |c| c == '/'); let is_absolute = (s.len() != 0 && s[0] == '/' as u8); return PosixPath { is_absolute: is_absolute, components: components } } - pure fn dirname(&self) -> ~str { + fn dirname(&self) -> ~str { unsafe { let s = self.dir_path().to_str(); if s.len() == 0 { @@ -398,38 +398,38 @@ impl GenericPath for PosixPath { } } - pure fn filename(&self) -> Option<~str> { + fn filename(&self) -> Option<~str> { match self.components.len() { 0 => None, n => Some(copy self.components[n - 1]) } } - pure fn filestem(&self) -> Option<~str> { + fn filestem(&self) -> Option<~str> { match self.filename() { None => None, Some(ref f) => { match str::rfind_char(*f, '.') { - Some(p) => Some(f.slice(0, p)), + Some(p) => Some(f.slice(0, p).to_owned()), None => Some(copy *f) } } } } - pure fn filetype(&self) -> Option<~str> { + fn filetype(&self) -> Option<~str> { match self.filename() { None => None, Some(ref f) => { match str::rfind_char(*f, '.') { - Some(p) if p < f.len() => Some(f.slice(p, f.len())), + Some(p) if p < f.len() => Some(f.slice(p, f.len()).to_owned()), _ => None } } } } - pure fn with_dirname(&self, d: &str) -> PosixPath { + fn with_dirname(&self, d: &str) -> PosixPath { let dpath = PosixPath(d); match self.filename() { Some(ref f) => dpath.push(*f), @@ -437,21 +437,21 @@ impl GenericPath for PosixPath { } } - pure fn with_filename(&self, f: &str) -> PosixPath { + fn with_filename(&self, f: &str) -> PosixPath { unsafe { fail_unless!(! str::any(f, |c| windows::is_sep(c as u8))); self.dir_path().push(f) } } - pure fn with_filestem(&self, s: &str) -> PosixPath { + fn with_filestem(&self, s: &str) -> PosixPath { match self.filetype() { None => self.with_filename(s), Some(ref t) => self.with_filename(str::from_slice(s) + *t) } } - pure fn with_filetype(&self, t: &str) -> PosixPath { + fn with_filetype(&self, t: &str) -> PosixPath { if t.len() == 0 { match self.filestem() { None => copy *self, @@ -466,7 +466,7 @@ impl GenericPath for PosixPath { } } - pure fn dir_path(&self) -> PosixPath { + fn dir_path(&self) -> PosixPath { if self.components.len() != 0 { self.pop() } else { @@ -474,7 +474,7 @@ impl GenericPath for PosixPath { } } - pure fn file_path(&self) -> PosixPath { + fn file_path(&self) -> PosixPath { let cs = match self.filename() { None => ~[], Some(ref f) => ~[copy *f] @@ -483,12 +483,12 @@ impl GenericPath for PosixPath { components: cs } } - pure fn push_rel(&self, other: &PosixPath) -> PosixPath { + fn push_rel(&self, other: &PosixPath) -> PosixPath { fail_unless!(!other.is_absolute); self.push_many(other.components) } - pure fn unsafe_join(&self, other: &PosixPath) -> PosixPath { + fn unsafe_join(&self, other: &PosixPath) -> PosixPath { if other.is_absolute { PosixPath { is_absolute: true, components: copy other.components } @@ -497,11 +497,11 @@ impl GenericPath for PosixPath { } } - pure fn is_restricted(&self) -> bool { + fn is_restricted(&self) -> bool { false } - pure fn push_many(&self, cs: &[~str]) -> PosixPath { + fn push_many(&self, cs: &[~str]) -> PosixPath { let mut v = copy self.components; for cs.each |e| { let mut ss = str::split_nonempty( @@ -513,14 +513,14 @@ impl GenericPath for PosixPath { components: v } } - pure fn push(&self, s: &str) -> PosixPath { + fn push(&self, s: &str) -> PosixPath { let mut v = copy self.components; let mut ss = str::split_nonempty(s, |c| windows::is_sep(c as u8)); unsafe { v.push_all_move(ss); } PosixPath { components: v, ..copy *self } } - pure fn pop(&self) -> PosixPath { + fn pop(&self) -> PosixPath { let mut cs = copy self.components; if cs.len() != 0 { unsafe { cs.pop(); } @@ -532,7 +532,7 @@ impl GenericPath for PosixPath { //..self } } - pure fn normalize(&self) -> PosixPath { + fn normalize(&self) -> PosixPath { return PosixPath { is_absolute: self.is_absolute, components: normalize(self.components) @@ -543,7 +543,7 @@ impl GenericPath for PosixPath { impl ToStr for WindowsPath { - pure fn to_str(&self) -> ~str { + fn to_str(&self) -> ~str { let mut s = ~""; match self.host { Some(ref h) => { s += "\\\\"; s += *h; } @@ -563,7 +563,7 @@ impl ToStr for WindowsPath { impl GenericPath for WindowsPath { - static pure fn from_str(s: &str) -> WindowsPath { + fn from_str(s: &str) -> WindowsPath { let host; let device; let rest; @@ -599,7 +599,7 @@ impl GenericPath for WindowsPath { components: components } } - pure fn dirname(&self) -> ~str { + fn dirname(&self) -> ~str { unsafe { let s = self.dir_path().to_str(); if s.len() == 0 { @@ -610,38 +610,38 @@ impl GenericPath for WindowsPath { } } - pure fn filename(&self) -> Option<~str> { + fn filename(&self) -> Option<~str> { match self.components.len() { 0 => None, n => Some(copy self.components[n - 1]) } } - pure fn filestem(&self) -> Option<~str> { + fn filestem(&self) -> Option<~str> { match self.filename() { None => None, Some(ref f) => { match str::rfind_char(*f, '.') { - Some(p) => Some(f.slice(0, p)), + Some(p) => Some(f.slice(0, p).to_owned()), None => Some(copy *f) } } } } - pure fn filetype(&self) -> Option<~str> { + fn filetype(&self) -> Option<~str> { match self.filename() { None => None, Some(ref f) => { match str::rfind_char(*f, '.') { - Some(p) if p < f.len() => Some(f.slice(p, f.len())), + Some(p) if p < f.len() => Some(f.slice(p, f.len()).to_owned()), _ => None } } } } - pure fn with_dirname(&self, d: &str) -> WindowsPath { + fn with_dirname(&self, d: &str) -> WindowsPath { let dpath = WindowsPath(d); match self.filename() { Some(ref f) => dpath.push(*f), @@ -649,19 +649,19 @@ impl GenericPath for WindowsPath { } } - pure fn with_filename(&self, f: &str) -> WindowsPath { + fn with_filename(&self, f: &str) -> WindowsPath { fail_unless!(! str::any(f, |c| windows::is_sep(c as u8))); self.dir_path().push(f) } - pure fn with_filestem(&self, s: &str) -> WindowsPath { + fn with_filestem(&self, s: &str) -> WindowsPath { match self.filetype() { None => self.with_filename(s), Some(ref t) => self.with_filename(str::from_slice(s) + *t) } } - pure fn with_filetype(&self, t: &str) -> WindowsPath { + fn with_filetype(&self, t: &str) -> WindowsPath { if t.len() == 0 { match self.filestem() { None => copy *self, @@ -677,7 +677,7 @@ impl GenericPath for WindowsPath { } } - pure fn dir_path(&self) -> WindowsPath { + fn dir_path(&self) -> WindowsPath { if self.components.len() != 0 { self.pop() } else { @@ -685,7 +685,7 @@ impl GenericPath for WindowsPath { } } - pure fn file_path(&self) -> WindowsPath { + fn file_path(&self) -> WindowsPath { let cs = match self.filename() { None => ~[], Some(ref f) => ~[copy *f] @@ -696,12 +696,12 @@ impl GenericPath for WindowsPath { components: cs } } - pure fn push_rel(&self, other: &WindowsPath) -> WindowsPath { + fn push_rel(&self, other: &WindowsPath) -> WindowsPath { fail_unless!(!other.is_absolute); self.push_many(other.components) } - pure fn unsafe_join(&self, other: &WindowsPath) -> WindowsPath { + fn unsafe_join(&self, other: &WindowsPath) -> WindowsPath { /* rhs not absolute is simple push */ if !other.is_absolute { return self.push_many(other.components); @@ -743,7 +743,7 @@ impl GenericPath for WindowsPath { } } - pure fn is_restricted(&self) -> bool { + fn is_restricted(&self) -> bool { match self.filestem() { Some(stem) => { match stem.to_lower() { @@ -756,7 +756,7 @@ impl GenericPath for WindowsPath { } } - pure fn push_many(&self, cs: &[~str]) -> WindowsPath { + fn push_many(&self, cs: &[~str]) -> WindowsPath { let mut v = copy self.components; for cs.each |e| { let mut ss = str::split_nonempty( @@ -773,14 +773,14 @@ impl GenericPath for WindowsPath { } } - pure fn push(&self, s: &str) -> WindowsPath { + fn push(&self, s: &str) -> WindowsPath { let mut v = copy self.components; let mut ss = str::split_nonempty(s, |c| windows::is_sep(c as u8)); unsafe { v.push_all_move(ss); } return WindowsPath { components: v, ..copy *self } } - pure fn pop(&self) -> WindowsPath { + fn pop(&self) -> WindowsPath { let mut cs = copy self.components; if cs.len() != 0 { unsafe { cs.pop(); } @@ -793,7 +793,7 @@ impl GenericPath for WindowsPath { } } - pure fn normalize(&self) -> WindowsPath { + fn normalize(&self) -> WindowsPath { return WindowsPath { host: copy self.host, device: match self.device { @@ -807,7 +807,7 @@ impl GenericPath for WindowsPath { } -pub pure fn normalize(components: &[~str]) -> ~[~str] { +pub fn normalize(components: &[~str]) -> ~[~str] { let mut cs = ~[]; unsafe { for components.each |c| { @@ -831,19 +831,19 @@ pub mod windows { use option::{None, Option, Some}; #[inline(always)] - pub pure fn is_sep(u: u8) -> bool { + pub fn is_sep(u: u8) -> bool { u == '/' as u8 || u == '\\' as u8 } - pub pure fn extract_unc_prefix(s: &str) -> Option<(~str,~str)> { + pub fn extract_unc_prefix(s: &str) -> Option<(~str,~str)> { if (s.len() > 1 && (s[0] == '\\' as u8 || s[0] == '/' as u8) && s[0] == s[1]) { let mut i = 2; while i < s.len() { if is_sep(s[i]) { - let pre = s.slice(2, i); - let mut rest = s.slice(i, s.len()); + let pre = s.slice(2, i).to_owned(); + let mut rest = s.slice(i, s.len()).to_owned(); return Some((pre, rest)); } i += 1; @@ -852,7 +852,7 @@ pub mod windows { None } - pub pure fn extract_drive_prefix(s: &str) -> Option<(~str,~str)> { + pub fn extract_drive_prefix(s: &str) -> Option<(~str,~str)> { unsafe { if (s.len() > 1 && libc::isalpha(s[0] as libc::c_int) != 0 && @@ -860,9 +860,9 @@ pub mod windows { let rest = if s.len() == 2 { ~"" } else { - s.slice(2, s.len()) + s.slice(2, s.len()).to_owned() }; - return Some((s.slice(0,1), rest)); + return Some((s.slice(0,1).to_owned(), rest)); } None } diff --git a/src/libcore/pipes.rs b/src/libcore/pipes.rs index eb385d9035450..350a1de629cd4 100644 --- a/src/libcore/pipes.rs +++ b/src/libcore/pipes.rs @@ -82,7 +82,6 @@ bounded and unbounded protocols allows for less code duplication. */ -use cmp::Eq; use cast::{forget, reinterpret_cast, transmute}; use cell::Cell; use either::{Either, Left, Right}; @@ -96,13 +95,14 @@ use task; use vec; #[doc(hidden)] -const SPIN_COUNT: uint = 0; +static SPIN_COUNT: uint = 0; macro_rules! move_it ( { $x:expr } => ( unsafe { let y = *ptr::addr_of(&($x)); y } ) ) #[doc(hidden)] +#[deriving(Eq)] enum State { Empty, Full, @@ -110,13 +110,6 @@ enum State { Terminated } -impl Eq for State { - pure fn eq(&self, other: &State) -> bool { - ((*self) as uint) == ((*other) as uint) - } - pure fn ne(&self, other: &State) -> bool { !(*self).eq(other) } -} - 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. @@ -350,6 +343,7 @@ struct BufferResource { } +#[unsafe_destructor] impl ::ops::Drop for BufferResource { fn finalize(&self) { unsafe { @@ -445,16 +439,17 @@ pub fn try_recv(p: RecvPacketBuffered) let p_ = p.unwrap(); let p = unsafe { &*p_ }; + #[unsafe_destructor] struct DropState { p: &'self PacketHeader, drop { - if task::failing() { - self.p.state = Terminated; - let old_task = swap_task(&mut self.p.blocked_task, - ptr::null()); - if !old_task.is_null() { - unsafe { + unsafe { + if task::failing() { + self.p.state = Terminated; + let old_task = swap_task(&mut self.p.blocked_task, + ptr::null()); + if !old_task.is_null() { rustrt::rust_task_deref(old_task); } } @@ -549,7 +544,7 @@ pub fn try_recv(p: RecvPacketBuffered) } /// Returns true if messages are available. -pub pure fn peek(p: &RecvPacketBuffered) -> bool { +pub fn peek(p: &RecvPacketBuffered) -> bool { match unsafe {(*p.header()).state} { Empty | Terminated => false, Blocked => fail!(~"peeking on blocked packet"), @@ -721,11 +716,11 @@ pub fn select2( #[doc(hidden)] pub trait Selectable { - pure fn header(&self) -> *PacketHeader; + fn header(&self) -> *PacketHeader; } impl Selectable for *PacketHeader { - pure fn header(&self) -> *PacketHeader { *self } + fn header(&self) -> *PacketHeader { *self } } /// Returns the index of an endpoint that is ready to receive. @@ -773,6 +768,7 @@ pub struct SendPacketBuffered { mut buffer: Option>, } +#[unsafe_destructor] impl ::ops::Drop for SendPacketBuffered { fn finalize(&self) { //if self.p != none { @@ -809,7 +805,7 @@ pub impl SendPacketBuffered { option::unwrap(p) } - pure fn header(&self) -> *PacketHeader { + fn header(&self) -> *PacketHeader { match self.p { Some(packet) => unsafe { let packet = &*packet; @@ -842,6 +838,7 @@ pub struct RecvPacketBuffered { mut buffer: Option>, } +#[unsafe_destructor] impl ::ops::Drop for RecvPacketBuffered { fn finalize(&self) { //if self.p != none { @@ -875,7 +872,7 @@ pub impl RecvPacketBuffered { } impl Selectable for RecvPacketBuffered { - pure fn header(&self) -> *PacketHeader { + fn header(&self) -> *PacketHeader { match self.p { Some(packet) => unsafe { let packet = &*packet; diff --git a/src/libcore/prelude.rs b/src/libcore/prelude.rs index 1710373b1e725..d0307c8bf70de 100644 --- a/src/libcore/prelude.rs +++ b/src/libcore/prelude.rs @@ -36,13 +36,14 @@ pub use path::Path; pub use path::PosixPath; pub use path::WindowsPath; pub use ptr::Ptr; -pub use str::{StrSlice, Trimmable, OwnedStr}; +pub use str::{StrSlice, OwnedStr}; pub use to_bytes::IterBytes; pub use to_str::ToStr; pub use tuple::{CopyableTuple, ImmutableTuple, ExtendedTupleOps}; pub use vec::{CopyableVector, ImmutableVector}; pub use vec::{ImmutableEqVector, ImmutableCopyableVector}; pub use vec::{OwnedVector, OwnedCopyableVector}; +pub use io::{Reader, ReaderUtil, Writer, WriterUtil}; /* Reexported runtime types */ pub use comm::{stream, Port, Chan, GenericChan, GenericSmartChan, GenericPort, Peekable}; diff --git a/src/libcore/ptr.rs b/src/libcore/ptr.rs index c1b6b26d86a35..fa96467cb0f67 100644 --- a/src/libcore/ptr.rs +++ b/src/libcore/ptr.rs @@ -51,11 +51,11 @@ pub mod rusti { /// Get an unsafe pointer to a value #[inline(always)] -pub pure fn addr_of(val: &T) -> *T { unsafe { rusti::addr_of(*val) } } +pub fn addr_of(val: &T) -> *T { unsafe { rusti::addr_of(*val) } } /// Calculate the offset from a pointer #[inline(always)] -pub pure fn offset(ptr: *T, count: uint) -> *T { +pub fn offset(ptr: *T, count: uint) -> *T { unsafe { (ptr as uint + count * sys::size_of::()) as *T } @@ -63,7 +63,7 @@ pub pure fn offset(ptr: *T, count: uint) -> *T { /// Calculate the offset from a const pointer #[inline(always)] -pub pure fn const_offset(ptr: *const T, count: uint) -> *const T { +pub fn const_offset(ptr: *const T, count: uint) -> *const T { unsafe { (ptr as uint + count * sys::size_of::()) as *T } @@ -71,7 +71,7 @@ pub pure fn const_offset(ptr: *const T, count: uint) -> *const T { /// Calculate the offset from a mut pointer #[inline(always)] -pub pure fn mut_offset(ptr: *mut T, count: uint) -> *mut T { +pub fn mut_offset(ptr: *mut T, count: uint) -> *mut T { (ptr as uint + count * sys::size_of::()) as *mut T } @@ -93,19 +93,19 @@ pub unsafe fn position(buf: *T, f: &fn(&T) -> bool) -> uint { /// Create an unsafe null pointer #[inline(always)] -pub pure fn null() -> *T { unsafe { cast::reinterpret_cast(&0u) } } +pub fn null() -> *T { unsafe { cast::reinterpret_cast(&0u) } } /// Create an unsafe mutable null pointer #[inline(always)] -pub pure fn mut_null() -> *mut T { unsafe { cast::reinterpret_cast(&0u) } } +pub fn mut_null() -> *mut T { unsafe { cast::reinterpret_cast(&0u) } } /// Returns true if the pointer is equal to the null pointer. #[inline(always)] -pub pure fn is_null(ptr: *const T) -> bool { ptr == null() } +pub fn is_null(ptr: *const T) -> bool { ptr == null() } /// Returns true if the pointer is not equal to the null pointer. #[inline(always)] -pub pure fn is_not_null(ptr: *const T) -> bool { !is_null(ptr) } +pub fn is_not_null(ptr: *const T) -> bool { !is_null(ptr) } /** * Copies data from one location to another @@ -138,7 +138,7 @@ pub unsafe fn set_memory(dst: *mut T, c: int, count: uint) { reinterpret_cast. */ #[inline(always)] -pub pure fn to_unsafe_ptr(thing: &T) -> *T { +pub fn to_unsafe_ptr(thing: &T) -> *T { unsafe { cast::reinterpret_cast(&thing) } } @@ -148,7 +148,7 @@ pub pure fn to_unsafe_ptr(thing: &T) -> *T { reinterpret_cast. */ #[inline(always)] -pub pure fn to_const_unsafe_ptr(thing: &const T) -> *const T { +pub fn to_const_unsafe_ptr(thing: &const T) -> *const T { unsafe { cast::reinterpret_cast(&thing) } } @@ -158,7 +158,7 @@ pub pure fn to_const_unsafe_ptr(thing: &const T) -> *const T { reinterpret_cast. */ #[inline(always)] -pub pure fn to_mut_unsafe_ptr(thing: &mut T) -> *mut T { +pub fn to_mut_unsafe_ptr(thing: &mut T) -> *mut T { unsafe { cast::reinterpret_cast(&thing) } } @@ -170,7 +170,7 @@ pub pure fn to_mut_unsafe_ptr(thing: &mut T) -> *mut T { (I couldn't think of a cutesy name for this one.) */ #[inline(always)] -pub pure fn to_uint(thing: &T) -> uint { +pub fn to_uint(thing: &T) -> uint { unsafe { cast::reinterpret_cast(&thing) } @@ -178,7 +178,7 @@ pub pure fn to_uint(thing: &T) -> uint { /// Determine if two borrowed pointers point to the same thing. #[inline(always)] -pub pure 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) } @@ -223,46 +223,46 @@ pub unsafe fn array_each(arr: **T, cb: &fn(*T)) { } pub trait Ptr { - pure fn is_null(&const self) -> bool; - pure fn is_not_null(&const self) -> bool; - pure fn offset(&self, count: uint) -> Self; + fn is_null(&const self) -> bool; + fn is_not_null(&const self) -> bool; + fn offset(&self, count: uint) -> Self; } /// Extension methods for immutable pointers impl Ptr for *T { /// Returns true if the pointer is equal to the null pointer. #[inline(always)] - pure fn is_null(&const self) -> bool { is_null(*self) } + fn is_null(&const self) -> bool { is_null(*self) } /// Returns true if the pointer is not equal to the null pointer. #[inline(always)] - pure fn is_not_null(&const self) -> bool { is_not_null(*self) } + fn is_not_null(&const self) -> bool { is_not_null(*self) } /// Calculates the offset from a pointer. #[inline(always)] - pure fn offset(&self, count: uint) -> *T { offset(*self, count) } + fn offset(&self, count: uint) -> *T { offset(*self, count) } } /// Extension methods for mutable pointers impl Ptr for *mut T { /// Returns true if the pointer is equal to the null pointer. #[inline(always)] - pure fn is_null(&const self) -> bool { is_null(*self) } + fn is_null(&const self) -> bool { is_null(*self) } /// Returns true if the pointer is not equal to the null pointer. #[inline(always)] - pure fn is_not_null(&const self) -> bool { is_not_null(*self) } + fn is_not_null(&const self) -> bool { is_not_null(*self) } /// Calculates the offset from a mutable pointer. #[inline(always)] - pure fn offset(&self, count: uint) -> *mut T { mut_offset(*self, count) } + fn offset(&self, count: uint) -> *mut T { mut_offset(*self, count) } } // Equality for pointers #[cfg(notest)] impl Eq for *const T { #[inline(always)] - pure fn eq(&self, other: &*const T) -> bool { + fn eq(&self, other: &*const T) -> bool { unsafe { let a: uint = cast::reinterpret_cast(&(*self)); let b: uint = cast::reinterpret_cast(&(*other)); @@ -270,14 +270,14 @@ impl Eq for *const T { } } #[inline(always)] - pure fn ne(&self, other: &*const T) -> bool { !(*self).eq(other) } + fn ne(&self, other: &*const T) -> bool { !(*self).eq(other) } } // Comparison for pointers #[cfg(notest)] impl Ord for *const T { #[inline(always)] - pure fn lt(&self, other: &*const T) -> bool { + fn lt(&self, other: &*const T) -> bool { unsafe { let a: uint = cast::reinterpret_cast(&(*self)); let b: uint = cast::reinterpret_cast(&(*other)); @@ -285,7 +285,7 @@ impl Ord for *const T { } } #[inline(always)] - pure fn le(&self, other: &*const T) -> bool { + fn le(&self, other: &*const T) -> bool { unsafe { let a: uint = cast::reinterpret_cast(&(*self)); let b: uint = cast::reinterpret_cast(&(*other)); @@ -293,7 +293,7 @@ impl Ord for *const T { } } #[inline(always)] - pure fn ge(&self, other: &*const T) -> bool { + fn ge(&self, other: &*const T) -> bool { unsafe { let a: uint = cast::reinterpret_cast(&(*self)); let b: uint = cast::reinterpret_cast(&(*other)); @@ -301,7 +301,7 @@ impl Ord for *const T { } } #[inline(always)] - pure fn gt(&self, other: &*const T) -> bool { + fn gt(&self, other: &*const T) -> bool { unsafe { let a: uint = cast::reinterpret_cast(&(*self)); let b: uint = cast::reinterpret_cast(&(*other)); @@ -314,11 +314,11 @@ impl Ord for *const T { #[cfg(notest)] impl Eq for &'self const T { #[inline(always)] - pure fn eq(&self, other: & &'self const T) -> bool { + fn eq(&self, other: & &'self const T) -> bool { return *(*self) == *(*other); } #[inline(always)] - pure fn ne(&self, other: & &'self const T) -> bool { + fn ne(&self, other: & &'self const T) -> bool { return *(*self) != *(*other); } } @@ -327,19 +327,19 @@ impl Eq for &'self const T { #[cfg(notest)] impl Ord for &'self const T { #[inline(always)] - pure fn lt(&self, other: & &'self const T) -> bool { + fn lt(&self, other: & &'self const T) -> bool { *(*self) < *(*other) } #[inline(always)] - pure fn le(&self, other: & &'self const T) -> bool { + fn le(&self, other: & &'self const T) -> bool { *(*self) <= *(*other) } #[inline(always)] - pure fn ge(&self, other: & &'self const T) -> bool { + fn ge(&self, other: & &'self const T) -> bool { *(*self) >= *(*other) } #[inline(always)] - pure fn gt(&self, other: & &'self const T) -> bool { + fn gt(&self, other: & &'self const T) -> bool { *(*self) > *(*other) } } diff --git a/src/libcore/rand.rs b/src/libcore/rand.rs index 4cb5e58b73331..3085269f692ef 100644 --- a/src/libcore/rand.rs +++ b/src/libcore/rand.rs @@ -22,95 +22,95 @@ use libc::size_t; /// A type that can be randomly generated using an RNG pub trait Rand { - static fn rand(rng: @rand::Rng) -> Self; + fn rand(rng: @rand::Rng) -> Self; } impl Rand for int { - static fn rand(rng: @rand::Rng) -> int { + fn rand(rng: @rand::Rng) -> int { rng.gen_int() } } impl Rand for i8 { - static fn rand(rng: @rand::Rng) -> i8 { + fn rand(rng: @rand::Rng) -> i8 { rng.gen_i8() } } impl Rand for i16 { - static fn rand(rng: @rand::Rng) -> i16 { + fn rand(rng: @rand::Rng) -> i16 { rng.gen_i16() } } impl Rand for i32 { - static fn rand(rng: @rand::Rng) -> i32 { + fn rand(rng: @rand::Rng) -> i32 { rng.gen_i32() } } impl Rand for i64 { - static fn rand(rng: @rand::Rng) -> i64 { + fn rand(rng: @rand::Rng) -> i64 { rng.gen_i64() } } impl Rand for u8 { - static fn rand(rng: @rand::Rng) -> u8 { + fn rand(rng: @rand::Rng) -> u8 { rng.gen_u8() } } impl Rand for u16 { - static fn rand(rng: @rand::Rng) -> u16 { + fn rand(rng: @rand::Rng) -> u16 { rng.gen_u16() } } impl Rand for u32 { - static fn rand(rng: @rand::Rng) -> u32 { + fn rand(rng: @rand::Rng) -> u32 { rng.gen_u32() } } impl Rand for u64 { - static fn rand(rng: @rand::Rng) -> u64 { + fn rand(rng: @rand::Rng) -> u64 { rng.gen_u64() } } impl Rand for float { - static fn rand(rng: @rand::Rng) -> float { + fn rand(rng: @rand::Rng) -> float { rng.gen_float() } } impl Rand for f32 { - static fn rand(rng: @rand::Rng) -> f32 { + fn rand(rng: @rand::Rng) -> f32 { rng.gen_f32() } } impl Rand for f64 { - static fn rand(rng: @rand::Rng) -> f64 { + fn rand(rng: @rand::Rng) -> f64 { rng.gen_f64() } } impl Rand for char { - static fn rand(rng: @rand::Rng) -> char { + fn rand(rng: @rand::Rng) -> char { rng.gen_char() } } impl Rand for bool { - static fn rand(rng: @rand::Rng) -> bool { + fn rand(rng: @rand::Rng) -> bool { rng.gen_bool() } } impl Rand for Option { - static fn rand(rng: @rand::Rng) -> Option { + fn rand(rng: @rand::Rng) -> Option { if rng.gen_bool() { Some(Rand::rand(rng)) } else { @@ -313,7 +313,7 @@ impl RngUtil for @Rng { let u1 = self.next() as f64; let u2 = self.next() as f64; let u3 = self.next() as f64; - const scale : f64 = (u32::max_value as f64) + 1.0f64; + static scale : f64 = (u32::max_value as f64) + 1.0f64; return ((u1 / scale + u2) / scale + u3) / scale; } @@ -527,12 +527,12 @@ impl Rng for XorShiftState { } } -pub pure fn xorshift() -> @Rng { +pub fn xorshift() -> @Rng { // constants taken from http://en.wikipedia.org/wiki/Xorshift seeded_xorshift(123456789u32, 362436069u32, 521288629u32, 88675123u32) } -pub pure 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 { @XorShiftState { x: x, y: y, z: z, w: w } as @Rng } diff --git a/src/libcore/repr.rs b/src/libcore/repr.rs index 83df9b7c00fc3..39cc986f77252 100644 --- a/src/libcore/repr.rs +++ b/src/libcore/repr.rs @@ -24,7 +24,6 @@ use managed; use ptr; use reflect; use reflect::{MovePtr, MovePtrAdaptor, align}; -use str; use sys; use to_str::ToStr; use vec::UnboxedVecRepr; @@ -218,7 +217,7 @@ pub impl ReprVisitor { fn write_escaped_slice(&self, slice: &str) { self.writer.write_char('"'); - for str::chars_each(slice) |ch| { + for slice.each_char |ch| { self.writer.write_escaped_char(ch); } self.writer.write_char('"'); @@ -242,7 +241,7 @@ pub impl ReprVisitor { let (sz, al) = unsafe { ((*inner).size, (*inner).align) }; self.writer.write_char('['); let mut first = true; - while p as uint < end as uint { + while (p as uint) < (end as uint) { if first { first = false; } else { diff --git a/src/libcore/result.rs b/src/libcore/result.rs index 832071a0ba81b..0df9f78a3d6d7 100644 --- a/src/libcore/result.rs +++ b/src/libcore/result.rs @@ -20,7 +20,7 @@ use option::{None, Option, Some}; use vec; /// The result type -#[deriving_eq] +#[deriving(Clone, Eq)] pub enum Result { /// Contains the successful result value Ok(T), @@ -36,7 +36,7 @@ pub enum Result { * If the result is an error */ #[inline(always)] -pub pure fn get(res: &Result) -> T { +pub fn get(res: &Result) -> T { match *res { Ok(copy t) => t, Err(ref the_err) => unsafe { @@ -53,7 +53,7 @@ pub pure fn get(res: &Result) -> T { * If the result is an error */ #[inline(always)] -pub pure fn get_ref(res: &'a Result) -> &'a T { +pub fn get_ref(res: &'a Result) -> &'a T { match *res { Ok(ref t) => t, Err(ref the_err) => unsafe { @@ -70,7 +70,7 @@ pub pure fn get_ref(res: &'a Result) -> &'a T { * If the result is not an error */ #[inline(always)] -pub pure fn get_err(res: &Result) -> U { +pub fn get_err(res: &Result) -> U { match *res { Err(copy u) => u, Ok(_) => fail!(~"get_err called on ok result") @@ -79,7 +79,7 @@ pub pure fn get_err(res: &Result) -> U { /// Returns true if the result is `ok` #[inline(always)] -pub pure fn is_ok(res: &Result) -> bool { +pub fn is_ok(res: &Result) -> bool { match *res { Ok(_) => true, Err(_) => false @@ -88,7 +88,7 @@ pub pure fn is_ok(res: &Result) -> bool { /// Returns true if the result is `err` #[inline(always)] -pub pure fn is_err(res: &Result) -> bool { +pub fn is_err(res: &Result) -> bool { !is_ok(res) } @@ -99,7 +99,7 @@ pub pure fn is_err(res: &Result) -> bool { * result variants are converted to `either::left`. */ #[inline(always)] -pub pure fn to_either(res: &Result) +pub fn to_either(res: &Result) -> Either { match *res { Ok(copy res) => either::Right(res), @@ -122,7 +122,7 @@ pub pure fn to_either(res: &Result) * } */ #[inline(always)] -pub pure fn chain(res: Result, op: &fn(T) +pub fn chain(res: Result, op: &fn(T) -> Result) -> Result { match res { Ok(t) => op(t), @@ -139,7 +139,7 @@ pub pure fn chain(res: Result, op: &fn(T) * successful result while handling an error. */ #[inline(always)] -pub pure fn chain_err( +pub fn chain_err( res: Result, op: &fn(t: V) -> Result) -> Result { @@ -164,7 +164,7 @@ pub pure fn chain_err( * } */ #[inline(always)] -pub pure fn iter(res: &Result, f: &fn(&T)) { +pub fn iter(res: &Result, f: &fn(&T)) { match *res { Ok(ref t) => f(t), Err(_) => () @@ -180,7 +180,7 @@ pub pure fn iter(res: &Result, f: &fn(&T)) { * handling an error. */ #[inline(always)] -pub pure fn iter_err(res: &Result, f: &fn(&E)) { +pub fn iter_err(res: &Result, f: &fn(&E)) { match *res { Ok(_) => (), Err(ref e) => f(e) @@ -202,7 +202,7 @@ pub pure fn iter_err(res: &Result, f: &fn(&E)) { * } */ #[inline(always)] -pub pure fn map(res: &Result, op: &fn(&T) -> U) +pub fn map(res: &Result, op: &fn(&T) -> U) -> Result { match *res { Ok(ref t) => Ok(op(t)), @@ -219,7 +219,7 @@ pub pure fn map(res: &Result, op: &fn(&T) -> U) * successful result while handling an error. */ #[inline(always)] -pub pure fn map_err(res: &Result, op: &fn(&E) -> F) +pub fn map_err(res: &Result, op: &fn(&E) -> F) -> Result { match *res { Ok(copy t) => Ok(t), @@ -229,53 +229,53 @@ pub pure fn map_err(res: &Result, op: &fn(&E) -> F) pub impl Result { #[inline(always)] - pure fn get_ref(&self) -> &'self T { get_ref(self) } + fn get_ref(&self) -> &'self T { get_ref(self) } #[inline(always)] - pure fn is_ok(&self) -> bool { is_ok(self) } + fn is_ok(&self) -> bool { is_ok(self) } #[inline(always)] - pure fn is_err(&self) -> bool { is_err(self) } + fn is_err(&self) -> bool { is_err(self) } #[inline(always)] - pure fn iter(&self, f: &fn(&T)) { iter(self, f) } + fn iter(&self, f: &fn(&T)) { iter(self, f) } #[inline(always)] - pure fn iter_err(&self, f: &fn(&E)) { iter_err(self, f) } + fn iter_err(&self, f: &fn(&E)) { iter_err(self, f) } #[inline(always)] - pure fn unwrap(self) -> T { unwrap(self) } + fn unwrap(self) -> T { unwrap(self) } #[inline(always)] - pure fn unwrap_err(self) -> E { unwrap_err(self) } + fn unwrap_err(self) -> E { unwrap_err(self) } #[inline(always)] - pure fn chain(self, op: &fn(T) -> Result) -> Result { + fn chain(self, op: &fn(T) -> Result) -> Result { chain(self, op) } #[inline(always)] - pure fn chain_err(self, op: &fn(E) -> Result) -> Result { + fn chain_err(self, op: &fn(E) -> Result) -> Result { chain_err(self, op) } } pub impl Result { #[inline(always)] - pure fn get(&self) -> T { get(self) } + fn get(&self) -> T { get(self) } #[inline(always)] - pure fn map_err(&self, op: &fn(&E) -> F) -> Result { + fn map_err(&self, op: &fn(&E) -> F) -> Result { map_err(self, op) } } pub impl Result { #[inline(always)] - pure fn get_err(&self) -> E { get_err(self) } + fn get_err(&self) -> E { get_err(self) } #[inline(always)] - pure fn map(&self, op: &fn(&T) -> U) -> Result { + fn map(&self, op: &fn(&T) -> U) -> Result { map(self, op) } } @@ -375,7 +375,7 @@ pub fn iter_vec2(ss: &[S], ts: &[T], /// Unwraps a result, assuming it is an `ok(T)` #[inline(always)] -pub pure fn unwrap(res: Result) -> T { +pub fn unwrap(res: Result) -> T { match res { Ok(t) => t, Err(_) => fail!(~"unwrap called on an err result") @@ -384,7 +384,7 @@ pub pure fn unwrap(res: Result) -> T { /// Unwraps a result, assuming it is an `err(U)` #[inline(always)] -pub pure fn unwrap_err(res: Result) -> U { +pub fn unwrap_err(res: Result) -> U { match res { Err(u) => u, Ok(_) => fail!(~"unwrap called on an ok result") diff --git a/src/libcore/rt/context.rs b/src/libcore/rt/context.rs index dfb7bdf04c3bd..527acd4d1b1ba 100644 --- a/src/libcore/rt/context.rs +++ b/src/libcore/rt/context.rs @@ -8,6 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +use option::*; use super::stack::StackSegment; use libc::c_void; use cast::{transmute, transmute_mut_unsafe, @@ -16,17 +17,30 @@ use cast::{transmute, transmute_mut_unsafe, // XXX: Registers is boxed so that it is 16-byte aligned, for storing // SSE regs. It would be marginally better not to do this. In C++ we // use an attribute on a struct. -pub struct Context(~Registers); +// XXX: It would be nice to define regs as `~Option` since +// the registers are sometimes empty, but the discriminant would +// then misalign the regs again. +pub struct Context { + /// The context entry point, saved here for later destruction + start: Option<~~fn()>, + /// Hold the registers while the task or scheduler is suspended + regs: ~Registers +} pub impl Context { - static fn empty() -> Context { - Context(new_regs()) + fn empty() -> Context { + Context { + start: None, + regs: new_regs() + } } /// Create a new context that will resume execution by running ~fn() - /// # Safety Note - /// The `start` closure must remain valid for the life of the Task - static fn new(start: &~fn(), stack: &mut StackSegment) -> Context { + fn new(start: ~fn(), stack: &mut StackSegment) -> Context { + // XXX: Putting main into a ~ so it's a thin pointer and can + // be passed to the spawn function. Another unfortunate + // allocation + let start = ~start; // The C-ABI function that is the task entry point extern fn task_start_wrapper(f: &~fn()) { (*f)() } @@ -40,21 +54,29 @@ pub impl Context { // which we will then modify to call the given function when restored let mut regs = new_regs(); unsafe { - swap_registers(transmute_mut_region(&mut *regs), - transmute_region(&*regs)) + swap_registers(transmute_mut_region(&mut *regs), transmute_region(&*regs)) }; initialize_call_frame(&mut *regs, fp, argp, sp); - return Context(regs); + return Context { + start: Some(start), + regs: regs + } } - static fn swap(out_context: &mut Context, in_context: &Context) { + /* Switch contexts + + Suspend the current execution context and resume another by + saving the registers values of the executing thread to a Context + then loading the registers from a previously saved Context. + */ + fn swap(out_context: &mut Context, in_context: &Context) { let out_regs: &mut Registers = match out_context { - &Context(~ref mut r) => r + &Context { regs: ~ref mut r, _ } => r }; let in_regs: &Registers = match in_context { - &Context(~ref r) => r + &Context { regs: ~ref r, _ } => r }; unsafe { swap_registers(out_regs, in_regs) }; @@ -84,11 +106,10 @@ fn new_regs() -> ~Registers { } #[cfg(target_arch = "x86")] -fn initialize_call_frame(regs: &mut Registers, - fptr: *c_void, arg: *c_void, sp: *mut uint) { +fn initialize_call_frame(regs: &mut Registers, fptr: *c_void, arg: *c_void, sp: *mut uint) { let sp = align_down(sp); - let sp = mut_offset(sp, -4); // XXX: -4 words? Needs this be done at all? + let sp = mut_offset(sp, -4); unsafe { *sp = arg as uint; } let sp = mut_offset(sp, -1); @@ -108,14 +129,13 @@ type Registers = [uint * 22]; fn new_regs() -> ~Registers { ~[0, .. 22] } #[cfg(target_arch = "x86_64")] -fn initialize_call_frame(regs: &mut Registers, - fptr: *c_void, arg: *c_void, sp: *mut uint) { +fn initialize_call_frame(regs: &mut Registers, fptr: *c_void, arg: *c_void, sp: *mut uint) { // Redefinitions from regs.h - const RUSTRT_ARG0: uint = 3; - const RUSTRT_RSP: uint = 1; - const RUSTRT_IP: uint = 8; - const RUSTRT_RBP: uint = 2; + static RUSTRT_ARG0: uint = 3; + static RUSTRT_RSP: uint = 1; + static RUSTRT_IP: uint = 8; + static RUSTRT_RBP: uint = 2; let sp = align_down(sp); let sp = mut_offset(sp, -1); @@ -143,8 +163,7 @@ type Registers = [uint * 32]; fn new_regs() -> ~Registers { ~[0, .. 32] } #[cfg(target_arch = "arm")] -fn initialize_call_frame(regs: &mut Registers, - fptr: *c_void, arg: *c_void, sp: *mut uint) { +fn initialize_call_frame(regs: &mut Registers, fptr: *c_void, arg: *c_void, sp: *mut uint) { let sp = mut_offset(sp, -1); // The final return address. 0 indicates the bottom of the stack @@ -162,8 +181,7 @@ type Registers = [uint * 32]; fn new_regs() -> ~Registers { ~[0, .. 32] } #[cfg(target_arch = "mips")] -fn initialize_call_frame(regs: &mut Registers, - fptr: *c_void, arg: *c_void, sp: *mut uint) { +fn initialize_call_frame(regs: &mut Registers, fptr: *c_void, arg: *c_void, sp: *mut uint) { let sp = mut_offset(sp, -1); // The final return address. 0 indicates the bottom of the stack @@ -184,7 +202,7 @@ fn align_down(sp: *mut uint) -> *mut uint { // XXX: ptr::offset is positive ints only #[inline(always)] -pub pure fn mut_offset(ptr: *mut T, count: int) -> *mut T { +pub fn mut_offset(ptr: *mut T, count: int) -> *mut T { use core::sys::size_of; unsafe { (ptr as int + count * (size_of::() as int)) as *mut T diff --git a/src/libcore/rt/io/file.rs b/src/libcore/rt/io/file.rs new file mode 100644 index 0000000000000..9f1f200d8e466 --- /dev/null +++ b/src/libcore/rt/io/file.rs @@ -0,0 +1,45 @@ +// Copyright 2013 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +use prelude::*; +use super::super::sched::*; +use super::super::rtio::*; +use super::Stream; + +pub struct FileStream; + +pub impl FileStream { + fn new(_path: Path) -> FileStream { + fail!() + } +} + +impl Stream for FileStream { + fn read(&mut self, _buf: &mut [u8]) -> uint { + fail!() + } + + fn eof(&mut self) -> bool { + fail!() + } + + fn write(&mut self, _v: &const [u8]) { + fail!() + } +} + +#[test] +#[ignore] +fn super_simple_smoke_test_lets_go_read_some_files_and_have_a_good_time() { + let message = "it's alright. have a good time"; + let filename = Path("test.txt"); + let mut outstream = FileStream::new(filename); + outstream.write(message.to_bytes()); +} diff --git a/src/libcore/rt/io/mod.rs b/src/libcore/rt/io/mod.rs new file mode 100644 index 0000000000000..f82092b829c9b --- /dev/null +++ b/src/libcore/rt/io/mod.rs @@ -0,0 +1,45 @@ +// Copyright 2013 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +use option::*; +use comm::{GenericPort, GenericChan}; + +pub mod file; + +// FIXME #5370 Strongly want this to be StreamError(&mut Stream) +pub struct StreamError; + +// XXX: Can't put doc comments on macros +// Raised by `Stream` instances on error. Returning `true` from the handler +// indicates that the `Stream` should continue, `false` that it should fail. +condition! { + stream_error: super::StreamError -> bool; +} + +pub trait Stream { + /// Read bytes, up to the length of `buf` and place them in `buf`, + /// returning the number of bytes read or an `IoError`. Reads + /// 0 bytes on EOF. + /// + /// # Failure + /// + /// Raises the `reader_error` condition on error + fn read(&mut self, buf: &mut [u8]) -> uint; + + /// Return whether the Reader has reached the end of the stream + fn eof(&mut self) -> bool; + + /// Write the given buffer + /// + /// # Failure + /// + /// Raises the `writer_error` condition on error + fn write(&mut self, v: &const [u8]); +} diff --git a/src/libcore/rt/mod.rs b/src/libcore/rt/mod.rs index a1a9884aeca2c..04891a1673c0a 100644 --- a/src/libcore/rt/mod.rs +++ b/src/libcore/rt/mod.rs @@ -8,6 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +use libc::c_char; // Some basic logging macro_rules! rtdebug_ ( @@ -15,16 +16,10 @@ macro_rules! rtdebug_ ( dumb_println(fmt!( $($arg),+ )); fn dumb_println(s: &str) { - use str::as_c_str; - use libc::c_char; - - extern { - fn printf(s: *c_char); - } - - do as_c_str(s.to_str() + "\n") |s| { - unsafe { printf(s); } - } + use io::WriterUtil; + let dbg = ::libc::STDERR_FILENO as ::io::fd_t; + dbg.write_str(s); + dbg.write_str("\n"); } } ) @@ -36,9 +31,13 @@ macro_rules! rtdebug ( ) mod sched; -mod io; +mod rtio; +pub mod uvll; mod uvio; +#[path = "uv/mod.rs"] mod uv; +#[path = "io/mod.rs"] +mod io; // FIXME #5248: The import in `sched` doesn't resolve unless this is pub! pub mod thread_local_storage; mod work_queue; @@ -46,3 +45,23 @@ mod stack; mod context; mod thread; pub mod env; + +pub fn start(main: *u8, _argc: int, _argv: *c_char, _crate_map: *u8) -> int { + use self::sched::{Scheduler, Task}; + use self::uvio::UvEventLoop; + + let loop_ = ~UvEventLoop::new(); + let mut sched = ~Scheduler::new(loop_); + let main_task = ~do Task::new(&mut sched.stack_pool) { + // XXX: Can't call a C function pointer from Rust yet + unsafe { rust_call_nullary_fn(main) }; + }; + sched.task_queue.push_back(main_task); + sched.run(); + return 0; + + extern { + fn rust_call_nullary_fn(f: *u8); + } +} + diff --git a/src/libcore/rt/io.rs b/src/libcore/rt/rtio.rs similarity index 100% rename from src/libcore/rt/io.rs rename to src/libcore/rt/rtio.rs diff --git a/src/libcore/rt/sched.rs b/src/libcore/rt/sched.rs index 60dbc8b82da11..5034ffa3c6045 100644 --- a/src/libcore/rt/sched.rs +++ b/src/libcore/rt/sched.rs @@ -16,7 +16,7 @@ use ptr::mut_null; use super::work_queue::WorkQueue; use super::stack::{StackPool, StackSegment}; -use super::io::{EventLoop, EventLoopObject}; +use super::rtio::{EventLoop, EventLoopObject}; use super::context::Context; use tls = super::thread_local_storage; @@ -50,11 +50,11 @@ pub struct Scheduler { // complaining type UnsafeTaskReceiver = sys::Closure; trait HackAroundBorrowCk { - static fn from_fn(&fn(&mut Scheduler, ~Task)) -> Self; + fn from_fn(&fn(&mut Scheduler, ~Task)) -> Self; fn to_fn(self) -> &fn(&mut Scheduler, ~Task); } impl HackAroundBorrowCk for UnsafeTaskReceiver { - static fn from_fn(f: &fn(&mut Scheduler, ~Task)) -> UnsafeTaskReceiver { + fn from_fn(f: &fn(&mut Scheduler, ~Task)) -> UnsafeTaskReceiver { unsafe { transmute(f) } } fn to_fn(self) -> &fn(&mut Scheduler, ~Task) { @@ -70,7 +70,14 @@ enum CleanupJob { pub impl Scheduler { - static pub fn new(event_loop: ~EventLoopObject) -> Scheduler { + fn new(event_loop: ~EventLoopObject) -> Scheduler { + + // Lazily initialize the global state, currently the scheduler TLS key + unsafe { rust_initialize_global_state(); } + extern { + fn rust_initialize_global_state(); + } + Scheduler { event_loop: event_loop, task_queue: WorkQueue::new(), @@ -114,7 +121,7 @@ pub impl Scheduler { return tlsched.take_scheduler(); } - static fn local(f: &fn(&mut Scheduler)) { + fn local(f: &fn(&mut Scheduler)) { let mut tlsched = ThreadLocalScheduler::new(); f(tlsched.get_scheduler()); } @@ -183,8 +190,7 @@ pub impl Scheduler { let blocked_task = self.current_task.swap_unwrap(); let f_fake_region = unsafe { - transmute::<&fn(&mut Scheduler, ~Task), - &fn(&mut Scheduler, ~Task)>(f) + transmute::<&fn(&mut Scheduler, ~Task), &fn(&mut Scheduler, ~Task)>(f) }; let f_opaque = HackAroundBorrowCk::from_fn(f_fake_region); self.enqueue_cleanup_job(GiveTask(blocked_task, f_opaque)); @@ -233,8 +239,7 @@ pub impl Scheduler { Context::swap(task_context, scheduler_context); } - priv fn swap_in_task_from_running_task(&mut self, - running_task: &mut Task) { + priv fn swap_in_task_from_running_task(&mut self, running_task: &mut Task) { let running_task_context = &mut running_task.saved_context; let next_context = &self.current_task.get_ref().saved_context; Context::swap(running_task_context, next_context); @@ -282,11 +287,9 @@ pub impl Scheduler { } } -const TASK_MIN_STACK_SIZE: uint = 10000000; // XXX: Too much stack +static TASK_MIN_STACK_SIZE: uint = 10000000; // XXX: Too much stack pub struct Task { - /// The task entry point, saved here for later destruction - priv start: ~~fn(), /// The segment of stack on which the task is currently running or, /// if the task is blocked, on which the task will resume execution priv current_stack_segment: StackSegment, @@ -295,23 +298,19 @@ pub struct Task { priv saved_context: Context, } -impl Task { - static pub fn new(stack_pool: &mut StackPool, start: ~fn()) -> Task { - // XXX: Putting main into a ~ so it's a thin pointer and can - // be passed to the spawn function. Another unfortunate - // allocation - let start = ~Task::build_start_wrapper(start); +pub impl Task { + fn new(stack_pool: &mut StackPool, start: ~fn()) -> Task { + let start = Task::build_start_wrapper(start); let mut stack = stack_pool.take_segment(TASK_MIN_STACK_SIZE); // NB: Context holds a pointer to that ~fn - let initial_context = Context::new(&*start, &mut stack); + let initial_context = Context::new(start, &mut stack); return Task { - start: start, current_stack_segment: stack, saved_context: initial_context, }; } - static priv fn build_start_wrapper(start: ~fn()) -> ~fn() { + priv fn build_start_wrapper(start: ~fn()) -> ~fn() { // XXX: The old code didn't have this extra allocation let wrapper: ~fn() = || { start(); @@ -337,7 +336,7 @@ impl Task { struct ThreadLocalScheduler(tls::Key); impl ThreadLocalScheduler { - static fn new() -> ThreadLocalScheduler { + fn new() -> ThreadLocalScheduler { unsafe { // NB: This assumes that the TLS key has been created prior. // Currently done in rust_start. @@ -350,8 +349,7 @@ impl ThreadLocalScheduler { fn put_scheduler(&mut self, scheduler: ~Scheduler) { unsafe { let key = match self { &ThreadLocalScheduler(key) => key }; - let value: *mut c_void = - transmute::<~Scheduler, *mut c_void>(scheduler); + let value: *mut c_void = transmute::<~Scheduler, *mut c_void>(scheduler); tls::set(key, value); } } @@ -363,8 +361,9 @@ impl ThreadLocalScheduler { fail_unless!(value.is_not_null()); { let value_ptr = &mut value; - let sched: &mut ~Scheduler = - transmute::<&mut *mut c_void, &mut ~Scheduler>(value_ptr); + let sched: &mut ~Scheduler = { + transmute::<&mut *mut c_void, &mut ~Scheduler>(value_ptr) + }; let sched: &mut Scheduler = &mut **sched; return sched; } @@ -481,7 +480,7 @@ fn test_swap_tasks() { #[bench] #[test] #[ignore(reason = "long test")] fn test_run_a_lot_of_tasks_queued() { do run_in_bare_thread { - const MAX: int = 1000000; + static MAX: int = 1000000; let mut count = 0; let count_ptr: *mut int = &mut count; @@ -514,7 +513,7 @@ fn test_run_a_lot_of_tasks_queued() { #[bench] #[test] #[ignore(reason = "too much stack allocation")] fn test_run_a_lot_of_tasks_direct() { do run_in_bare_thread { - const MAX: int = 100000; + static MAX: int = 100000; let mut count = 0; let count_ptr: *mut int = &mut count; diff --git a/src/libcore/rt/stack.rs b/src/libcore/rt/stack.rs index b5e7d4f3aa215..9eca3bda0473c 100644 --- a/src/libcore/rt/stack.rs +++ b/src/libcore/rt/stack.rs @@ -15,7 +15,7 @@ pub struct StackSegment { } pub impl StackSegment { - static fn new(size: uint) -> StackSegment { + fn new(size: uint) -> StackSegment { // Crate a block of uninitialized values let mut stack = vec::with_capacity(size); unsafe { @@ -27,6 +27,7 @@ pub impl StackSegment { } } + /// Point one word beyond the high end of the allocated stack fn end(&self) -> *uint { unsafe { vec::raw::to_ptr(self.buf).offset(self.buf.len()) as *uint @@ -37,7 +38,7 @@ pub impl StackSegment { pub struct StackPool(()); impl StackPool { - static pub fn new() -> StackPool { StackPool(()) } + pub fn new() -> StackPool { StackPool(()) } fn take_segment(&self, min_size: uint) -> StackSegment { StackSegment::new(min_size) diff --git a/src/libcore/rt/thread.rs b/src/libcore/rt/thread.rs index 5dccf90096e02..910e445f47b04 100644 --- a/src/libcore/rt/thread.rs +++ b/src/libcore/rt/thread.rs @@ -14,13 +14,13 @@ use ops::Drop; #[allow(non_camel_case_types)] // runtime type type raw_thread = libc::c_void; -struct Thread { +pub struct Thread { main: ~fn(), raw_thread: *raw_thread } -impl Thread { - static pub fn start(main: ~fn()) -> Thread { +pub impl Thread { + fn start(main: ~fn()) -> Thread { fn substart(main: &fn()) -> *raw_thread { unsafe { rust_raw_thread_start(&main) } } diff --git a/src/libcore/rt/thread_local_storage.rs b/src/libcore/rt/thread_local_storage.rs index e10551b6b893b..5af8c79fd635c 100644 --- a/src/libcore/rt/thread_local_storage.rs +++ b/src/libcore/rt/thread_local_storage.rs @@ -56,7 +56,7 @@ pub type Key = DWORD; #[cfg(windows)] pub unsafe fn create(key: &mut Key) { - const TLS_OUT_OF_INDEXES: DWORD = 0xFFFFFFFF; + static TLS_OUT_OF_INDEXES: DWORD = 0xFFFFFFFF; *key = unsafe { TlsAlloc() }; fail_unless!(*key != TLS_OUT_OF_INDEXES); } diff --git a/src/libcore/rt/uv.rs b/src/libcore/rt/uv.rs deleted file mode 100644 index 80224fa523a9e..0000000000000 --- a/src/libcore/rt/uv.rs +++ /dev/null @@ -1,919 +0,0 @@ -// Copyright 2013 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -/*! - -Bindings to libuv. - -UV types consist of the event loop (Loop), Watchers, Requests and -Callbacks. - -Watchers and Requests encapsulate pointers to uv *handles*, which have -subtyping relationships with each other. This subtyping is reflected -in the bindings with explicit or implicit coercions. For example, an -upcast from TcpWatcher to StreamWatcher is done with -`tcp_watcher.as_stream()`. In other cases a callback on a specific -type of watcher will be passed a watcher of a supertype. - -Currently all use of Request types (connect/write requests) are -encapsulated in the bindings and don't need to be dealt with by the -caller. - -# Safety note - -Due to the complex lifecycle of uv handles, as well as compiler bugs, -this module is not memory safe and requires explicit memory management, -via `close` and `delete` methods. - -*/ - -use option::*; -use str::raw::from_c_str; -use to_str::ToStr; -use vec; -use ptr; -use libc::{c_void, c_int, size_t, malloc, free, ssize_t}; -use cast::{transmute, transmute_mut_region}; -use ptr::null; -use sys::size_of; -use unstable::uvll; -use super::io::{IpAddr, Ipv4, Ipv6}; - -#[cfg(test)] use unstable::run_in_bare_thread; -#[cfg(test)] use super::thread::Thread; -#[cfg(test)] use cell::Cell; - -fn ip4_to_uv_ip4(addr: IpAddr) -> uvll::sockaddr_in { - match addr { - Ipv4(a, b, c, d, p) => { - unsafe { - uvll::ip4_addr(fmt!("%u.%u.%u.%u", - a as uint, - b as uint, - c as uint, - d as uint), p as int) - } - } - Ipv6 => fail!() - } -} - -/// A trait for callbacks to implement. Provides a little extra type safety -/// for generic, unsafe interop functions like `set_watcher_callback`. -trait Callback { } - -type NullCallback = ~fn(); -impl Callback for NullCallback { } - -/// A type that wraps a native handle -trait NativeHandle { - static pub fn from_native_handle(T) -> Self; - pub fn native_handle(&self) -> T; -} - -/// XXX: Loop(*handle) is buggy with destructors. Normal structs -/// with dtors may not be destructured, but tuple structs can, -/// but the results are not correct. -pub struct Loop { - handle: *uvll::uv_loop_t -} - -pub impl Loop { - static fn new() -> Loop { - let handle = unsafe { uvll::loop_new() }; - fail_unless!(handle.is_not_null()); - NativeHandle::from_native_handle(handle) - } - - fn run(&mut self) { - unsafe { uvll::run(self.native_handle()) }; - } - - fn close(&mut self) { - unsafe { uvll::loop_delete(self.native_handle()) }; - } -} - -impl NativeHandle<*uvll::uv_loop_t> for Loop { - static fn from_native_handle(handle: *uvll::uv_loop_t) -> Loop { - Loop { handle: handle } - } - fn native_handle(&self) -> *uvll::uv_loop_t { - self.handle - } -} - -/// The trait implemented by uv 'watchers' (handles). Watchers are -/// non-owning wrappers around the uv handles and are not completely -/// safe - there may be multiple instances for a single underlying -/// handle. Watchers are generally created, then `start`ed, `stop`ed -/// and `close`ed, but due to their complex life cycle may not be -/// entirely memory safe if used in unanticipated patterns. -trait Watcher { - fn event_loop(&self) -> Loop; -} - -pub struct IdleWatcher(*uvll::uv_idle_t); - -impl Watcher for IdleWatcher { - fn event_loop(&self) -> Loop { - loop_from_watcher(self) - } -} - -type IdleCallback = ~fn(IdleWatcher, Option); -impl Callback for IdleCallback { } - -pub impl IdleWatcher { - static fn new(loop_: &mut Loop) -> IdleWatcher { - unsafe { - let handle = uvll::idle_new(); - fail_unless!(handle.is_not_null()); - fail_unless!(0 == uvll::idle_init(loop_.native_handle(), handle)); - uvll::set_data_for_uv_handle(handle, null::<()>()); - NativeHandle::from_native_handle(handle) - } - } - - fn start(&mut self, cb: IdleCallback) { - - set_watcher_callback(self, cb); - unsafe { - fail_unless!(0 == uvll::idle_start(self.native_handle(), idle_cb)) - }; - - extern fn idle_cb(handle: *uvll::uv_idle_t, status: c_int) { - let idle_watcher: IdleWatcher = - NativeHandle::from_native_handle(handle); - let cb: &IdleCallback = - borrow_callback_from_watcher(&idle_watcher); - let status = status_to_maybe_uv_error(handle, status); - (*cb)(idle_watcher, status); - } - } - - fn stop(&mut self) { - unsafe { fail_unless!(0 == uvll::idle_stop(self.native_handle())); } - } - - fn close(self) { - unsafe { uvll::close(self.native_handle(), close_cb) }; - - extern fn close_cb(handle: *uvll::uv_idle_t) { - let mut idle_watcher = NativeHandle::from_native_handle(handle); - drop_watcher_callback::(&mut idle_watcher); - unsafe { uvll::idle_delete(handle) }; - } - } -} - -impl NativeHandle<*uvll::uv_idle_t> for IdleWatcher { - static fn from_native_handle(handle: *uvll::uv_idle_t) -> IdleWatcher { - IdleWatcher(handle) - } - fn native_handle(&self) -> *uvll::uv_idle_t { - match self { &IdleWatcher(ptr) => ptr } - } -} - -// uv_stream t is the parent class of uv_tcp_t, uv_pipe_t, uv_tty_t -// and uv_file_t -pub struct StreamWatcher(*uvll::uv_stream_t); - -impl Watcher for StreamWatcher { - fn event_loop(&self) -> Loop { - loop_from_watcher(self) - } -} - -type ReadCallback = ~fn(StreamWatcher, int, Buf, Option); -impl Callback for ReadCallback { } - -// XXX: The uv alloc callback also has a *uv_handle_t arg -pub type AllocCallback = ~fn(uint) -> Buf; -impl Callback for AllocCallback { } - -pub impl StreamWatcher { - - fn read_start(&mut self, alloc: AllocCallback, cb: ReadCallback) { - // XXX: Borrowchk problems - let data = get_watcher_data(unsafe { transmute_mut_region(self) }); - data.alloc_cb = Some(alloc); - data.read_cb = Some(cb); - - let handle = self.native_handle(); - unsafe { uvll::read_start(handle, alloc_cb, read_cb); } - - extern fn alloc_cb(stream: *uvll::uv_stream_t, - suggested_size: size_t) -> Buf { - let mut stream_watcher: StreamWatcher = - NativeHandle::from_native_handle(stream); - let data = get_watcher_data(&mut stream_watcher); - let alloc_cb = data.alloc_cb.get_ref(); - return (*alloc_cb)(suggested_size as uint); - } - - extern fn read_cb(stream: *uvll::uv_stream_t, - nread: ssize_t, ++buf: Buf) { - rtdebug!("buf addr: %x", buf.base as uint); - rtdebug!("buf len: %d", buf.len as int); - let mut stream_watcher: StreamWatcher = - NativeHandle::from_native_handle(stream); - let data = get_watcher_data(&mut stream_watcher); - let cb = data.read_cb.get_ref(); - let status = status_to_maybe_uv_error(stream, nread as c_int); - (*cb)(stream_watcher, nread as int, buf, status); - } - } - - fn read_stop(&mut self) { - // It would be nice to drop the alloc and read callbacks here, - // but read_stop may be called from inside one of them and we - // would end up freeing the in-use environment - let handle = self.native_handle(); - unsafe { uvll::read_stop(handle); } - } - - // XXX: Needs to take &[u8], not ~[u8] - fn write(&mut self, msg: ~[u8], cb: ConnectionCallback) { - // XXX: Borrowck - let data = get_watcher_data(unsafe { transmute_mut_region(self) }); - fail_unless!(data.write_cb.is_none()); - data.write_cb = Some(cb); - - let req = WriteRequest::new(); - let buf = vec_to_uv_buf(msg); - // XXX: Allocation - let bufs = ~[buf]; - unsafe { - fail_unless!(0 == uvll::write(req.native_handle(), - self.native_handle(), - &bufs, write_cb)); - } - // XXX: Freeing immediately after write. Is this ok? - let _v = vec_from_uv_buf(buf); - - extern fn write_cb(req: *uvll::uv_write_t, status: c_int) { - let write_request: WriteRequest = - NativeHandle::from_native_handle(req); - let mut stream_watcher = write_request.stream(); - write_request.delete(); - let cb = get_watcher_data(&mut stream_watcher) - .write_cb.swap_unwrap(); - let status = status_to_maybe_uv_error( - stream_watcher.native_handle(), status); - cb(stream_watcher, status); - } - } - - fn accept(&mut self, stream: StreamWatcher) { - let self_handle = self.native_handle() as *c_void; - let stream_handle = stream.native_handle() as *c_void; - unsafe { - fail_unless!(0 == uvll::accept(self_handle, stream_handle)); - } - } - - fn close(self, cb: NullCallback) { - { - let mut self = self; - let data = get_watcher_data(&mut self); - fail_unless!(data.close_cb.is_none()); - data.close_cb = Some(cb); - } - - unsafe { uvll::close(self.native_handle(), close_cb); } - - extern fn close_cb(handle: *uvll::uv_stream_t) { - let mut stream_watcher: StreamWatcher = - NativeHandle::from_native_handle(handle); - { - let mut data = get_watcher_data(&mut stream_watcher); - data.close_cb.swap_unwrap()(); - } - drop_watcher_data(&mut stream_watcher); - unsafe { free(handle as *c_void) } - } - } -} - -impl NativeHandle<*uvll::uv_stream_t> for StreamWatcher { - static fn from_native_handle( - handle: *uvll::uv_stream_t) -> StreamWatcher { - StreamWatcher(handle) - } - fn native_handle(&self) -> *uvll::uv_stream_t { - match self { &StreamWatcher(ptr) => ptr } - } -} - -pub struct TcpWatcher(*uvll::uv_tcp_t); - -impl Watcher for TcpWatcher { - fn event_loop(&self) -> Loop { - loop_from_watcher(self) - } -} - -type ConnectionCallback = ~fn(StreamWatcher, Option); -impl Callback for ConnectionCallback { } - -pub impl TcpWatcher { - static fn new(loop_: &mut Loop) -> TcpWatcher { - unsafe { - let size = size_of::() as size_t; - let handle = malloc(size) as *uvll::uv_tcp_t; - fail_unless!(handle.is_not_null()); - fail_unless!(0 == uvll::tcp_init(loop_.native_handle(), handle)); - let mut watcher = NativeHandle::from_native_handle(handle); - install_watcher_data(&mut watcher); - return watcher; - } - } - - fn bind(&mut self, address: IpAddr) { - match address { - Ipv4(*) => { - let addr = ip4_to_uv_ip4(address); - let result = unsafe { - uvll::tcp_bind(self.native_handle(), &addr) - }; - // XXX: bind is likely to fail. need real error handling - fail_unless!(result == 0); - } - _ => fail!() - } - } - - fn connect(&mut self, address: IpAddr, cb: ConnectionCallback) { - unsafe { - fail_unless!(get_watcher_data(self).connect_cb.is_none()); - get_watcher_data(self).connect_cb = Some(cb); - - let mut connect_watcher = ConnectRequest::new(); - let connect_handle = connect_watcher.native_handle(); - match address { - Ipv4(*) => { - let addr = ip4_to_uv_ip4(address); - rtdebug!("connect_t: %x", connect_handle as uint); - fail_unless!(0 == uvll::tcp_connect(connect_handle, - self.native_handle(), - &addr, connect_cb)); - } - _ => fail!() - } - - extern fn connect_cb(req: *uvll::uv_connect_t, status: c_int) { - rtdebug!("connect_t: %x", req as uint); - let connect_request: ConnectRequest = - NativeHandle::from_native_handle(req); - let mut stream_watcher = connect_request.stream(); - connect_request.delete(); - let cb: ConnectionCallback = { - let data = get_watcher_data(&mut stream_watcher); - data.connect_cb.swap_unwrap() - }; - let status = status_to_maybe_uv_error( - stream_watcher.native_handle(), status); - cb(stream_watcher, status); - } - } - } - - fn listen(&mut self, cb: ConnectionCallback) { - // XXX: Borrowck - let data = get_watcher_data(unsafe { transmute_mut_region(self) }); - fail_unless!(data.connect_cb.is_none()); - data.connect_cb = Some(cb); - - unsafe { - const BACKLOG: c_int = 128; // XXX should be configurable - // XXX: This can probably fail - fail_unless!(0 == uvll::listen(self.native_handle(), - BACKLOG, connection_cb)); - } - - extern fn connection_cb(handle: *uvll::uv_stream_t, status: c_int) { - rtdebug!("connection_cb"); - let mut stream_watcher: StreamWatcher = - NativeHandle::from_native_handle(handle); - let cb = get_watcher_data(&mut stream_watcher) - .connect_cb.swap_unwrap(); - let status = status_to_maybe_uv_error( - stream_watcher.native_handle(), status); - cb(stream_watcher, status); - } - } - - fn as_stream(&self) -> StreamWatcher { - NativeHandle::from_native_handle( - self.native_handle() as *uvll::uv_stream_t) - } -} - -impl NativeHandle<*uvll::uv_tcp_t> for TcpWatcher { - static fn from_native_handle(handle: *uvll::uv_tcp_t) -> TcpWatcher { - TcpWatcher(handle) - } - fn native_handle(&self) -> *uvll::uv_tcp_t { - match self { &TcpWatcher(ptr) => ptr } - } -} - -trait Request { } - -type ConnectCallback = ~fn(ConnectRequest, Option); -impl Callback for ConnectCallback { } - -// uv_connect_t is a subclass of uv_req_t -struct ConnectRequest(*uvll::uv_connect_t); - -impl Request for ConnectRequest { } - -impl ConnectRequest { - - static fn new() -> ConnectRequest { - let connect_handle = unsafe { - malloc(size_of::() as size_t) - }; - fail_unless!(connect_handle.is_not_null()); - let connect_handle = connect_handle as *uvll::uv_connect_t; - ConnectRequest(connect_handle) - } - - fn stream(&self) -> StreamWatcher { - unsafe { - let stream_handle = - uvll::get_stream_handle_from_connect_req( - self.native_handle()); - NativeHandle::from_native_handle(stream_handle) - } - } - - fn delete(self) { - unsafe { free(self.native_handle() as *c_void) } - } -} - -impl NativeHandle<*uvll::uv_connect_t> for ConnectRequest { - static fn from_native_handle( - handle: *uvll:: uv_connect_t) -> ConnectRequest { - ConnectRequest(handle) - } - fn native_handle(&self) -> *uvll::uv_connect_t { - match self { &ConnectRequest(ptr) => ptr } - } -} - -pub struct WriteRequest(*uvll::uv_write_t); - -impl Request for WriteRequest { } - -impl WriteRequest { - - static fn new() -> WriteRequest { - let write_handle = unsafe { - malloc(size_of::() as size_t) - }; - fail_unless!(write_handle.is_not_null()); - let write_handle = write_handle as *uvll::uv_write_t; - WriteRequest(write_handle) - } - - fn stream(&self) -> StreamWatcher { - unsafe { - let stream_handle = - uvll::get_stream_handle_from_write_req(self.native_handle()); - NativeHandle::from_native_handle(stream_handle) - } - } - - fn delete(self) { - unsafe { free(self.native_handle() as *c_void) } - } -} - -impl NativeHandle<*uvll::uv_write_t> for WriteRequest { - static fn from_native_handle(handle: *uvll:: uv_write_t) -> WriteRequest { - WriteRequest(handle) - } - fn native_handle(&self) -> *uvll::uv_write_t { - match self { &WriteRequest(ptr) => ptr } - } -} - -// XXX: Need to define the error constants like EOF so they can be -// compared to the UvError type - -struct UvError(uvll::uv_err_t); - -impl UvError { - - pure fn name(&self) -> ~str { - unsafe { - let inner = match self { &UvError(ref a) => a }; - let name_str = uvll::err_name(inner); - fail_unless!(name_str.is_not_null()); - from_c_str(name_str) - } - } - - pure fn desc(&self) -> ~str { - unsafe { - let inner = match self { &UvError(ref a) => a }; - let desc_str = uvll::strerror(inner); - fail_unless!(desc_str.is_not_null()); - from_c_str(desc_str) - } - } -} - -impl ToStr for UvError { - pure fn to_str(&self) -> ~str { - fmt!("%s: %s", self.name(), self.desc()) - } -} - -#[test] -fn error_smoke_test() { - let err = uvll::uv_err_t { code: 1, sys_errno_: 1 }; - let err: UvError = UvError(err); - fail_unless!(err.to_str() == ~"EOF: end of file"); -} - - -/// Given a uv handle, convert a callback status to a UvError -// XXX: Follow the pattern below by parameterizing over T: Watcher, not T -fn status_to_maybe_uv_error(handle: *T, status: c_int) -> Option { - if status != -1 { - None - } else { - unsafe { - rtdebug!("handle: %x", handle as uint); - let loop_ = uvll::get_loop_for_uv_handle(handle); - rtdebug!("loop: %x", loop_ as uint); - let err = uvll::last_error(loop_); - Some(UvError(err)) - } - } -} - -/// Get the uv event loop from a Watcher -pub fn loop_from_watcher>( - watcher: &W) -> Loop { - - let handle = watcher.native_handle(); - let loop_ = unsafe { uvll::get_loop_for_uv_handle(handle) }; - NativeHandle::from_native_handle(loop_) -} - -/// Set the custom data on a handle to a callback Note: This is only -/// suitable for watchers that make just one type of callback. For -/// others use WatcherData -fn set_watcher_callback, CB: Callback>( - watcher: &mut W, cb: CB) { - - drop_watcher_callback::(watcher); - // XXX: Boxing the callback so it fits into a - // pointer. Unfortunate extra allocation - let boxed_cb = ~cb; - let data = unsafe { transmute::<~CB, *c_void>(boxed_cb) }; - unsafe { uvll::set_data_for_uv_handle(watcher.native_handle(), data) }; -} - -/// Delete a callback from a handle's custom data -fn drop_watcher_callback, CB: Callback>( - watcher: &mut W) { - - unsafe { - let handle = watcher.native_handle(); - let handle_data: *c_void = uvll::get_data_for_uv_handle(handle); - if handle_data.is_not_null() { - // Take ownership of the callback and drop it - let _cb = transmute::<*c_void, ~CB>(handle_data); - // Make sure the pointer is zeroed - uvll::set_data_for_uv_handle( - watcher.native_handle(), null::<()>()); - } - } -} - -/// Take a pointer to the callback installed as custom data -fn borrow_callback_from_watcher, - CB: Callback>(watcher: &W) -> &CB { - - unsafe { - let handle = watcher.native_handle(); - let handle_data: *c_void = uvll::get_data_for_uv_handle(handle); - fail_unless!(handle_data.is_not_null()); - let cb = transmute::<&*c_void, &~CB>(&handle_data); - return &**cb; - } -} - -/// Take ownership of the callback installed as custom data -fn take_callback_from_watcher, CB: Callback>( - watcher: &mut W) -> CB { - - unsafe { - let handle = watcher.native_handle(); - let handle_data: *c_void = uvll::get_data_for_uv_handle(handle); - fail_unless!(handle_data.is_not_null()); - uvll::set_data_for_uv_handle(handle, null::<()>()); - let cb: ~CB = transmute::<*c_void, ~CB>(handle_data); - let cb = match cb { ~cb => cb }; - return cb; - } -} - -/// Callbacks used by StreamWatchers, set as custom data on the foreign handle -struct WatcherData { - read_cb: Option, - write_cb: Option, - connect_cb: Option, - close_cb: Option, - alloc_cb: Option -} - -fn install_watcher_data>(watcher: &mut W) { - unsafe { - let data = ~WatcherData { - read_cb: None, - write_cb: None, - connect_cb: None, - close_cb: None, - alloc_cb: None - }; - let data = transmute::<~WatcherData, *c_void>(data); - uvll::set_data_for_uv_handle(watcher.native_handle(), data); - } -} - -fn get_watcher_data>( - watcher: &'r mut W) -> &'r mut WatcherData { - - unsafe { - let data = uvll::get_data_for_uv_handle(watcher.native_handle()); - let data = transmute::<&*c_void, &mut ~WatcherData>(&data); - return &mut **data; - } -} - -fn drop_watcher_data>(watcher: &mut W) { - unsafe { - let data = uvll::get_data_for_uv_handle(watcher.native_handle()); - let _data = transmute::<*c_void, ~WatcherData>(data); - uvll::set_data_for_uv_handle(watcher.native_handle(), null::<()>()); - } -} - -#[test] -fn test_slice_to_uv_buf() { - let slice = [0, .. 20]; - let buf = slice_to_uv_buf(slice); - - fail_unless!(buf.len == 20); - - unsafe { - let base = transmute::<*u8, *mut u8>(buf.base); - (*base) = 1; - (*ptr::mut_offset(base, 1)) = 2; - } - - fail_unless!(slice[0] == 1); - fail_unless!(slice[1] == 2); -} - -/// The uv buffer type -pub type Buf = uvll::uv_buf_t; - -/// Borrow a slice to a Buf -pub fn slice_to_uv_buf(v: &[u8]) -> Buf { - let data = unsafe { vec::raw::to_ptr(v) }; - unsafe { uvll::buf_init(data, v.len()) } -} - -// XXX: Do these conversions without copying - -/// Transmute an owned vector to a Buf -fn vec_to_uv_buf(v: ~[u8]) -> Buf { - let data = unsafe { malloc(v.len() as size_t) } as *u8; - fail_unless!(data.is_not_null()); - do vec::as_imm_buf(v) |b, l| { - let data = data as *mut u8; - unsafe { ptr::copy_memory(data, b, l) } - } - let buf = unsafe { uvll::buf_init(data, v.len()) }; - return buf; -} - -/// Transmute a Buf that was once a ~[u8] back to ~[u8] -fn vec_from_uv_buf(buf: Buf) -> Option<~[u8]> { - if !(buf.len == 0 && buf.base.is_null()) { - let v = unsafe { vec::from_buf(buf.base, buf.len as uint) }; - unsafe { free(buf.base as *c_void) }; - return Some(v); - } else { - // No buffer - return None; - } -} - -#[test] -fn loop_smoke_test() { - do run_in_bare_thread { - let mut loop_ = Loop::new(); - loop_.run(); - loop_.close(); - } -} - -#[test] -#[ignore(reason = "valgrind - loop destroyed before watcher?")] -fn idle_new_then_close() { - do run_in_bare_thread { - let mut loop_ = Loop::new(); - let mut idle_watcher = { IdleWatcher::new(&mut loop_) }; - idle_watcher.close(); - } -} - -#[test] -fn idle_smoke_test() { - do run_in_bare_thread { - let mut loop_ = Loop::new(); - let mut idle_watcher = { IdleWatcher::new(&mut loop_) }; - let mut count = 10; - let count_ptr: *mut int = &mut count; - do idle_watcher.start |idle_watcher, status| { - let mut idle_watcher = idle_watcher; - fail_unless!(status.is_none()); - if unsafe { *count_ptr == 10 } { - idle_watcher.stop(); - idle_watcher.close(); - } else { - unsafe { *count_ptr = *count_ptr + 1; } - } - } - loop_.run(); - loop_.close(); - fail_unless!(count == 10); - } -} - -#[test] -fn idle_start_stop_start() { - do run_in_bare_thread { - let mut loop_ = Loop::new(); - let mut idle_watcher = { IdleWatcher::new(&mut loop_) }; - do idle_watcher.start |idle_watcher, status| { - let mut idle_watcher = idle_watcher; - fail_unless!(status.is_none()); - idle_watcher.stop(); - do idle_watcher.start |idle_watcher, status| { - fail_unless!(status.is_none()); - let mut idle_watcher = idle_watcher; - idle_watcher.stop(); - idle_watcher.close(); - } - } - loop_.run(); - loop_.close(); - } -} - -#[test] -#[ignore(reason = "ffi struct issues")] -fn connect_close() { - do run_in_bare_thread() { - let mut loop_ = Loop::new(); - let mut tcp_watcher = { TcpWatcher::new(&mut loop_) }; - // Connect to a port where nobody is listening - let addr = Ipv4(127, 0, 0, 1, 2923); - do tcp_watcher.connect(addr) |stream_watcher, status| { - rtdebug!("tcp_watcher.connect!"); - fail_unless!(status.is_some()); - fail_unless!(status.get().name() == ~"ECONNREFUSED"); - stream_watcher.close(||()); - } - loop_.run(); - loop_.close(); - } -} - -#[test] -#[ignore(reason = "need a server to connect to")] -fn connect_read() { - do run_in_bare_thread() { - let mut loop_ = Loop::new(); - let mut tcp_watcher = { TcpWatcher::new(&mut loop_) }; - let addr = Ipv4(127, 0, 0, 1, 2924); - do tcp_watcher.connect(addr) |stream_watcher, status| { - let mut stream_watcher = stream_watcher; - rtdebug!("tcp_watcher.connect!"); - fail_unless!(status.is_none()); - let alloc: AllocCallback = |size| { - vec_to_uv_buf(vec::from_elem(size, 0)) - }; - do stream_watcher.read_start(alloc) - |stream_watcher, nread, buf, status| { - - let buf = vec_from_uv_buf(buf); - rtdebug!("read cb!"); - if status.is_none() { - let bytes = buf.unwrap(); - rtdebug!("%s", bytes.slice(0, nread as uint).to_str()); - } else { - rtdebug!("status after read: %s", status.get().to_str()); - rtdebug!("closing"); - stream_watcher.close(||()); - } - } - } - loop_.run(); - loop_.close(); - } -} - -#[test] -#[ignore(reason = "ffi struct issues")] -fn listen() { - do run_in_bare_thread() { - const MAX: int = 10; - let mut loop_ = Loop::new(); - let mut server_tcp_watcher = { TcpWatcher::new(&mut loop_) }; - let addr = Ipv4(127, 0, 0, 1, 2925); - server_tcp_watcher.bind(addr); - let loop_ = loop_; - rtdebug!("listening"); - do server_tcp_watcher.listen |server_stream_watcher, status| { - rtdebug!("listened!"); - fail_unless!(status.is_none()); - let mut server_stream_watcher = server_stream_watcher; - let mut loop_ = loop_; - let mut client_tcp_watcher = TcpWatcher::new(&mut loop_); - let mut client_tcp_watcher = client_tcp_watcher.as_stream(); - server_stream_watcher.accept(client_tcp_watcher); - let count_cell = Cell(0); - let server_stream_watcher = server_stream_watcher; - rtdebug!("starting read"); - let alloc: AllocCallback = |size| { - vec_to_uv_buf(vec::from_elem(size, 0)) - }; - do client_tcp_watcher.read_start(alloc) - |stream_watcher, nread, buf, status| { - - rtdebug!("i'm reading!"); - let buf = vec_from_uv_buf(buf); - let mut count = count_cell.take(); - if status.is_none() { - rtdebug!("got %d bytes", nread); - let buf = buf.unwrap(); - for buf.view(0, nread as uint).each |byte| { - fail_unless!(*byte == count as u8); - rtdebug!("%u", *byte as uint); - count += 1; - } - } else { - fail_unless!(count == MAX); - do stream_watcher.close { - server_stream_watcher.close(||()); - } - } - count_cell.put_back(count); - } - } - - let _client_thread = do Thread::start { - rtdebug!("starting client thread"); - let mut loop_ = Loop::new(); - let mut tcp_watcher = { TcpWatcher::new(&mut loop_) }; - do tcp_watcher.connect(addr) |stream_watcher, status| { - rtdebug!("connecting"); - fail_unless!(status.is_none()); - let mut stream_watcher = stream_watcher; - let msg = ~[0, 1, 2, 3, 4, 5, 6 ,7 ,8, 9]; - do stream_watcher.write(msg) |stream_watcher, status| { - rtdebug!("writing"); - fail_unless!(status.is_none()); - stream_watcher.close(||()); - } - } - loop_.run(); - loop_.close(); - }; - - let mut loop_ = loop_; - loop_.run(); - loop_.close(); - } -} diff --git a/src/libcore/rt/uv/file.rs b/src/libcore/rt/uv/file.rs new file mode 100644 index 0000000000000..7df06f87dfe41 --- /dev/null +++ b/src/libcore/rt/uv/file.rs @@ -0,0 +1,52 @@ +// Copyright 2013 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +use prelude::*; +use ptr::null; +use libc::c_void; +use super::{UvError, Callback, Request, NativeHandle, Loop}; +use super::super::uvll; +use super::super::uvll::*; + +pub type FsCallback = ~fn(FsRequest, Option); +impl Callback for FsCallback { } + +pub struct FsRequest(*uvll::uv_fs_t); + +impl Request for FsRequest; + +impl FsRequest { + fn new() -> FsRequest { + let fs_req = unsafe { malloc_req(UV_FS) }; + fail_unless!(fs_req.is_not_null()); + let fs_req = fs_req as *uvll::uv_write_t; + unsafe { uvll::set_data_for_req(fs_req, null::<()>()); } + NativeHandle::from_native_handle(fs_req) + } + + fn delete(self) { + unsafe { free_req(self.native_handle() as *c_void) } + } + + fn open(&mut self, _loop_: &Loop, _cb: FsCallback) { + } + + fn close(&mut self, _loop_: &Loop, _cb: FsCallback) { + } +} + +impl NativeHandle<*uvll::uv_fs_t> for FsRequest { + fn from_native_handle(handle: *uvll:: uv_fs_t) -> FsRequest { + FsRequest(handle) + } + fn native_handle(&self) -> *uvll::uv_fs_t { + match self { &FsRequest(ptr) => ptr } + } +} diff --git a/src/libcore/rt/uv/mod.rs b/src/libcore/rt/uv/mod.rs new file mode 100644 index 0000000000000..28d695273e7c7 --- /dev/null +++ b/src/libcore/rt/uv/mod.rs @@ -0,0 +1,456 @@ +// Copyright 2013 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +/*! + +Bindings to libuv. + +UV types consist of the event loop (Loop), Watchers, Requests and +Callbacks. + +Watchers and Requests encapsulate pointers to uv *handles*, which have +subtyping relationships with each other. This subtyping is reflected +in the bindings with explicit or implicit coercions. For example, an +upcast from TcpWatcher to StreamWatcher is done with +`tcp_watcher.as_stream()`. In other cases a callback on a specific +type of watcher will be passed a watcher of a supertype. + +Currently all use of Request types (connect/write requests) are +encapsulated in the bindings and don't need to be dealt with by the +caller. + +# Safety note + +Due to the complex lifecycle of uv handles, as well as compiler bugs, +this module is not memory safe and requires explicit memory management, +via `close` and `delete` methods. + +*/ + +use option::*; +use str::raw::from_c_str; +use to_str::ToStr; +use vec; +use ptr; +use libc::{c_void, c_int, size_t, malloc, free, ssize_t}; +use cast::{transmute, transmute_mut_region}; +use ptr::null; +use sys::size_of; +use super::uvll; +use super::uvll::*; +use unstable::finally::Finally; + +#[cfg(test)] use unstable::run_in_bare_thread; +#[cfg(test)] use super::thread::Thread; +#[cfg(test)] use cell::Cell; + +pub use self::file::{FsRequest, FsCallback}; +pub use self::net::{StreamWatcher, TcpWatcher}; +pub use self::net::{ReadCallback, AllocCallback, ConnectionCallback, ConnectCallback}; + +pub mod file; +pub mod net; + +/// A trait for callbacks to implement. Provides a little extra type safety +/// for generic, unsafe interop functions like `set_watcher_callback`. +pub trait Callback { } + +pub trait Request { } + +/// The trait implemented by uv 'watchers' (handles). Watchers are +/// non-owning wrappers around the uv handles and are not completely +/// safe - there may be multiple instances for a single underlying +/// handle. Watchers are generally created, then `start`ed, `stop`ed +/// and `close`ed, but due to their complex life cycle may not be +/// entirely memory safe if used in unanticipated patterns. +pub trait Watcher { + fn event_loop(&self) -> Loop; +} + +pub type NullCallback = ~fn(); +impl Callback for NullCallback { } + +/// A type that wraps a native handle +pub trait NativeHandle { + pub fn from_native_handle(T) -> Self; + pub fn native_handle(&self) -> T; +} + +/// XXX: Loop(*handle) is buggy with destructors. Normal structs +/// with dtors may not be destructured, but tuple structs can, +/// but the results are not correct. +pub struct Loop { + handle: *uvll::uv_loop_t +} + +pub impl Loop { + fn new() -> Loop { + let handle = unsafe { uvll::loop_new() }; + fail_unless!(handle.is_not_null()); + NativeHandle::from_native_handle(handle) + } + + fn run(&mut self) { + unsafe { uvll::run(self.native_handle()) }; + } + + fn close(&mut self) { + unsafe { uvll::loop_delete(self.native_handle()) }; + } +} + +impl NativeHandle<*uvll::uv_loop_t> for Loop { + fn from_native_handle(handle: *uvll::uv_loop_t) -> Loop { + Loop { handle: handle } + } + fn native_handle(&self) -> *uvll::uv_loop_t { + self.handle + } +} + +pub struct IdleWatcher(*uvll::uv_idle_t); + +impl Watcher for IdleWatcher { + fn event_loop(&self) -> Loop { + loop_from_watcher(self) + } +} + +pub type IdleCallback = ~fn(IdleWatcher, Option); +impl Callback for IdleCallback { } + +pub impl IdleWatcher { + fn new(loop_: &mut Loop) -> IdleWatcher { + unsafe { + let handle = uvll::idle_new(); + fail_unless!(handle.is_not_null()); + fail_unless!(0 == uvll::idle_init(loop_.native_handle(), handle)); + uvll::set_data_for_uv_handle(handle, null::<()>()); + NativeHandle::from_native_handle(handle) + } + } + + fn start(&mut self, cb: IdleCallback) { + + set_watcher_callback(self, cb); + unsafe { + fail_unless!(0 == uvll::idle_start(self.native_handle(), idle_cb)) + }; + + extern fn idle_cb(handle: *uvll::uv_idle_t, status: c_int) { + let idle_watcher: IdleWatcher = NativeHandle::from_native_handle(handle); + let cb: &IdleCallback = borrow_callback_from_watcher(&idle_watcher); + let status = status_to_maybe_uv_error(handle, status); + (*cb)(idle_watcher, status); + } + } + + fn stop(&mut self) { + unsafe { fail_unless!(0 == uvll::idle_stop(self.native_handle())); } + } + + fn close(self) { + unsafe { uvll::close(self.native_handle(), close_cb) }; + + extern fn close_cb(handle: *uvll::uv_idle_t) { + let mut idle_watcher = NativeHandle::from_native_handle(handle); + drop_watcher_callback::(&mut idle_watcher); + unsafe { uvll::idle_delete(handle) }; + } + } +} + +impl NativeHandle<*uvll::uv_idle_t> for IdleWatcher { + fn from_native_handle(handle: *uvll::uv_idle_t) -> IdleWatcher { + IdleWatcher(handle) + } + fn native_handle(&self) -> *uvll::uv_idle_t { + match self { &IdleWatcher(ptr) => ptr } + } +} + +// XXX: Need to define the error constants like EOF so they can be +// compared to the UvError type + +pub struct UvError(uvll::uv_err_t); + +pub impl UvError { + + fn name(&self) -> ~str { + unsafe { + let inner = match self { &UvError(ref a) => a }; + let name_str = uvll::err_name(inner); + fail_unless!(name_str.is_not_null()); + from_c_str(name_str) + } + } + + fn desc(&self) -> ~str { + unsafe { + let inner = match self { &UvError(ref a) => a }; + let desc_str = uvll::strerror(inner); + fail_unless!(desc_str.is_not_null()); + from_c_str(desc_str) + } + } +} + +impl ToStr for UvError { + fn to_str(&self) -> ~str { + fmt!("%s: %s", self.name(), self.desc()) + } +} + +#[test] +fn error_smoke_test() { + let err = uvll::uv_err_t { code: 1, sys_errno_: 1 }; + let err: UvError = UvError(err); + fail_unless!(err.to_str() == ~"EOF: end of file"); +} + + +/// Given a uv handle, convert a callback status to a UvError +// XXX: Follow the pattern below by parameterizing over T: Watcher, not T +pub fn status_to_maybe_uv_error(handle: *T, status: c_int) -> Option { + if status != -1 { + None + } else { + unsafe { + rtdebug!("handle: %x", handle as uint); + let loop_ = uvll::get_loop_for_uv_handle(handle); + rtdebug!("loop: %x", loop_ as uint); + let err = uvll::last_error(loop_); + Some(UvError(err)) + } + } +} + +/// Get the uv event loop from a Watcher +pub fn loop_from_watcher>( + watcher: &W) -> Loop { + + let handle = watcher.native_handle(); + let loop_ = unsafe { uvll::get_loop_for_uv_handle(handle) }; + NativeHandle::from_native_handle(loop_) +} + +/// Set the custom data on a handle to a callback Note: This is only +/// suitable for watchers that make just one type of callback. For +/// others use WatcherData +pub fn set_watcher_callback, CB: Callback>( + watcher: &mut W, cb: CB) { + + drop_watcher_callback::(watcher); + // XXX: Boxing the callback so it fits into a + // pointer. Unfortunate extra allocation + let boxed_cb = ~cb; + let data = unsafe { transmute::<~CB, *c_void>(boxed_cb) }; + unsafe { uvll::set_data_for_uv_handle(watcher.native_handle(), data) }; +} + +/// Delete a callback from a handle's custom data +pub fn drop_watcher_callback, CB: Callback>( + watcher: &mut W) { + + unsafe { + let handle = watcher.native_handle(); + let handle_data: *c_void = uvll::get_data_for_uv_handle(handle); + if handle_data.is_not_null() { + // Take ownership of the callback and drop it + let _cb = transmute::<*c_void, ~CB>(handle_data); + // Make sure the pointer is zeroed + uvll::set_data_for_uv_handle(watcher.native_handle(), null::<()>()); + } + } +} + +/// Take a pointer to the callback installed as custom data +pub fn borrow_callback_from_watcher, + CB: Callback>(watcher: &W) -> &CB { + + unsafe { + let handle = watcher.native_handle(); + let handle_data: *c_void = uvll::get_data_for_uv_handle(handle); + fail_unless!(handle_data.is_not_null()); + let cb = transmute::<&*c_void, &~CB>(&handle_data); + return &**cb; + } +} + +/// Take ownership of the callback installed as custom data +pub fn take_callback_from_watcher, CB: Callback>( + watcher: &mut W) -> CB { + + unsafe { + let handle = watcher.native_handle(); + let handle_data: *c_void = uvll::get_data_for_uv_handle(handle); + fail_unless!(handle_data.is_not_null()); + uvll::set_data_for_uv_handle(handle, null::<()>()); + let cb: ~CB = transmute::<*c_void, ~CB>(handle_data); + let cb = match cb { ~cb => cb }; + return cb; + } +} + +/// Callbacks used by StreamWatchers, set as custom data on the foreign handle +struct WatcherData { + read_cb: Option, + write_cb: Option, + connect_cb: Option, + close_cb: Option, + alloc_cb: Option +} + +pub fn install_watcher_data>(watcher: &mut W) { + unsafe { + let data = ~WatcherData { + read_cb: None, + write_cb: None, + connect_cb: None, + close_cb: None, + alloc_cb: None + }; + let data = transmute::<~WatcherData, *c_void>(data); + uvll::set_data_for_uv_handle(watcher.native_handle(), data); + } +} + +pub fn get_watcher_data>( + watcher: &'r mut W) -> &'r mut WatcherData { + + unsafe { + let data = uvll::get_data_for_uv_handle(watcher.native_handle()); + let data = transmute::<&*c_void, &mut ~WatcherData>(&data); + return &mut **data; + } +} + +pub fn drop_watcher_data>(watcher: &mut W) { + unsafe { + let data = uvll::get_data_for_uv_handle(watcher.native_handle()); + let _data = transmute::<*c_void, ~WatcherData>(data); + uvll::set_data_for_uv_handle(watcher.native_handle(), null::<()>()); + } +} + +#[test] +fn test_slice_to_uv_buf() { + let slice = [0, .. 20]; + let buf = slice_to_uv_buf(slice); + + fail_unless!(buf.len == 20); + + unsafe { + let base = transmute::<*u8, *mut u8>(buf.base); + (*base) = 1; + (*ptr::mut_offset(base, 1)) = 2; + } + + fail_unless!(slice[0] == 1); + fail_unless!(slice[1] == 2); +} + +/// The uv buffer type +pub type Buf = uvll::uv_buf_t; + +/// Borrow a slice to a Buf +pub fn slice_to_uv_buf(v: &[u8]) -> Buf { + let data = unsafe { vec::raw::to_ptr(v) }; + unsafe { uvll::buf_init(data, v.len()) } +} + +// XXX: Do these conversions without copying + +/// Transmute an owned vector to a Buf +pub fn vec_to_uv_buf(v: ~[u8]) -> Buf { + let data = unsafe { malloc(v.len() as size_t) } as *u8; + fail_unless!(data.is_not_null()); + do vec::as_imm_buf(v) |b, l| { + let data = data as *mut u8; + unsafe { ptr::copy_memory(data, b, l) } + } + let buf = unsafe { uvll::buf_init(data, v.len()) }; + return buf; +} + +/// Transmute a Buf that was once a ~[u8] back to ~[u8] +pub fn vec_from_uv_buf(buf: Buf) -> Option<~[u8]> { + if !(buf.len == 0 && buf.base.is_null()) { + let v = unsafe { vec::from_buf(buf.base, buf.len as uint) }; + unsafe { free(buf.base as *c_void) }; + return Some(v); + } else { + // No buffer + return None; + } +} + +#[test] +fn loop_smoke_test() { + do run_in_bare_thread { + let mut loop_ = Loop::new(); + loop_.run(); + loop_.close(); + } +} + +#[test] +#[ignore(reason = "valgrind - loop destroyed before watcher?")] +fn idle_new_then_close() { + do run_in_bare_thread { + let mut loop_ = Loop::new(); + let mut idle_watcher = { IdleWatcher::new(&mut loop_) }; + idle_watcher.close(); + } +} + +#[test] +fn idle_smoke_test() { + do run_in_bare_thread { + let mut loop_ = Loop::new(); + let mut idle_watcher = { IdleWatcher::new(&mut loop_) }; + let mut count = 10; + let count_ptr: *mut int = &mut count; + do idle_watcher.start |idle_watcher, status| { + let mut idle_watcher = idle_watcher; + fail_unless!(status.is_none()); + if unsafe { *count_ptr == 10 } { + idle_watcher.stop(); + idle_watcher.close(); + } else { + unsafe { *count_ptr = *count_ptr + 1; } + } + } + loop_.run(); + loop_.close(); + fail_unless!(count == 10); + } +} + +#[test] +fn idle_start_stop_start() { + do run_in_bare_thread { + let mut loop_ = Loop::new(); + let mut idle_watcher = { IdleWatcher::new(&mut loop_) }; + do idle_watcher.start |idle_watcher, status| { + let mut idle_watcher = idle_watcher; + fail_unless!(status.is_none()); + idle_watcher.stop(); + do idle_watcher.start |idle_watcher, status| { + fail_unless!(status.is_none()); + let mut idle_watcher = idle_watcher; + idle_watcher.stop(); + idle_watcher.close(); + } + } + loop_.run(); + loop_.close(); + } +} diff --git a/src/libcore/rt/uv/net.rs b/src/libcore/rt/uv/net.rs new file mode 100644 index 0000000000000..8f0e8c3edd50d --- /dev/null +++ b/src/libcore/rt/uv/net.rs @@ -0,0 +1,483 @@ +// Copyright 2013 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +use prelude::*; +use libc::{size_t, ssize_t, c_int, c_void}; +use cast::{transmute, transmute_mut_region}; +use super::super::uvll; +use super::super::uvll::*; +use super::{Loop, Watcher, Request, UvError, Buf, Callback, NativeHandle, NullCallback, + loop_from_watcher, status_to_maybe_uv_error, + install_watcher_data, get_watcher_data, drop_watcher_data, + vec_to_uv_buf, vec_from_uv_buf}; +use super::super::rtio::{IpAddr, Ipv4, Ipv6}; + +#[cfg(test)] +use unstable::run_in_bare_thread; +#[cfg(test)] +use super::super::thread::Thread; +#[cfg(test)] +use cell::Cell; + +fn ip4_as_uv_ip4(addr: IpAddr, f: &fn(*sockaddr_in)) { + match addr { + Ipv4(a, b, c, d, p) => { + unsafe { + let addr = malloc_ip4_addr(fmt!("%u.%u.%u.%u", + a as uint, + b as uint, + c as uint, + d as uint), p as int); + do (|| { + f(addr); + }).finally { + free_ip4_addr(addr); + } + } + } + Ipv6 => fail!() + } +} + +// uv_stream t is the parent class of uv_tcp_t, uv_pipe_t, uv_tty_t +// and uv_file_t +pub struct StreamWatcher(*uvll::uv_stream_t); + +impl Watcher for StreamWatcher { + fn event_loop(&self) -> Loop { + loop_from_watcher(self) + } +} + +pub type ReadCallback = ~fn(StreamWatcher, int, Buf, Option); +impl Callback for ReadCallback { } + +// XXX: The uv alloc callback also has a *uv_handle_t arg +pub type AllocCallback = ~fn(uint) -> Buf; +impl Callback for AllocCallback { } + +pub impl StreamWatcher { + + fn read_start(&mut self, alloc: AllocCallback, cb: ReadCallback) { + // XXX: Borrowchk problems + let data = get_watcher_data(unsafe { transmute_mut_region(self) }); + data.alloc_cb = Some(alloc); + data.read_cb = Some(cb); + + let handle = self.native_handle(); + unsafe { uvll::read_start(handle, alloc_cb, read_cb); } + + extern fn alloc_cb(stream: *uvll::uv_stream_t, suggested_size: size_t) -> Buf { + let mut stream_watcher: StreamWatcher = NativeHandle::from_native_handle(stream); + let data = get_watcher_data(&mut stream_watcher); + let alloc_cb = data.alloc_cb.get_ref(); + return (*alloc_cb)(suggested_size as uint); + } + + extern fn read_cb(stream: *uvll::uv_stream_t, nread: ssize_t, ++buf: Buf) { + rtdebug!("buf addr: %x", buf.base as uint); + rtdebug!("buf len: %d", buf.len as int); + let mut stream_watcher: StreamWatcher = NativeHandle::from_native_handle(stream); + let data = get_watcher_data(&mut stream_watcher); + let cb = data.read_cb.get_ref(); + let status = status_to_maybe_uv_error(stream, nread as c_int); + (*cb)(stream_watcher, nread as int, buf, status); + } + } + + fn read_stop(&mut self) { + // It would be nice to drop the alloc and read callbacks here, + // but read_stop may be called from inside one of them and we + // would end up freeing the in-use environment + let handle = self.native_handle(); + unsafe { uvll::read_stop(handle); } + } + + // XXX: Needs to take &[u8], not ~[u8] + fn write(&mut self, msg: ~[u8], cb: ConnectionCallback) { + // XXX: Borrowck + let data = get_watcher_data(unsafe { transmute_mut_region(self) }); + fail_unless!(data.write_cb.is_none()); + data.write_cb = Some(cb); + + let req = WriteRequest::new(); + let buf = vec_to_uv_buf(msg); + // XXX: Allocation + let bufs = ~[buf]; + unsafe { + fail_unless!(0 == uvll::write(req.native_handle(), + self.native_handle(), + &bufs, write_cb)); + } + // XXX: Freeing immediately after write. Is this ok? + let _v = vec_from_uv_buf(buf); + + extern fn write_cb(req: *uvll::uv_write_t, status: c_int) { + let write_request: WriteRequest = NativeHandle::from_native_handle(req); + let mut stream_watcher = write_request.stream(); + write_request.delete(); + let cb = get_watcher_data(&mut stream_watcher).write_cb.swap_unwrap(); + let status = status_to_maybe_uv_error(stream_watcher.native_handle(), status); + cb(stream_watcher, status); + } + } + + fn accept(&mut self, stream: StreamWatcher) { + let self_handle = self.native_handle() as *c_void; + let stream_handle = stream.native_handle() as *c_void; + unsafe { + fail_unless!(0 == uvll::accept(self_handle, stream_handle)); + } + } + + fn close(self, cb: NullCallback) { + { + let mut self = self; + let data = get_watcher_data(&mut self); + fail_unless!(data.close_cb.is_none()); + data.close_cb = Some(cb); + } + + unsafe { uvll::close(self.native_handle(), close_cb); } + + extern fn close_cb(handle: *uvll::uv_stream_t) { + let mut stream_watcher: StreamWatcher = NativeHandle::from_native_handle(handle); + { + let mut data = get_watcher_data(&mut stream_watcher); + data.close_cb.swap_unwrap()(); + } + drop_watcher_data(&mut stream_watcher); + unsafe { free_handle(handle as *c_void) } + } + } +} + +impl NativeHandle<*uvll::uv_stream_t> for StreamWatcher { + fn from_native_handle( + handle: *uvll::uv_stream_t) -> StreamWatcher { + StreamWatcher(handle) + } + fn native_handle(&self) -> *uvll::uv_stream_t { + match self { &StreamWatcher(ptr) => ptr } + } +} + +pub struct TcpWatcher(*uvll::uv_tcp_t); + +impl Watcher for TcpWatcher { + fn event_loop(&self) -> Loop { + loop_from_watcher(self) + } +} + +pub type ConnectionCallback = ~fn(StreamWatcher, Option); +impl Callback for ConnectionCallback { } + +pub impl TcpWatcher { + fn new(loop_: &mut Loop) -> TcpWatcher { + unsafe { + let handle = malloc_handle(UV_TCP); + fail_unless!(handle.is_not_null()); + fail_unless!(0 == uvll::tcp_init(loop_.native_handle(), handle)); + let mut watcher = NativeHandle::from_native_handle(handle); + install_watcher_data(&mut watcher); + return watcher; + } + } + + fn bind(&mut self, address: IpAddr) { + match address { + Ipv4(*) => { + do ip4_as_uv_ip4(address) |addr| { + let result = unsafe { + uvll::tcp_bind(self.native_handle(), addr) + }; + // XXX: bind is likely to fail. need real error handling + fail_unless!(result == 0); + } + } + _ => fail!() + } + } + + fn connect(&mut self, address: IpAddr, cb: ConnectionCallback) { + unsafe { + fail_unless!(get_watcher_data(self).connect_cb.is_none()); + get_watcher_data(self).connect_cb = Some(cb); + + let mut connect_watcher = ConnectRequest::new(); + let connect_handle = connect_watcher.native_handle(); + match address { + Ipv4(*) => { + do ip4_as_uv_ip4(address) |addr| { + rtdebug!("connect_t: %x", connect_handle as uint); + fail_unless!(0 == uvll::tcp_connect(connect_handle, + self.native_handle(), + addr, connect_cb)); + } + } + _ => fail!() + } + + extern fn connect_cb(req: *uvll::uv_connect_t, status: c_int) { + rtdebug!("connect_t: %x", req as uint); + let connect_request: ConnectRequest = NativeHandle::from_native_handle(req); + let mut stream_watcher = connect_request.stream(); + connect_request.delete(); + let cb: ConnectionCallback = { + let data = get_watcher_data(&mut stream_watcher); + data.connect_cb.swap_unwrap() + }; + let status = status_to_maybe_uv_error(stream_watcher.native_handle(), status); + cb(stream_watcher, status); + } + } + } + + fn listen(&mut self, cb: ConnectionCallback) { + // XXX: Borrowck + let data = get_watcher_data(unsafe { transmute_mut_region(self) }); + fail_unless!(data.connect_cb.is_none()); + data.connect_cb = Some(cb); + + unsafe { + static BACKLOG: c_int = 128; // XXX should be configurable + // XXX: This can probably fail + fail_unless!(0 == uvll::listen(self.native_handle(), + BACKLOG, connection_cb)); + } + + extern fn connection_cb(handle: *uvll::uv_stream_t, status: c_int) { + rtdebug!("connection_cb"); + let mut stream_watcher: StreamWatcher = NativeHandle::from_native_handle(handle); + let cb = get_watcher_data(&mut stream_watcher).connect_cb.swap_unwrap(); + let status = status_to_maybe_uv_error(stream_watcher.native_handle(), status); + cb(stream_watcher, status); + } + } + + fn as_stream(&self) -> StreamWatcher { + NativeHandle::from_native_handle(self.native_handle() as *uvll::uv_stream_t) + } +} + +impl NativeHandle<*uvll::uv_tcp_t> for TcpWatcher { + fn from_native_handle(handle: *uvll::uv_tcp_t) -> TcpWatcher { + TcpWatcher(handle) + } + fn native_handle(&self) -> *uvll::uv_tcp_t { + match self { &TcpWatcher(ptr) => ptr } + } +} + +pub type ConnectCallback = ~fn(ConnectRequest, Option); +impl Callback for ConnectCallback { } + +// uv_connect_t is a subclass of uv_req_t +struct ConnectRequest(*uvll::uv_connect_t); + +impl Request for ConnectRequest { } + +impl ConnectRequest { + + fn new() -> ConnectRequest { + let connect_handle = unsafe { + malloc_req(UV_CONNECT) + }; + fail_unless!(connect_handle.is_not_null()); + let connect_handle = connect_handle as *uvll::uv_connect_t; + ConnectRequest(connect_handle) + } + + fn stream(&self) -> StreamWatcher { + unsafe { + let stream_handle = uvll::get_stream_handle_from_connect_req(self.native_handle()); + NativeHandle::from_native_handle(stream_handle) + } + } + + fn delete(self) { + unsafe { free_req(self.native_handle() as *c_void) } + } +} + +impl NativeHandle<*uvll::uv_connect_t> for ConnectRequest { + fn from_native_handle( + handle: *uvll:: uv_connect_t) -> ConnectRequest { + ConnectRequest(handle) + } + fn native_handle(&self) -> *uvll::uv_connect_t { + match self { &ConnectRequest(ptr) => ptr } + } +} + +pub struct WriteRequest(*uvll::uv_write_t); + +impl Request for WriteRequest { } + +pub impl WriteRequest { + + fn new() -> WriteRequest { + let write_handle = unsafe { + malloc_req(UV_WRITE) + }; + fail_unless!(write_handle.is_not_null()); + let write_handle = write_handle as *uvll::uv_write_t; + WriteRequest(write_handle) + } + + fn stream(&self) -> StreamWatcher { + unsafe { + let stream_handle = uvll::get_stream_handle_from_write_req(self.native_handle()); + NativeHandle::from_native_handle(stream_handle) + } + } + + fn delete(self) { + unsafe { free_req(self.native_handle() as *c_void) } + } +} + +impl NativeHandle<*uvll::uv_write_t> for WriteRequest { + fn from_native_handle(handle: *uvll:: uv_write_t) -> WriteRequest { + WriteRequest(handle) + } + fn native_handle(&self) -> *uvll::uv_write_t { + match self { &WriteRequest(ptr) => ptr } + } +} + + +#[test] +#[ignore(reason = "ffi struct issues")] +fn connect_close() { + do run_in_bare_thread() { + let mut loop_ = Loop::new(); + let mut tcp_watcher = { TcpWatcher::new(&mut loop_) }; + // Connect to a port where nobody is listening + let addr = Ipv4(127, 0, 0, 1, 2923); + do tcp_watcher.connect(addr) |stream_watcher, status| { + rtdebug!("tcp_watcher.connect!"); + fail_unless!(status.is_some()); + fail_unless!(status.get().name() == ~"ECONNREFUSED"); + stream_watcher.close(||()); + } + loop_.run(); + loop_.close(); + } +} + +#[test] +#[ignore(reason = "need a server to connect to")] +fn connect_read() { + do run_in_bare_thread() { + let mut loop_ = Loop::new(); + let mut tcp_watcher = { TcpWatcher::new(&mut loop_) }; + let addr = Ipv4(127, 0, 0, 1, 2924); + do tcp_watcher.connect(addr) |stream_watcher, status| { + let mut stream_watcher = stream_watcher; + rtdebug!("tcp_watcher.connect!"); + fail_unless!(status.is_none()); + let alloc: AllocCallback = |size| { + vec_to_uv_buf(vec::from_elem(size, 0)) + }; + do stream_watcher.read_start(alloc) + |stream_watcher, nread, buf, status| { + + let buf = vec_from_uv_buf(buf); + rtdebug!("read cb!"); + if status.is_none() { + let bytes = buf.unwrap(); + rtdebug!("%s", bytes.slice(0, nread as uint).to_str()); + } else { + rtdebug!("status after read: %s", status.get().to_str()); + rtdebug!("closing"); + stream_watcher.close(||()); + } + } + } + loop_.run(); + loop_.close(); + } +} + +#[test] +#[ignore(reason = "ffi struct issues")] +fn listen() { + do run_in_bare_thread() { + static MAX: int = 10; + let mut loop_ = Loop::new(); + let mut server_tcp_watcher = { TcpWatcher::new(&mut loop_) }; + let addr = Ipv4(127, 0, 0, 1, 2925); + server_tcp_watcher.bind(addr); + let loop_ = loop_; + rtdebug!("listening"); + do server_tcp_watcher.listen |server_stream_watcher, status| { + rtdebug!("listened!"); + fail_unless!(status.is_none()); + let mut server_stream_watcher = server_stream_watcher; + let mut loop_ = loop_; + let mut client_tcp_watcher = TcpWatcher::new(&mut loop_); + let mut client_tcp_watcher = client_tcp_watcher.as_stream(); + server_stream_watcher.accept(client_tcp_watcher); + let count_cell = Cell(0); + let server_stream_watcher = server_stream_watcher; + rtdebug!("starting read"); + let alloc: AllocCallback = |size| { + vec_to_uv_buf(vec::from_elem(size, 0)) + }; + do client_tcp_watcher.read_start(alloc) + |stream_watcher, nread, buf, status| { + + rtdebug!("i'm reading!"); + let buf = vec_from_uv_buf(buf); + let mut count = count_cell.take(); + if status.is_none() { + rtdebug!("got %d bytes", nread); + let buf = buf.unwrap(); + for buf.slice(0, nread as uint).each |byte| { + fail_unless!(*byte == count as u8); + rtdebug!("%u", *byte as uint); + count += 1; + } + } else { + fail_unless!(count == MAX); + do stream_watcher.close { + server_stream_watcher.close(||()); + } + } + count_cell.put_back(count); + } + } + + let _client_thread = do Thread::start { + rtdebug!("starting client thread"); + let mut loop_ = Loop::new(); + let mut tcp_watcher = { TcpWatcher::new(&mut loop_) }; + do tcp_watcher.connect(addr) |stream_watcher, status| { + rtdebug!("connecting"); + fail_unless!(status.is_none()); + let mut stream_watcher = stream_watcher; + let msg = ~[0, 1, 2, 3, 4, 5, 6 ,7 ,8, 9]; + do stream_watcher.write(msg) |stream_watcher, status| { + rtdebug!("writing"); + fail_unless!(status.is_none()); + stream_watcher.close(||()); + } + } + loop_.run(); + loop_.close(); + }; + + let mut loop_ = loop_; + loop_.run(); + loop_.close(); + } +} diff --git a/src/libcore/rt/uvio.rs b/src/libcore/rt/uvio.rs index a971ed92b7ebc..bcad67c0c94ff 100644 --- a/src/libcore/rt/uvio.rs +++ b/src/libcore/rt/uvio.rs @@ -12,13 +12,11 @@ use option::*; use result::*; use super::uv::*; -use super::io::*; +use super::rtio::*; use ops::Drop; use cell::{Cell, empty_cell}; use cast::transmute; -use super::StreamObject; use super::sched::Scheduler; -use super::IoFactoryObject; #[cfg(test)] use super::sched::Task; #[cfg(test)] use unstable::run_in_bare_thread; @@ -29,14 +27,14 @@ pub struct UvEventLoop { } pub impl UvEventLoop { - static fn new() -> UvEventLoop { + fn new() -> UvEventLoop { UvEventLoop { uvio: UvIoFactory(Loop::new()) } } /// A convenience constructor - static fn new_scheduler() -> Scheduler { + fn new_scheduler() -> Scheduler { Scheduler::new(~UvEventLoop::new()) } } @@ -189,12 +187,9 @@ impl TcpListener for UvTcpListener { do server_tcp_watcher.listen |server_stream_watcher, status| { let maybe_stream = if status.is_none() { let mut server_stream_watcher = server_stream_watcher; - let mut loop_ = - loop_from_watcher(&server_stream_watcher); - let mut client_tcp_watcher = - TcpWatcher::new(&mut loop_); - let mut client_tcp_watcher = - client_tcp_watcher.as_stream(); + let mut loop_ = loop_from_watcher(&server_stream_watcher); + let mut client_tcp_watcher = TcpWatcher::new(&mut loop_); + let mut client_tcp_watcher = client_tcp_watcher.as_stream(); // XXX: Need's to be surfaced in interface server_stream_watcher.accept(client_tcp_watcher); Some(~UvStream::new(client_tcp_watcher)) @@ -221,7 +216,7 @@ impl TcpListener for UvTcpListener { pub struct UvStream(StreamWatcher); impl UvStream { - static fn new(watcher: StreamWatcher) -> UvStream { + fn new(watcher: StreamWatcher) -> UvStream { UvStream(watcher) } @@ -425,8 +420,7 @@ fn test_read_and_block() { // Yield to the other task in hopes that it // will trigger a read callback while we are // not ready for it - do scheduler.block_running_task_and_then - |scheduler, task| { + do scheduler.block_running_task_and_then |scheduler, task| { scheduler.task_queue.push_back(task); } } diff --git a/src/libcore/rt/uvll.rs b/src/libcore/rt/uvll.rs new file mode 100644 index 0000000000000..5111b2bdc1d22 --- /dev/null +++ b/src/libcore/rt/uvll.rs @@ -0,0 +1,442 @@ +// Copyright 2012 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +/*! + * Low-level bindings to the libuv library. + * + * This module contains a set of direct, 'bare-metal' wrappers around + * the libuv C-API. + * + * We're not bothering yet to redefine uv's structs as Rust structs + * because they are quite large and change often between versions. + * The maintenance burden is just too high. Instead we use the uv's + * `uv_handle_size` and `uv_req_size` to find the correct size of the + * structs and allocate them on the heap. This can be revisited later. + * + * There are also a collection of helper functions to ease interacting + * with the low-level API. + * + * As new functionality, existant in uv.h, is added to the rust stdlib, + * the mappings should be added in this module. + */ + +#[allow(non_camel_case_types)]; // C types + +use libc::{size_t, c_int, c_uint, c_void, c_char, uintptr_t}; +use libc::{malloc, free}; +use prelude::*; +use ptr::to_unsafe_ptr; + +pub struct uv_err_t { + code: c_int, + sys_errno_: c_int +} + +pub struct uv_buf_t { + base: *u8, + len: libc::size_t, +} + +pub type uv_handle_t = c_void; +pub type uv_loop_t = c_void; +pub type uv_idle_t = c_void; +pub type uv_tcp_t = c_void; +pub type uv_connect_t = c_void; +pub type uv_write_t = c_void; +pub type uv_async_t = c_void; +pub type uv_timer_t = c_void; +pub type uv_stream_t = c_void; +pub type uv_fs_t = c_void; + +pub type uv_idle_cb = *u8; + +pub type sockaddr_in = c_void; +pub type sockaddr_in6 = c_void; + +#[deriving(Eq)] +pub enum uv_handle_type { + UV_UNKNOWN_HANDLE, + UV_ASYNC, + UV_CHECK, + UV_FS_EVENT, + UV_FS_POLL, + UV_HANDLE, + UV_IDLE, + UV_NAMED_PIPE, + UV_POLL, + UV_PREPARE, + UV_PROCESS, + UV_STREAM, + UV_TCP, + UV_TIMER, + UV_TTY, + UV_UDP, + UV_SIGNAL, + UV_FILE, + UV_HANDLE_TYPE_MAX +} + +#[deriving(Eq)] +pub enum uv_req_type { + UV_UNKNOWN_REQ, + UV_REQ, + UV_CONNECT, + UV_WRITE, + UV_SHUTDOWN, + UV_UDP_SEND, + UV_FS, + UV_WORK, + UV_GETADDRINFO, + UV_REQ_TYPE_MAX +} + +pub unsafe fn malloc_handle(handle: uv_handle_type) -> *c_void { + fail_unless!(handle != UV_UNKNOWN_HANDLE && handle != UV_HANDLE_TYPE_MAX); + let size = unsafe { rust_uv_handle_size(handle as uint) }; + let p = malloc(size); + fail_unless!(p.is_not_null()); + return p; +} + +pub unsafe fn free_handle(v: *c_void) { + free(v) +} + +pub unsafe fn malloc_req(req: uv_req_type) -> *c_void { + fail_unless!(req != UV_UNKNOWN_REQ && req != UV_REQ_TYPE_MAX); + let size = unsafe { rust_uv_req_size(req as uint) }; + let p = malloc(size); + fail_unless!(p.is_not_null()); + return p; +} + +pub unsafe fn free_req(v: *c_void) { + free(v) +} + +#[test] +fn handle_sanity_check() { + unsafe { + fail_unless!(UV_HANDLE_TYPE_MAX as uint == rust_uv_handle_type_max()); + } +} + +#[test] +fn request_sanity_check() { + unsafe { + fail_unless!(UV_REQ_TYPE_MAX as uint == rust_uv_req_type_max()); + } +} + +pub unsafe fn loop_new() -> *c_void { + return rust_uv_loop_new(); +} + +pub unsafe fn loop_delete(loop_handle: *c_void) { + rust_uv_loop_delete(loop_handle); +} + +pub unsafe fn run(loop_handle: *c_void) { + rust_uv_run(loop_handle); +} + +pub unsafe fn close(handle: *T, cb: *u8) { + rust_uv_close(handle as *c_void, cb); +} + +pub unsafe fn walk(loop_handle: *c_void, cb: *u8, arg: *c_void) { + rust_uv_walk(loop_handle, cb, arg); +} + +pub unsafe fn idle_new() -> *uv_idle_t { + rust_uv_idle_new() +} + +pub unsafe fn idle_delete(handle: *uv_idle_t) { + rust_uv_idle_delete(handle) +} + +pub unsafe fn idle_init(loop_handle: *uv_loop_t, handle: *uv_idle_t) -> c_int { + rust_uv_idle_init(loop_handle, handle) +} + +pub unsafe fn idle_start(handle: *uv_idle_t, cb: uv_idle_cb) -> c_int { + rust_uv_idle_start(handle, cb) +} + +pub unsafe fn idle_stop(handle: *uv_idle_t) -> c_int { + rust_uv_idle_stop(handle) +} + +pub unsafe fn tcp_init(loop_handle: *c_void, handle: *uv_tcp_t) -> c_int { + return rust_uv_tcp_init(loop_handle, handle); +} + +// FIXME ref #2064 +pub unsafe fn tcp_connect(connect_ptr: *uv_connect_t, + tcp_handle_ptr: *uv_tcp_t, + addr_ptr: *sockaddr_in, + after_connect_cb: *u8) -> c_int { + return rust_uv_tcp_connect(connect_ptr, tcp_handle_ptr, + after_connect_cb, addr_ptr); +} +// FIXME ref #2064 +pub unsafe fn tcp_connect6(connect_ptr: *uv_connect_t, + tcp_handle_ptr: *uv_tcp_t, + addr_ptr: *sockaddr_in6, + after_connect_cb: *u8) -> c_int { + return rust_uv_tcp_connect6(connect_ptr, tcp_handle_ptr, + after_connect_cb, addr_ptr); +} +// FIXME ref #2064 +pub unsafe fn tcp_bind(tcp_server_ptr: *uv_tcp_t, addr_ptr: *sockaddr_in) -> c_int { + return rust_uv_tcp_bind(tcp_server_ptr, addr_ptr); +} +// FIXME ref #2064 +pub unsafe fn tcp_bind6(tcp_server_ptr: *uv_tcp_t, addr_ptr: *sockaddr_in6) -> c_int { + return rust_uv_tcp_bind6(tcp_server_ptr, addr_ptr); +} + +pub unsafe fn tcp_getpeername(tcp_handle_ptr: *uv_tcp_t, name: *sockaddr_in) -> c_int { + return rust_uv_tcp_getpeername(tcp_handle_ptr, name); +} + +pub unsafe fn tcp_getpeername6(tcp_handle_ptr: *uv_tcp_t, name: *sockaddr_in6) ->c_int { + return rust_uv_tcp_getpeername6(tcp_handle_ptr, name); +} + +pub unsafe fn listen(stream: *T, backlog: c_int, cb: *u8) -> c_int { + return rust_uv_listen(stream as *c_void, backlog, cb); +} + +pub unsafe fn accept(server: *c_void, client: *c_void) -> c_int { + return rust_uv_accept(server as *c_void, client as *c_void); +} + +pub unsafe fn write(req: *uv_write_t, stream: *T, buf_in: *~[uv_buf_t], cb: *u8) -> c_int { + let buf_ptr = vec::raw::to_ptr(*buf_in); + let buf_cnt = vec::len(*buf_in) as i32; + return rust_uv_write(req as *c_void, stream as *c_void, buf_ptr, buf_cnt, cb); +} +pub unsafe fn read_start(stream: *uv_stream_t, on_alloc: *u8, on_read: *u8) -> c_int { + return rust_uv_read_start(stream as *c_void, on_alloc, on_read); +} + +pub unsafe fn read_stop(stream: *uv_stream_t) -> c_int { + return rust_uv_read_stop(stream as *c_void); +} + +pub unsafe fn last_error(loop_handle: *c_void) -> uv_err_t { + return rust_uv_last_error(loop_handle); +} + +pub unsafe fn strerror(err: *uv_err_t) -> *c_char { + return rust_uv_strerror(err); +} +pub unsafe fn err_name(err: *uv_err_t) -> *c_char { + return rust_uv_err_name(err); +} + +pub unsafe fn async_init(loop_handle: *c_void, async_handle: *uv_async_t, cb: *u8) -> c_int { + return rust_uv_async_init(loop_handle, async_handle, cb); +} + +pub unsafe fn async_send(async_handle: *uv_async_t) { + return rust_uv_async_send(async_handle); +} +pub unsafe fn buf_init(input: *u8, len: uint) -> uv_buf_t { + let out_buf = uv_buf_t { base: ptr::null(), len: 0 as size_t }; + let out_buf_ptr = ptr::addr_of(&out_buf); + rust_uv_buf_init(out_buf_ptr, input, len as size_t); + return out_buf; +} + +pub unsafe fn timer_init(loop_ptr: *c_void, timer_ptr: *uv_timer_t) -> c_int { + return rust_uv_timer_init(loop_ptr, timer_ptr); +} +pub unsafe fn timer_start(timer_ptr: *uv_timer_t, cb: *u8, timeout: uint, + repeat: uint) -> c_int { + return rust_uv_timer_start(timer_ptr, cb, timeout as c_uint, repeat as c_uint); +} +pub unsafe fn timer_stop(timer_ptr: *uv_timer_t) -> c_int { + return rust_uv_timer_stop(timer_ptr); +} + +pub unsafe fn malloc_ip4_addr(ip: &str, port: int) -> *sockaddr_in { + do str::as_c_str(ip) |ip_buf| { + rust_uv_ip4_addrp(ip_buf as *u8, port as libc::c_int) + } +} +pub unsafe fn malloc_ip6_addr(ip: &str, port: int) -> *sockaddr_in6 { + do str::as_c_str(ip) |ip_buf| { + rust_uv_ip6_addrp(ip_buf as *u8, port as libc::c_int) + } +} + +pub unsafe fn free_ip4_addr(addr: *sockaddr_in) { + rust_uv_free_ip4_addr(addr); +} + +pub unsafe fn free_ip6_addr(addr: *sockaddr_in6) { + rust_uv_free_ip6_addr(addr); +} + +// data access helpers +pub unsafe fn get_loop_for_uv_handle(handle: *T) -> *c_void { + return rust_uv_get_loop_for_uv_handle(handle as *c_void); +} +pub unsafe fn get_stream_handle_from_connect_req(connect: *uv_connect_t) -> *uv_stream_t { + return rust_uv_get_stream_handle_from_connect_req(connect); +} +pub unsafe fn get_stream_handle_from_write_req(write_req: *uv_write_t) -> *uv_stream_t { + return rust_uv_get_stream_handle_from_write_req(write_req); +} +pub unsafe fn get_data_for_uv_loop(loop_ptr: *c_void) -> *c_void { + rust_uv_get_data_for_uv_loop(loop_ptr) +} +pub unsafe fn set_data_for_uv_loop(loop_ptr: *c_void, data: *c_void) { + rust_uv_set_data_for_uv_loop(loop_ptr, data); +} +pub unsafe fn get_data_for_uv_handle(handle: *T) -> *c_void { + return rust_uv_get_data_for_uv_handle(handle as *c_void); +} +pub unsafe fn set_data_for_uv_handle(handle: *T, data: *U) { + rust_uv_set_data_for_uv_handle(handle as *c_void, data as *c_void); +} +pub unsafe fn get_data_for_req(req: *T) -> *c_void { + return rust_uv_get_data_for_req(req as *c_void); +} +pub unsafe fn set_data_for_req(req: *T, data: *U) { + rust_uv_set_data_for_req(req as *c_void, data as *c_void); +} +pub unsafe fn get_base_from_buf(buf: uv_buf_t) -> *u8 { + return rust_uv_get_base_from_buf(buf); +} +pub unsafe fn get_len_from_buf(buf: uv_buf_t) -> size_t { + return rust_uv_get_len_from_buf(buf); +} +pub unsafe fn malloc_buf_base_of(suggested_size: size_t) -> *u8 { + return rust_uv_malloc_buf_base_of(suggested_size); +} +pub unsafe fn free_base_of_buf(buf: uv_buf_t) { + rust_uv_free_base_of_buf(buf); +} + +pub unsafe fn get_last_err_info(uv_loop: *c_void) -> ~str { + let err = last_error(uv_loop); + 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); +} + +pub unsafe fn get_last_err_data(uv_loop: *c_void) -> uv_err_data { + let err = last_error(uv_loop); + 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)); + uv_err_data { err_name: err_name, err_msg: err_msg } +} + +pub struct uv_err_data { + err_name: ~str, + err_msg: ~str, +} + +extern { + + fn rust_uv_handle_size(type_: uintptr_t) -> size_t; + fn rust_uv_req_size(type_: uintptr_t) -> size_t; + fn rust_uv_handle_type_max() -> uintptr_t; + fn rust_uv_req_type_max() -> uintptr_t; + + // libuv public API + fn rust_uv_loop_new() -> *c_void; + fn rust_uv_loop_delete(lp: *c_void); + fn rust_uv_run(loop_handle: *c_void); + fn rust_uv_close(handle: *c_void, cb: *u8); + fn rust_uv_walk(loop_handle: *c_void, cb: *u8, arg: *c_void); + + fn rust_uv_idle_new() -> *uv_idle_t; + fn rust_uv_idle_delete(handle: *uv_idle_t); + fn rust_uv_idle_init(loop_handle: *uv_loop_t, handle: *uv_idle_t) -> c_int; + fn rust_uv_idle_start(handle: *uv_idle_t, cb: uv_idle_cb) -> c_int; + fn rust_uv_idle_stop(handle: *uv_idle_t) -> c_int; + + fn rust_uv_async_send(handle: *uv_async_t); + fn rust_uv_async_init(loop_handle: *c_void, + async_handle: *uv_async_t, + cb: *u8) -> c_int; + fn rust_uv_tcp_init(loop_handle: *c_void, handle_ptr: *uv_tcp_t) -> c_int; + // FIXME ref #2604 .. ? + fn rust_uv_buf_init(out_buf: *uv_buf_t, base: *u8, len: size_t); + fn rust_uv_last_error(loop_handle: *c_void) -> uv_err_t; + // FIXME ref #2064 + fn rust_uv_strerror(err: *uv_err_t) -> *c_char; + // FIXME ref #2064 + fn rust_uv_err_name(err: *uv_err_t) -> *c_char; + fn rust_uv_ip4_addrp(ip: *u8, port: c_int) -> *sockaddr_in; + fn rust_uv_ip6_addrp(ip: *u8, port: c_int) -> *sockaddr_in6; + fn rust_uv_free_ip4_addr(addr: *sockaddr_in); + fn rust_uv_free_ip6_addr(addr: *sockaddr_in6); + fn rust_uv_ip4_name(src: *sockaddr_in, dst: *u8, size: size_t) -> c_int; + fn rust_uv_ip6_name(src: *sockaddr_in6, dst: *u8, size: size_t) -> c_int; + fn rust_uv_ip4_port(src: *sockaddr_in) -> c_uint; + fn rust_uv_ip6_port(src: *sockaddr_in6) -> c_uint; + // FIXME ref #2064 + fn rust_uv_tcp_connect(connect_ptr: *uv_connect_t, + tcp_handle_ptr: *uv_tcp_t, + ++after_cb: *u8, + ++addr: *sockaddr_in) -> c_int; + // FIXME ref #2064 + fn rust_uv_tcp_bind(tcp_server: *uv_tcp_t, ++addr: *sockaddr_in) -> c_int; + // FIXME ref #2064 + fn rust_uv_tcp_connect6(connect_ptr: *uv_connect_t, + tcp_handle_ptr: *uv_tcp_t, + ++after_cb: *u8, + ++addr: *sockaddr_in6) -> c_int; + // FIXME ref #2064 + fn rust_uv_tcp_bind6(tcp_server: *uv_tcp_t, ++addr: *sockaddr_in6) -> c_int; + fn rust_uv_tcp_getpeername(tcp_handle_ptr: *uv_tcp_t, ++name: *sockaddr_in) -> c_int; + fn rust_uv_tcp_getpeername6(tcp_handle_ptr: *uv_tcp_t, ++name: *sockaddr_in6) ->c_int; + fn rust_uv_listen(stream: *c_void, backlog: c_int, cb: *u8) -> c_int; + fn rust_uv_accept(server: *c_void, client: *c_void) -> c_int; + fn rust_uv_write(req: *c_void, + stream: *c_void, + ++buf_in: *uv_buf_t, + buf_cnt: c_int, + cb: *u8) -> c_int; + fn rust_uv_read_start(stream: *c_void, + on_alloc: *u8, + on_read: *u8) -> c_int; + fn rust_uv_read_stop(stream: *c_void) -> c_int; + fn rust_uv_timer_init(loop_handle: *c_void, + timer_handle: *uv_timer_t) -> c_int; + fn rust_uv_timer_start(timer_handle: *uv_timer_t, + cb: *u8, + timeout: c_uint, + repeat: c_uint) -> c_int; + fn rust_uv_timer_stop(handle: *uv_timer_t) -> c_int; + + fn rust_uv_malloc_buf_base_of(sug_size: size_t) -> *u8; + fn rust_uv_free_base_of_buf(++buf: uv_buf_t); + fn rust_uv_get_stream_handle_from_connect_req(connect_req: *uv_connect_t) -> *uv_stream_t; + fn rust_uv_get_stream_handle_from_write_req(write_req: *uv_write_t) -> *uv_stream_t; + fn rust_uv_get_loop_for_uv_handle(handle: *c_void) -> *c_void; + fn rust_uv_get_data_for_uv_loop(loop_ptr: *c_void) -> *c_void; + fn rust_uv_set_data_for_uv_loop(loop_ptr: *c_void, data: *c_void); + fn rust_uv_get_data_for_uv_handle(handle: *c_void) -> *c_void; + fn rust_uv_set_data_for_uv_handle(handle: *c_void, data: *c_void); + fn rust_uv_get_data_for_req(req: *c_void) -> *c_void; + fn rust_uv_set_data_for_req(req: *c_void, data: *c_void); + fn rust_uv_get_base_from_buf(++buf: uv_buf_t) -> *u8; + fn rust_uv_get_len_from_buf(++buf: uv_buf_t) -> size_t; +} diff --git a/src/libcore/rt/work_queue.rs b/src/libcore/rt/work_queue.rs index 1be2eb26e6292..dfa88b783c59f 100644 --- a/src/libcore/rt/work_queue.rs +++ b/src/libcore/rt/work_queue.rs @@ -15,7 +15,7 @@ pub struct WorkQueue { } pub impl WorkQueue { - static fn new() -> WorkQueue { + fn new() -> WorkQueue { WorkQueue { queue: ~[] } diff --git a/src/libcore/run.rs b/src/libcore/run.rs index d3affbc69fe91..088c10cbc1d51 100644 --- a/src/libcore/run.rs +++ b/src/libcore/run.rs @@ -182,7 +182,7 @@ fn with_dirp(d: &Option<~str>, * * # Return value * - * The process id + * The process's exit code */ pub fn run_program(prog: &str, args: &[~str]) -> int { let pid = spawn_process(prog, args, &None, &None, @@ -303,7 +303,7 @@ fn read_all(rd: io::Reader) -> ~str { let mut bytes = [0, ..4096]; while !rd.eof() { let nread = rd.read(bytes, bytes.len()); - wr.write(bytes.view(0, nread)); + wr.write(bytes.slice(0, nread)); } }); str::from_bytes(buf) @@ -404,7 +404,7 @@ pub fn readclose(fd: c_int) -> ~str { let mut bytes = [0, ..4096]; while !reader.eof() { let nread = reader.read(bytes, bytes.len()); - writer.write(bytes.view(0, nread)); + writer.write(bytes.slice(0, nread)); } }); os::fclose(file); diff --git a/src/libcore/str.rs b/src/libcore/str.rs index 3d591af6d3c43..92358c6a5e97b 100644 --- a/src/libcore/str.rs +++ b/src/libcore/str.rs @@ -29,6 +29,7 @@ use str; use u8; use uint; use vec; +use to_str::ToStr; #[cfg(notest)] use cmp::{Eq, Ord}; @@ -43,14 +44,27 @@ Section: Creating a string * * Fails if invalid UTF-8 */ -pub pure fn from_bytes(vv: &[const u8]) -> ~str { +pub fn from_bytes(vv: &[const u8]) -> ~str { fail_unless!(is_utf8(vv)); return unsafe { raw::from_bytes(vv) }; } /// Copy a slice into a new unique str -pub pure fn from_slice(s: &str) -> ~str { - unsafe { raw::slice_bytes(s, 0, len(s)) } +pub fn from_slice(s: &str) -> ~str { + unsafe { raw::slice_bytes_unique(s, 0, len(s)) } +} + +impl ToStr for ~str { + #[inline(always)] + fn to_str(&self) -> ~str { copy *self } +} +impl ToStr for &'self str { + #[inline(always)] + fn to_str(&self) -> ~str { ::str::from_slice(*self) } +} +impl ToStr for @str { + #[inline(always)] + fn to_str(&self) -> ~str { ::str::from_slice(*self) } } /** @@ -60,7 +74,7 @@ pub pure fn from_slice(s: &str) -> ~str { * * Fails if invalid UTF-8 */ -pub pure fn from_byte(b: u8) -> ~str { +pub fn from_byte(b: u8) -> ~str { fail_unless!(b < 128u8); unsafe { ::cast::transmute(~[b, 0u8]) } } @@ -137,14 +151,14 @@ pub fn push_char(s: &mut ~str, ch: char) { } /// Convert a char to a string -pub pure fn from_char(ch: char) -> ~str { +pub fn from_char(ch: char) -> ~str { let mut buf = ~""; unsafe { push_char(&mut buf, ch); } buf } /// Convert a vector of chars to a string -pub pure fn from_chars(chs: &[char]) -> ~str { +pub fn from_chars(chs: &[char]) -> ~str { let mut buf = ~""; unsafe { reserve(&mut buf, chs.len()); @@ -192,7 +206,7 @@ pub fn push_str(lhs: &mut ~str, rhs: &str) { /// Concatenate two strings together #[inline(always)] -pub pure fn append(lhs: ~str, rhs: &str) -> ~str { +pub fn append(lhs: ~str, rhs: &str) -> ~str { let mut v = lhs; unsafe { push_str_no_overallocate(&mut v, rhs); @@ -202,7 +216,7 @@ pub pure fn append(lhs: ~str, rhs: &str) -> ~str { /// Concatenate a vector of strings -pub pure fn concat(v: &[~str]) -> ~str { +pub fn concat(v: &[~str]) -> ~str { let mut s: ~str = ~""; for vec::each(v) |ss| { unsafe { push_str(&mut s, *ss) }; @@ -211,7 +225,7 @@ pub pure fn concat(v: &[~str]) -> ~str { } /// Concatenate a vector of strings, placing a given separator between each -pub pure fn connect(v: &[~str], sep: &str) -> ~str { +pub 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); } } @@ -221,7 +235,7 @@ pub pure fn connect(v: &[~str], sep: &str) -> ~str { } /// Concatenate a vector of strings, placing a given separator between each -pub pure fn connect_slices(v: &[&str], sep: &str) -> ~str { +pub fn connect_slices(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); } } @@ -231,7 +245,7 @@ pub pure fn connect_slices(v: &[&str], sep: &str) -> ~str { } /// Given a string, make a new string with repeated copies of it -pub pure fn repeat(ss: &str, nn: uint) -> ~str { +pub fn repeat(ss: &str, nn: uint) -> ~str { let mut acc = ~""; for nn.times { acc += ss; } acc @@ -265,7 +279,7 @@ pub fn pop_char(s: &mut ~str) -> char { */ pub fn shift_char(s: &mut ~str) -> char { let CharRange {ch, next} = char_range_at(*s, 0u); - *s = unsafe { raw::slice_bytes(*s, next, len(*s)) }; + *s = unsafe { raw::slice_bytes_unique(*s, next, len(*s)) }; return ch; } @@ -279,9 +293,9 @@ pub fn shift_char(s: &mut ~str) -> char { * If the string does not contain any characters */ #[inline] -pub fn view_shift_char(s: &'a str) -> (char, &'a str) { +pub fn slice_shift_char(s: &'a str) -> (char, &'a str) { let CharRange {ch, next} = char_range_at(s, 0u); - let next_s = unsafe { raw::view_bytes(s, next, len(s)) }; + let next_s = unsafe { raw::slice_bytes(s, next, len(s)) }; return (ch, next_s); } @@ -299,11 +313,11 @@ pub fn unshift_char(s: &mut ~str, ch: char) { * * chars_to_trim - A vector of chars * */ -pub pure fn trim_left_chars(s: &str, chars_to_trim: &[char]) -> ~str { - if chars_to_trim.is_empty() { return from_slice(s); } +pub fn trim_left_chars(s: &'a str, chars_to_trim: &[char]) -> &'a str { + if chars_to_trim.is_empty() { return s; } match find(s, |c| !chars_to_trim.contains(&c)) { - None => ~"", + None => "", Some(first) => unsafe { raw::slice_bytes(s, first, s.len()) } } } @@ -317,11 +331,11 @@ pub pure fn trim_left_chars(s: &str, chars_to_trim: &[char]) -> ~str { * * chars_to_trim - A vector of chars * */ -pub pure fn trim_right_chars(s: &str, chars_to_trim: &[char]) -> ~str { - if chars_to_trim.is_empty() { return str::from_slice(s); } +pub fn trim_right_chars(s: &'a str, chars_to_trim: &[char]) -> &'a str { + if chars_to_trim.is_empty() { return s; } match rfind(s, |c| !chars_to_trim.contains(&c)) { - None => ~"", + None => "", Some(last) => { let next = char_range_at(s, last).next; unsafe { raw::slice_bytes(s, 0u, next) } @@ -338,22 +352,22 @@ pub pure fn trim_right_chars(s: &str, chars_to_trim: &[char]) -> ~str { * * chars_to_trim - A vector of chars * */ -pub pure fn trim_chars(s: &str, chars_to_trim: &[char]) -> ~str { +pub fn trim_chars(s: &'a str, chars_to_trim: &[char]) -> &'a str { trim_left_chars(trim_right_chars(s, chars_to_trim), chars_to_trim) } /// Returns a string with leading whitespace removed -pub pure fn trim_left(s: &str) -> ~str { +pub fn trim_left(s: &'a str) -> &'a str { match find(s, |c| !char::is_whitespace(c)) { - None => ~"", + None => "", Some(first) => unsafe { raw::slice_bytes(s, first, len(s)) } } } /// Returns a string with trailing whitespace removed -pub pure fn trim_right(s: &str) -> ~str { +pub fn trim_right(s: &'a str) -> &'a str { match rfind(s, |c| !char::is_whitespace(c)) { - None => ~"", + None => "", Some(last) => { let next = char_range_at(s, last).next; unsafe { raw::slice_bytes(s, 0u, next) } @@ -362,7 +376,7 @@ pub pure fn trim_right(s: &str) -> ~str { } /// Returns a string with leading and trailing whitespace removed -pub pure fn trim(s: &str) -> ~str { trim_left(trim_right(s)) } +pub fn trim(s: &'a str) -> &'a str { trim_left(trim_right(s)) } /* Section: Transforming strings @@ -373,7 +387,7 @@ Section: Transforming strings * * The result vector is not null-terminated. */ -pub pure fn to_bytes(s: &str) -> ~[u8] { +pub fn to_bytes(s: &str) -> ~[u8] { unsafe { let mut v: ~[u8] = ::cast::transmute(from_slice(s)); vec::raw::set_len(&mut v, len(s)); @@ -383,14 +397,14 @@ pub pure fn to_bytes(s: &str) -> ~[u8] { /// Work with the string as a byte slice, not including trailing null. #[inline(always)] -pub pure fn byte_slice(s: &str, f: &fn(v: &[u8]) -> T) -> T { +pub fn byte_slice(s: &str, f: &fn(v: &[u8]) -> T) -> T { do as_buf(s) |p,n| { unsafe { vec::raw::buf_as_slice(p, n-1u, f) } } } /// Convert a string to a vector of characters -pub pure fn chars(s: &str) -> ~[char] { +pub fn chars(s: &str) -> ~[char] { let mut buf = ~[], i = 0; let len = len(s); while i < len { @@ -407,56 +421,53 @@ pub pure fn chars(s: &str) -> ~[char] { * Returns a string containing `n` characters starting at byte offset * `begin`. */ -pub pure fn substr(s: &str, begin: uint, n: uint) -> ~str { +pub fn substr(s: &'a str, begin: uint, n: uint) -> &'a str { slice(s, begin, begin + count_bytes(s, begin, n)) } /** * Returns a slice of the given string from the byte range [`begin`..`end`) * - * Fails when `begin` and `end` do not point to valid characters or - * beyond the last character of the string - */ -pub pure fn slice(s: &str, begin: uint, end: uint) -> ~str { - fail_unless!(is_char_boundary(s, begin)); - fail_unless!(is_char_boundary(s, end)); - unsafe { raw::slice_bytes(s, begin, end) } -} - -/** - * Returns a view of the given string from the byte range [`begin`..`end`) - * * Fails when `begin` and `end` do not point to valid characters or beyond * the last character of the string */ -pub pure fn view(s: &'a str, begin: uint, end: uint) -> &'a str { +pub fn slice(s: &'a str, begin: uint, end: uint) -> &'a str { fail_unless!(is_char_boundary(s, begin)); fail_unless!(is_char_boundary(s, end)); - unsafe { raw::view_bytes(s, begin, end) } + unsafe { raw::slice_bytes(s, begin, end) } } -/// Splits a string into substrings at each occurrence of a given character -pub pure fn split_char(s: &str, sep: char) -> ~[~str] { - split_char_inner(s, sep, len(s), true) +/// Splits a string into substrings at each occurrence of a given +/// character. +pub fn split_char(s: &str, sep: char) -> ~[~str] { + split_char_inner(s, sep, len(s), true, true) } /** * Splits a string into substrings at each occurrence of a given - * character up to 'count' times + * character up to 'count' times. * * The byte must be a valid UTF-8/ASCII byte */ -pub pure fn splitn_char(s: &str, sep: char, count: uint) -> ~[~str] { - split_char_inner(s, sep, count, true) +pub fn splitn_char(s: &str, sep: char, count: uint) -> ~[~str] { + split_char_inner(s, sep, count, true, true) } /// Like `split_char`, but omits empty strings from the returned vector -pub pure fn split_char_nonempty(s: &str, sep: char) -> ~[~str] { - split_char_inner(s, sep, len(s), false) +pub fn split_char_nonempty(s: &str, sep: char) -> ~[~str] { + split_char_inner(s, sep, len(s), false, false) +} + +/** + * Like `split_char`, but a trailing empty string is omitted + * (e.g. `split_char_no_trailing("A B ",' ') == ~[~"A",~"B"]`) + */ +pub fn split_char_no_trailing(s: &str, sep: char) -> ~[~str] { + split_char_inner(s, sep, len(s), true, false) } -pure fn split_char_inner(s: &str, sep: char, count: uint, allow_empty: bool) - -> ~[~str] { +fn split_char_inner(s: &str, sep: char, count: uint, allow_empty: bool, + allow_trailing_empty: bool) -> ~[~str] { if sep < 128u as char { let b = sep as u8, l = len(s); let mut result = ~[], done = 0u; @@ -465,7 +476,7 @@ pure fn split_char_inner(s: &str, sep: char, count: uint, allow_empty: bool) if s[i] == b { if allow_empty || start < i { unsafe { - result.push(raw::slice_bytes(s, start, i)); + result.push(raw::slice_bytes_unique(s, start, i)); } } start = i + 1u; @@ -473,39 +484,49 @@ pure fn split_char_inner(s: &str, sep: char, count: uint, allow_empty: bool) } i += 1u; } - if allow_empty || start < l { - unsafe { result.push(raw::slice_bytes(s, start, l) ) }; + // only push a non-empty trailing substring + if allow_trailing_empty || start < l { + unsafe { result.push(raw::slice_bytes_unique(s, start, l) ) }; } result } else { - splitn(s, |cur| cur == sep, count) + split_inner(s, |cur| cur == sep, count, allow_empty, allow_trailing_empty) } } /// Splits a string into substrings using a character function -pub pure fn split(s: &str, sepfn: &fn(char) -> bool) -> ~[~str] { - split_inner(s, sepfn, len(s), true) +pub fn split(s: &str, sepfn: &fn(char) -> bool) -> ~[~str] { + split_inner(s, sepfn, len(s), true, true) } /** * Splits a string into substrings using a character function, cutting at * most `count` times. */ -pub pure fn splitn(s: &str, +pub fn splitn(s: &str, sepfn: &fn(char) -> bool, count: uint) -> ~[~str] { - split_inner(s, sepfn, count, true) + split_inner(s, sepfn, count, true, true) } /// Like `split`, but omits empty strings from the returned vector -pub pure fn split_nonempty(s: &str, sepfn: &fn(char) -> bool) -> ~[~str] { - split_inner(s, sepfn, len(s), false) +pub fn split_nonempty(s: &str, sepfn: &fn(char) -> bool) -> ~[~str] { + split_inner(s, sepfn, len(s), false, false) +} + + +/** + * Like `split`, but a trailing empty string is omitted + * (e.g. `split_no_trailing("A B ",' ') == ~[~"A",~"B"]`) + */ +pub fn split_no_trailing(s: &str, sepfn: &fn(char) -> bool) -> ~[~str] { + split_inner(s, sepfn, len(s), true, false) } -pure fn split_inner(s: &str, sepfn: &fn(cc: char) -> bool, count: uint, - allow_empty: bool) -> ~[~str] { +fn split_inner(s: &str, sepfn: &fn(cc: char) -> bool, count: uint, + allow_empty: bool, allow_trailing_empty: bool) -> ~[~str] { let l = len(s); let mut result = ~[], i = 0u, start = 0u, done = 0u; while i < l && done < count { @@ -513,7 +534,7 @@ pure fn split_inner(s: &str, sepfn: &fn(cc: char) -> bool, count: uint, if sepfn(ch) { if allow_empty || start < i { unsafe { - result.push(raw::slice_bytes(s, start, i)); + result.push(raw::slice_bytes_unique(s, start, i)); } } start = next; @@ -521,16 +542,16 @@ pure fn split_inner(s: &str, sepfn: &fn(cc: char) -> bool, count: uint, } i = next; } - if allow_empty || start < l { + if allow_trailing_empty || start < l { unsafe { - result.push(raw::slice_bytes(s, start, l)); + result.push(raw::slice_bytes_unique(s, start, l)); } } result } // See Issue #1932 for why this is a naive search -pure fn iter_matches(s: &'a str, sep: &'b str, f: &fn(uint, uint)) { +fn iter_matches(s: &'a str, sep: &'b str, f: &fn(uint, uint)) { let sep_len = len(sep), l = len(s); fail_unless!(sep_len > 0u); let mut i = 0u, match_start = 0u, match_i = 0u; @@ -557,7 +578,7 @@ pure fn iter_matches(s: &'a str, sep: &'b str, f: &fn(uint, uint)) { } } -pure fn iter_between_matches(s: &'a str, sep: &'b str, f: &fn(uint, uint)) { +fn iter_between_matches(s: &'a str, sep: &'b str, f: &fn(uint, uint)) { let mut last_end = 0u; do iter_matches(s, sep) |from, to| { f(last_end, from); @@ -575,19 +596,19 @@ pure fn iter_between_matches(s: &'a str, sep: &'b str, f: &fn(uint, uint)) { * fail_unless!(["", "XXX", "YYY", ""] == split_str(".XXX.YYY.", ".")) * ~~~ */ -pub pure fn split_str(s: &'a str, sep: &'b str) -> ~[~str] { +pub fn split_str(s: &'a str, sep: &'b str) -> ~[~str] { let mut result = ~[]; do iter_between_matches(s, sep) |from, to| { - unsafe { result.push(raw::slice_bytes(s, from, to)); } + unsafe { result.push(raw::slice_bytes_unique(s, from, to)); } } result } -pub pure fn split_str_nonempty(s: &'a str, sep: &'b str) -> ~[~str] { +pub 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 { result.push(raw::slice_bytes(s, from, to)); } + unsafe { result.push(raw::slice_bytes_unique(s, from, to)); } } } result @@ -596,20 +617,20 @@ pub pure fn split_str_nonempty(s: &'a str, sep: &'b str) -> ~[~str] { /// Levenshtein Distance between two strings pub fn levdistance(s: &str, t: &str) -> uint { - let slen = str::len(s); - let tlen = str::len(t); + let slen = s.len(); + let tlen = t.len(); if slen == 0 { return tlen; } if tlen == 0 { return slen; } let mut dcol = vec::from_fn(tlen + 1, |x| x); - for str::each_chari(s) |i, sc| { + for s.each_chari |i, sc| { let mut current = i; dcol[0] = current + 1; - for str::each_chari(t) |j, tc| { + for t.each_chari |j, tc| { let mut next = dcol[j + 1]; @@ -628,15 +649,17 @@ pub fn levdistance(s: &str, t: &str) -> uint { } /** - * Splits a string into a vector of the substrings separated by LF ('\n') + * Splits a string into a vector of the substrings separated by LF ('\n'). */ -pub pure fn lines(s: &str) -> ~[~str] { split_char(s, '\n') } +pub fn lines(s: &str) -> ~[~str] { + split_char_no_trailing(s, '\n') +} /** * Splits a string into a vector of the substrings separated by LF ('\n') * and/or CR LF ("\r\n") */ -pub pure fn lines_any(s: &str) -> ~[~str] { +pub fn lines_any(s: &str) -> ~[~str] { vec::map(lines(s), |s| { let l = len(*s); let mut cp = copy *s; @@ -648,8 +671,8 @@ pub pure fn lines_any(s: &str) -> ~[~str] { } /// Splits a string into a vector of the substrings separated by whitespace -pub pure fn words(s: &str) -> ~[~str] { - split_nonempty(s, |c| char::is_whitespace(c)) +pub fn words(s: &str) -> ~[~str] { + split_nonempty(s, char::is_whitespace) } /** Split a string into a vector of substrings, @@ -687,14 +710,14 @@ pub fn split_within(ss: &str, lim: uint) -> ~[~str] { /// Convert a string to lowercase. ASCII only -pub pure fn to_lower(s: &str) -> ~str { +pub 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 -pub pure fn to_upper(s: &str) -> ~str { +pub fn to_upper(s: &str) -> ~str { map(s, |c| unsafe{(libc::toupper(c as libc::c_char)) as char} ) @@ -713,7 +736,7 @@ pub pure fn to_upper(s: &str) -> ~str { * * The original string with all occurances of `from` replaced with `to` */ -pub pure fn replace(s: &str, from: &str, to: &str) -> ~str { +pub fn replace(s: &str, from: &str, to: &str) -> ~str { let mut result = ~"", first = true; do iter_between_matches(s, from) |start, end| { if first { @@ -721,7 +744,7 @@ pub pure fn replace(s: &str, from: &str, to: &str) -> ~str { } else { unsafe { push_str(&mut result, to); } } - unsafe { push_str(&mut result, raw::slice_bytes(s, start, end)); } + unsafe { push_str(&mut result, raw::slice_bytes_unique(s, start, end)); } } result } @@ -733,7 +756,7 @@ Section: Comparing strings /// Bytewise slice equality #[cfg(notest)] #[lang="str_eq"] -pub pure fn eq_slice(a: &str, b: &str) -> bool { +pub fn eq_slice(a: &str, b: &str) -> bool { do as_buf(a) |ap, alen| { do as_buf(b) |bp, blen| { if (alen != blen) { false } @@ -749,7 +772,7 @@ pub pure fn eq_slice(a: &str, b: &str) -> bool { } #[cfg(test)] -pub pure fn eq_slice(a: &str, b: &str) -> bool { +pub fn eq_slice(a: &str, b: &str) -> bool { do as_buf(a) |ap, alen| { do as_buf(b) |bp, blen| { if (alen != blen) { false } @@ -767,16 +790,16 @@ pub pure fn eq_slice(a: &str, b: &str) -> bool { /// Bytewise string equality #[cfg(notest)] #[lang="uniq_str_eq"] -pub pure fn eq(a: &~str, b: &~str) -> bool { +pub fn eq(a: &~str, b: &~str) -> bool { eq_slice(*a, *b) } #[cfg(test)] -pub pure fn eq(a: &~str, b: &~str) -> bool { +pub fn eq(a: &~str, b: &~str) -> bool { eq_slice(*a, *b) } -pure fn cmp(a: &str, b: &str) -> Ordering { +fn cmp(a: &str, b: &str) -> Ordering { let low = uint::min(a.len(), b.len()); for uint::range(0, low) |idx| { @@ -792,21 +815,21 @@ pure fn cmp(a: &str, b: &str) -> Ordering { #[cfg(notest)] impl TotalOrd for &'self str { - pure fn cmp(&self, other: & &'self str) -> Ordering { cmp(*self, *other) } + fn cmp(&self, other: & &'self str) -> Ordering { cmp(*self, *other) } } #[cfg(notest)] impl TotalOrd for ~str { - pure fn cmp(&self, other: &~str) -> Ordering { cmp(*self, *other) } + fn cmp(&self, other: &~str) -> Ordering { cmp(*self, *other) } } #[cfg(notest)] impl TotalOrd for @str { - pure fn cmp(&self, other: &@str) -> Ordering { cmp(*self, *other) } + fn cmp(&self, other: &@str) -> Ordering { cmp(*self, *other) } } /// Bytewise slice less than -pure fn lt(a: &str, b: &str) -> bool { +fn lt(a: &str, b: &str) -> bool { let (a_len, b_len) = (a.len(), b.len()); let mut end = uint::min(a_len, b_len); @@ -822,90 +845,90 @@ pure fn lt(a: &str, b: &str) -> bool { } /// Bytewise less than or equal -pub pure fn le(a: &str, b: &str) -> bool { +pub fn le(a: &str, b: &str) -> bool { !lt(b, a) } /// Bytewise greater than or equal -pure fn ge(a: &str, b: &str) -> bool { +fn ge(a: &str, b: &str) -> bool { !lt(a, b) } /// Bytewise greater than -pure fn gt(a: &str, b: &str) -> bool { +fn gt(a: &str, b: &str) -> bool { !le(a, b) } #[cfg(notest)] impl Eq for &'self str { #[inline(always)] - pure fn eq(&self, other: & &'self str) -> bool { + fn eq(&self, other: & &'self str) -> bool { eq_slice((*self), (*other)) } #[inline(always)] - pure fn ne(&self, other: & &'self str) -> bool { !(*self).eq(other) } + fn ne(&self, other: & &'self str) -> bool { !(*self).eq(other) } } #[cfg(notest)] impl Eq for ~str { #[inline(always)] - pure fn eq(&self, other: &~str) -> bool { + fn eq(&self, other: &~str) -> bool { eq_slice((*self), (*other)) } #[inline(always)] - pure fn ne(&self, other: &~str) -> bool { !(*self).eq(other) } + fn ne(&self, other: &~str) -> bool { !(*self).eq(other) } } #[cfg(notest)] impl Eq for @str { #[inline(always)] - pure fn eq(&self, other: &@str) -> bool { + fn eq(&self, other: &@str) -> bool { eq_slice((*self), (*other)) } #[inline(always)] - pure fn ne(&self, other: &@str) -> bool { !(*self).eq(other) } + fn ne(&self, other: &@str) -> bool { !(*self).eq(other) } } #[cfg(notest)] impl Ord for ~str { #[inline(always)] - pure fn lt(&self, other: &~str) -> bool { lt((*self), (*other)) } + fn lt(&self, other: &~str) -> bool { lt((*self), (*other)) } #[inline(always)] - pure fn le(&self, other: &~str) -> bool { le((*self), (*other)) } + fn le(&self, other: &~str) -> bool { le((*self), (*other)) } #[inline(always)] - pure fn ge(&self, other: &~str) -> bool { ge((*self), (*other)) } + fn ge(&self, other: &~str) -> bool { ge((*self), (*other)) } #[inline(always)] - pure fn gt(&self, other: &~str) -> bool { gt((*self), (*other)) } + fn gt(&self, other: &~str) -> bool { gt((*self), (*other)) } } #[cfg(notest)] impl Ord for &'self str { #[inline(always)] - pure fn lt(&self, other: & &'self str) -> bool { lt((*self), (*other)) } + fn lt(&self, other: & &'self str) -> bool { lt((*self), (*other)) } #[inline(always)] - pure fn le(&self, other: & &'self str) -> bool { le((*self), (*other)) } + fn le(&self, other: & &'self str) -> bool { le((*self), (*other)) } #[inline(always)] - pure fn ge(&self, other: & &'self str) -> bool { ge((*self), (*other)) } + fn ge(&self, other: & &'self str) -> bool { ge((*self), (*other)) } #[inline(always)] - pure fn gt(&self, other: & &'self str) -> bool { gt((*self), (*other)) } + fn gt(&self, other: & &'self str) -> bool { gt((*self), (*other)) } } #[cfg(notest)] impl Ord for @str { #[inline(always)] - pure fn lt(&self, other: &@str) -> bool { lt((*self), (*other)) } + fn lt(&self, other: &@str) -> bool { lt((*self), (*other)) } #[inline(always)] - pure fn le(&self, other: &@str) -> bool { le((*self), (*other)) } + fn le(&self, other: &@str) -> bool { le((*self), (*other)) } #[inline(always)] - pure fn ge(&self, other: &@str) -> bool { ge((*self), (*other)) } + fn ge(&self, other: &@str) -> bool { ge((*self), (*other)) } #[inline(always)] - pure fn gt(&self, other: &@str) -> bool { gt((*self), (*other)) } + fn gt(&self, other: &@str) -> bool { gt((*self), (*other)) } } #[cfg(notest)] impl Equiv<~str> for &'self str { #[inline(always)] - pure fn equiv(&self, other: &~str) -> bool { eq_slice(*self, *other) } + fn equiv(&self, other: &~str) -> bool { eq_slice(*self, *other) } } /* @@ -916,7 +939,7 @@ Section: Iterating through strings * Return true if a predicate matches all characters or if the string * contains no characters */ -pub pure fn all(s: &str, it: &fn(char) -> bool) -> bool { +pub fn all(s: &str, it: &fn(char) -> bool) -> bool { all_between(s, 0u, len(s), it) } @@ -924,16 +947,16 @@ pub 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) */ -pub pure fn any(ss: &str, pred: &fn(char) -> bool) -> bool { +pub fn any(ss: &str, pred: &fn(char) -> bool) -> bool { !all(ss, |cc| !pred(cc)) } /// Apply a function to each character -pub pure fn map(ss: &str, ff: &fn(char) -> char) -> ~str { +pub fn map(ss: &str, ff: &fn(char) -> char) -> ~str { let mut result = ~""; unsafe { reserve(&mut result, len(ss)); - for chars_each(ss) |cc| { + for ss.each_char |cc| { str::push_char(&mut result, ff(cc)); } } @@ -941,43 +964,51 @@ pub pure fn map(ss: &str, ff: &fn(char) -> char) -> ~str { } /// Iterate over the bytes in a string -pub pure fn bytes_each(ss: &str, it: &fn(u8) -> bool) { - let mut pos = 0u; - let len = len(ss); +#[inline(always)] +pub 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)] +pub fn eachi(s: &str, it: &fn(uint, u8) -> bool) { + let mut pos = 0; + let len = s.len(); - while (pos < len) { - if !it(ss[pos]) { return; } - pos += 1u; + while pos < len { + if !it(pos, s[pos]) { break; } + pos += 1; } } -/// Iterate over the bytes in a string +/// Iterate over the bytes in a string in reverse #[inline(always)] -pub pure fn each(s: &str, it: &fn(u8) -> bool) { - eachi(s, |_i, b| it(b) ) +pub fn each_reverse(s: &str, it: &fn(u8) -> bool) { + eachi_reverse(s, |_i, b| it(b) ) } -/// Iterate over the bytes in a string, with indices +/// Iterate over the bytes in a string in reverse, with indices #[inline(always)] -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; } - i += 1u; +pub fn eachi_reverse(s: &str, it: &fn(uint, u8) -> bool) { + let mut pos = s.len(); + while pos > 0 { + pos -= 1; + if !it(pos, s[pos]) { break; } } } /// Iterates over the chars in a string #[inline(always)] -pub pure fn each_char(s: &str, it: &fn(char) -> bool) { +pub 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)] -pub pure fn each_chari(s: &str, it: &fn(uint, char) -> bool) { - let mut pos = 0u, ch_pos = 0u; - let len = len(s); +pub fn each_chari(s: &str, it: &fn(uint, char) -> bool) { + let mut pos = 0; + let mut ch_pos = 0u; + let len = s.len(); while pos < len { let CharRange {ch, next} = char_range_at(s, pos); pos = next; @@ -986,19 +1017,29 @@ pub pure fn each_chari(s: &str, it: &fn(uint, char) -> bool) { } } -/// Iterate over the characters in a string -pub pure fn chars_each(s: &str, it: &fn(char) -> bool) { - let mut pos = 0u; - let len = len(s); - while (pos < len) { - let CharRange {ch, next} = char_range_at(s, pos); +/// Iterates over the chars in a string in reverse +#[inline(always)] +pub fn each_char_reverse(s: &str, it: &fn(char) -> bool) { + each_chari_reverse(s, |_, c| it(c)) +} + +// Iterates over the chars in a string in reverse, with indices +#[inline(always)] +pub fn each_chari_reverse(s: &str, it: &fn(uint, char) -> bool) { + let mut pos = s.len(); + let mut ch_pos = s.char_len(); + while pos > 0 { + let CharRange {ch, next} = char_range_at_reverse(s, pos); pos = next; - if !it(ch) { return; } + ch_pos -= 1; + + if !it(ch_pos, ch) { break; } + } } /// Apply a function to each substring after splitting by character -pub pure fn split_char_each(ss: &str, cc: char, ff: &fn(v: &str) -> bool) { +pub fn split_char_each(ss: &str, cc: char, ff: &fn(v: &str) -> bool) { vec::each(split_char(ss, cc), |s| ff(*s)) } @@ -1006,20 +1047,20 @@ pub 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 */ -pub pure fn splitn_char_each(ss: &str, sep: char, count: uint, +pub 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 -pub pure fn words_each(ss: &str, ff: &fn(v: &str) -> bool) { +pub 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') */ -pub pure fn lines_each(ss: &str, ff: &fn(v: &str) -> bool) { +pub fn lines_each(ss: &str, ff: &fn(v: &str) -> bool) { vec::each(lines(ss), |s| ff(*s)) } @@ -1040,7 +1081,7 @@ Section: Searching * An `option` containing the byte index of the first matching character * or `none` if there is no match */ -pub pure fn find_char(s: &str, c: char) -> Option { +pub fn find_char(s: &str, c: char) -> Option { find_char_between(s, c, 0u, len(s)) } @@ -1064,7 +1105,7 @@ pub 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`. */ -pub pure fn find_char_from(s: &str, c: char, start: uint) -> Option { +pub fn find_char_from(s: &str, c: char, start: uint) -> Option { find_char_between(s, c, start, len(s)) } @@ -1089,7 +1130,7 @@ pub 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`. */ -pub pure fn find_char_between(s: &str, c: char, start: uint, end: uint) +pub fn find_char_between(s: &str, c: char, start: uint, end: uint) -> Option { if c < 128u as char { fail_unless!(start <= end); @@ -1119,7 +1160,7 @@ pub 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 */ -pub pure fn rfind_char(s: &str, c: char) -> Option { +pub fn rfind_char(s: &str, c: char) -> Option { rfind_char_between(s, c, len(s), 0u) } @@ -1143,7 +1184,7 @@ pub 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`. */ -pub pure fn rfind_char_from(s: &str, c: char, start: uint) -> Option { +pub fn rfind_char_from(s: &str, c: char, start: uint) -> Option { rfind_char_between(s, c, start, 0u) } @@ -1168,7 +1209,7 @@ pub 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`. */ -pub pure fn rfind_char_between(s: &str, c: char, start: uint, end: uint) +pub fn rfind_char_between(s: &str, c: char, start: uint, end: uint) -> Option { if c < 128u as char { fail_unless!(start >= end); @@ -1199,7 +1240,7 @@ pub 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 */ -pub pure fn find(s: &str, f: &fn(char) -> bool) -> Option { +pub fn find(s: &str, f: &fn(char) -> bool) -> Option { find_between(s, 0u, len(s), f) } @@ -1223,7 +1264,7 @@ pub 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`. */ -pub pure fn find_from(s: &str, start: uint, f: &fn(char) +pub fn find_from(s: &str, start: uint, f: &fn(char) -> bool) -> Option { find_between(s, start, len(s), f) } @@ -1250,7 +1291,7 @@ pub 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`. */ -pub pure fn find_between(s: &str, +pub fn find_between(s: &str, start: uint, end: uint, f: &fn(char) -> bool) @@ -1281,7 +1322,7 @@ pub pure fn find_between(s: &str, * An option containing the byte index of the last matching character * or `none` if there is no match */ -pub pure fn rfind(s: &str, f: &fn(char) -> bool) -> Option { +pub fn rfind(s: &str, f: &fn(char) -> bool) -> Option { rfind_between(s, len(s), 0u, f) } @@ -1305,7 +1346,7 @@ pub 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` */ -pub pure fn rfind_from(s: &str, start: uint, f: &fn(char) -> bool) +pub fn rfind_from(s: &str, start: uint, f: &fn(char) -> bool) -> Option { rfind_between(s, start, 0u, f) } @@ -1332,7 +1373,7 @@ pub 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` */ -pub pure fn rfind_between(s: &str, start: uint, end: uint, +pub fn rfind_between(s: &str, start: uint, end: uint, f: &fn(char) -> bool) -> Option { fail_unless!(start >= end); @@ -1348,7 +1389,7 @@ pub pure fn rfind_between(s: &str, start: uint, end: uint, } // Utility used by various searching functions -pure fn match_at(haystack: &'a str, needle: &'b str, at: uint) -> bool { +fn match_at(haystack: &'a str, needle: &'b str, at: uint) -> bool { let mut i = at; for each(needle) |c| { if haystack[i] != c { return false; } i += 1u; } return true; @@ -1367,7 +1408,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 */ -pub pure fn find_str(haystack: &'a str, needle: &'b str) -> Option { +pub fn find_str(haystack: &'a str, needle: &'b str) -> Option { find_str_between(haystack, needle, 0u, len(haystack)) } @@ -1390,7 +1431,7 @@ pub pure fn find_str(haystack: &'a str, needle: &'b str) -> Option { * * `start` must be less than or equal to `len(s)` */ -pub pure fn find_str_from(haystack: &'a str, needle: &'b str, start: uint) +pub fn find_str_from(haystack: &'a str, needle: &'b str, start: uint) -> Option { find_str_between(haystack, needle, start, len(haystack)) } @@ -1415,7 +1456,7 @@ pub 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)`. */ -pub pure fn find_str_between(haystack: &'a str, needle: &'b str, start: uint, +pub 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 @@ -1441,7 +1482,7 @@ pub 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 */ -pub pure fn contains(haystack: &'a str, needle: &'b str) -> bool { +pub fn contains(haystack: &'a str, needle: &'b str) -> bool { find_str(haystack, needle).is_some() } @@ -1453,7 +1494,7 @@ pub pure fn contains(haystack: &'a str, needle: &'b str) -> bool { * * haystack - The string to look in * * needle - The char to look for */ -pub pure fn contains_char(haystack: &str, needle: char) -> bool { +pub fn contains_char(haystack: &str, needle: char) -> bool { find_char(haystack, needle).is_some() } @@ -1465,7 +1506,7 @@ pub pure fn contains_char(haystack: &str, needle: char) -> bool { * * haystack - The string to look in * * needle - The string to look for */ -pub pure fn starts_with(haystack: &'a str, needle: &'b str) -> bool { +pub 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 } @@ -1480,7 +1521,7 @@ pub pure fn starts_with(haystack: &'a str, needle: &'b str) -> bool { * * haystack - The string to look in * * needle - The string to look for */ -pub pure fn ends_with(haystack: &'a str, needle: &'b str) -> bool { +pub 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 } @@ -1492,21 +1533,21 @@ Section: String properties */ /// Determines if a string contains only ASCII characters -pub pure fn is_ascii(s: &str) -> bool { +pub 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 -pub pure fn is_empty(s: &str) -> bool { len(s) == 0u } +pub fn is_empty(s: &str) -> bool { len(s) == 0u } /** * Returns true if the string contains only whitespace * * Whitespace characters are determined by `char::is_whitespace` */ -pub pure fn is_whitespace(s: &str) -> bool { +pub fn is_whitespace(s: &str) -> bool { return all(s, char::is_whitespace); } @@ -1515,24 +1556,24 @@ pub pure fn is_whitespace(s: &str) -> bool { * * Alphanumeric characters are determined by `char::is_alphanumeric` */ -pure fn is_alphanumeric(s: &str) -> bool { +fn is_alphanumeric(s: &str) -> bool { return all(s, char::is_alphanumeric); } /// Returns the string length/size in bytes not counting the null terminator -pub pure fn len(s: &str) -> uint { +pub fn len(s: &str) -> uint { do as_buf(s) |_p, n| { n - 1u } } /// Returns the number of characters that a string holds -pub pure fn char_len(s: &str) -> uint { count_chars(s, 0u, len(s)) } +pub fn char_len(s: &str) -> uint { count_chars(s, 0u, len(s)) } /* Section: Misc */ /// Determines if a vector of bytes contains valid UTF-8 -pub pure fn is_utf8(v: &[const u8]) -> bool { +pub fn is_utf8(v: &[const u8]) -> bool { let mut i = 0u; let total = vec::len::(v); while i < total { @@ -1550,7 +1591,7 @@ pub pure fn is_utf8(v: &[const u8]) -> bool { } /// Determines if a vector of `u16` contains valid UTF-16 -pub pure fn is_utf16(v: &[u16]) -> bool { +pub fn is_utf16(v: &[u16]) -> bool { let len = vec::len(v); let mut i = 0u; while (i < len) { @@ -1571,11 +1612,11 @@ pub pure fn is_utf16(v: &[u16]) -> bool { } /// Converts to a vector of `u16` encoded as UTF-16 -pub pure fn to_utf16(s: &str) -> ~[u16] { +pub fn to_utf16(s: &str) -> ~[u16] { let mut u = ~[]; - for chars_each(s) |cch| { + for s.each_char |ch| { // Arithmetic with u32 literals is easier on the eyes than chars. - let mut ch = cch as u32; + let mut ch = ch as u32; unsafe { if (ch & 0xFFFF_u32) == ch { @@ -1596,7 +1637,7 @@ pub pure fn to_utf16(s: &str) -> ~[u16] { u } -pub pure fn utf16_chars(v: &[u16], f: &fn(char)) { +pub fn utf16_chars(v: &[u16], f: &fn(char)) { let len = vec::len(v); let mut i = 0u; while (i < len && v[i] != 0u16) { @@ -1621,7 +1662,7 @@ pub pure fn utf16_chars(v: &[u16], f: &fn(char)) { } -pub pure fn from_utf16(v: &[u16]) -> ~str { +pub fn from_utf16(v: &[u16]) -> ~str { let mut buf = ~""; unsafe { reserve(&mut buf, vec::len(v)); @@ -1630,7 +1671,7 @@ pub pure fn from_utf16(v: &[u16]) -> ~str { buf } -pub pure fn with_capacity(capacity: uint) -> ~str { +pub fn with_capacity(capacity: uint) -> ~str { let mut buf = ~""; unsafe { reserve(&mut buf, capacity); } buf @@ -1649,7 +1690,7 @@ pub pure fn with_capacity(capacity: uint) -> ~str { * * The number of Unicode characters in `s` between the given indices. */ -pub pure fn count_chars(s: &str, start: uint, end: uint) -> uint { +pub fn count_chars(s: &str, start: uint, end: uint) -> uint { fail_unless!(is_char_boundary(s, start)); fail_unless!(is_char_boundary(s, end)); let mut i = start, len = 0u; @@ -1662,7 +1703,7 @@ pub 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`. -pub pure fn count_bytes(s: &'b str, start: uint, n: uint) -> uint { +pub fn count_bytes(s: &'b str, start: uint, n: uint) -> uint { fail_unless!(is_char_boundary(s, start)); let mut end = start, cnt = n; let l = len(s); @@ -1676,7 +1717,7 @@ pub 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 -pub pure fn utf8_char_width(b: u8) -> uint { +pub fn utf8_char_width(b: u8) -> uint { let byte: uint = b as uint; if byte < 128u { return 1u; } // Not a valid start byte @@ -1692,7 +1733,7 @@ pub pure fn utf8_char_width(b: u8) -> uint { * Returns false if the index points into the middle of a multi-byte * character sequence. */ -pub pure fn is_char_boundary(s: &str, index: uint) -> bool { +pub fn is_char_boundary(s: &str, index: uint) -> bool { if index == len(s) { return true; } let b = s[index]; return b < 128u8 || b >= 192u8; @@ -1747,7 +1788,7 @@ pub 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. */ -pub pure fn char_range_at(s: &str, i: uint) -> CharRange { +pub fn char_range_at(s: &str, i: uint) -> CharRange { let b0 = s[i]; let w = utf8_char_width(b0); fail_unless!((w != 0u)); @@ -1769,8 +1810,8 @@ pub pure fn char_range_at(s: &str, i: uint) -> CharRange { return CharRange {ch: val as char, next: i}; } -/// Pluck a character out of a string -pub pure fn char_at(s: &str, i: uint) -> char { +/// Plucks the `n`th character from the beginning of a string +pub fn char_at(s: &str, i: uint) -> char { return char_range_at(s, i).ch; } @@ -1784,7 +1825,7 @@ pub struct CharRange { * * This function can be used to iterate over a unicode string in reverse. */ -pure fn char_range_at_reverse(ss: &str, start: uint) -> CharRange { +fn char_range_at_reverse(ss: &str, start: uint) -> CharRange { let mut prev = start; // while there is a previous byte == 10...... @@ -1799,6 +1840,11 @@ pure fn char_range_at_reverse(ss: &str, start: uint) -> CharRange { return CharRange {ch:ch, next:prev}; } +/// Plucks the `n`th character from the end of a string +pub fn char_at_reverse(s: &str, i: uint) -> char { + char_range_at_reverse(s, i).ch +} + /** * Loop through a substring, char by char * @@ -1821,7 +1867,7 @@ pure fn char_range_at_reverse(ss: &str, start: uint) -> CharRange { * `true` If execution proceeded correctly, `false` if it was interrupted, * that is if `it` returned `false` at any point. */ -pub pure fn all_between(s: &str, start: uint, end: uint, +pub fn all_between(s: &str, start: uint, end: uint, it: &fn(char) -> bool) -> bool { fail_unless!(is_char_boundary(s, start)); let mut i = start; @@ -1854,32 +1900,32 @@ pub pure fn all_between(s: &str, start: uint, end: uint, * * `true` if `it` returns `true` for any character */ -pub pure fn any_between(s: &str, start: uint, end: uint, +pub fn any_between(s: &str, start: uint, end: uint, it: &fn(char) -> bool) -> bool { !all_between(s, start, end, |c| !it(c)) } // UTF-8 tags and ranges -const tag_cont_u8: u8 = 128u8; -const tag_cont: uint = 128u; -const max_one_b: uint = 128u; -const tag_two_b: uint = 192u; -const max_two_b: uint = 2048u; -const tag_three_b: uint = 224u; -const max_three_b: uint = 65536u; -const tag_four_b: uint = 240u; -const max_four_b: uint = 2097152u; -const tag_five_b: uint = 248u; -const max_five_b: uint = 67108864u; -const tag_six_b: uint = 252u; +static tag_cont_u8: u8 = 128u8; +static tag_cont: uint = 128u; +static max_one_b: uint = 128u; +static tag_two_b: uint = 192u; +static max_two_b: uint = 2048u; +static tag_three_b: uint = 224u; +static max_three_b: uint = 65536u; +static tag_four_b: uint = 240u; +static max_four_b: uint = 2097152u; +static tag_five_b: uint = 248u; +static max_five_b: uint = 67108864u; +static tag_six_b: uint = 252u; // Constants used for converting strs to floats -pub const inf_buf: [u8*3] = ['i' as u8, 'n' as u8, 'f' as u8]; -pub const positive_inf_buf: [u8*4] = ['+' as u8, 'i' as u8, - 'n' as u8, 'f' as u8]; -pub const negative_inf_buf: [u8*4] = ['-' as u8, 'i' as u8, - 'n' as u8, 'f' as u8]; -pub const nan_buf: [u8*3] = ['N' as u8, 'a' as u8, 'N' as u8]; +pub static inf_buf: [u8*3] = ['i' as u8, 'n' as u8, 'f' as u8]; +pub static positive_inf_buf: [u8*4] = ['+' as u8, 'i' as u8, + 'n' as u8, 'f' as u8]; +pub static negative_inf_buf: [u8*4] = ['-' as u8, 'i' as u8, + 'n' as u8, 'f' as u8]; +pub static nan_buf: [u8*3] = ['N' as u8, 'a' as u8, 'N' as u8]; /** * Work with the byte buffer of a string. @@ -1893,7 +1939,7 @@ pub const nan_buf: [u8*3] = ['N' as u8, 'a' as u8, 'N' as u8]; * let i = str::as_bytes("Hello World") { |bytes| vec::len(bytes) }; * ~~~ */ -pub pure fn as_bytes(s: &const ~str, f: &fn(&~[u8]) -> T) -> T { +pub fn as_bytes(s: &const ~str, f: &fn(&~[u8]) -> T) -> T { unsafe { let v: *~[u8] = cast::transmute(copy s); f(&*v) @@ -1905,7 +1951,7 @@ pub pure fn as_bytes(s: &const ~str, f: &fn(&~[u8]) -> T) -> T { * * The byte slice does not include the null terminator. */ -pub pure fn as_bytes_slice(s: &'a str) -> &'a [u8] { +pub 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); @@ -1928,7 +1974,7 @@ pub pure fn as_bytes_slice(s: &'a str) -> &'a [u8] { * let s = str::as_c_str("PATH", { |path| libc::getenv(path) }); * ~~~ */ -pub pure fn as_c_str(s: &str, f: &fn(*libc::c_char) -> T) -> T { +pub 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. fail_unless!(len > 0); @@ -1950,7 +1996,7 @@ pub pure fn as_c_str(s: &str, f: &fn(*libc::c_char) -> T) -> T { * to full strings, or suffixes of them. */ #[inline(always)] -pub pure fn as_buf(s: &str, f: &fn(*u8, uint) -> T) -> T { +pub fn as_buf(s: &str, f: &fn(*u8, uint) -> T) -> T { unsafe { let v : *(*u8,uint) = ::cast::reinterpret_cast(&ptr::addr_of(&s)); let (buf,len) = *v; @@ -2009,7 +2055,7 @@ pub fn reserve_at_least(s: &mut ~str, n: uint) { * Returns the number of single-byte characters the string can hold without * reallocating */ -pub pure fn capacity(s: &const ~str) -> uint { +pub fn capacity(s: &const ~str) -> uint { do as_bytes(s) |buf| { let vcap = vec::capacity(buf); fail_unless!(vcap > 0u); @@ -2018,11 +2064,11 @@ pub pure fn capacity(s: &const ~str) -> uint { } /// Escape each char in `s` with char::escape_default. -pub pure fn escape_default(s: &str) -> ~str { +pub fn escape_default(s: &str) -> ~str { let mut out: ~str = ~""; unsafe { reserve_at_least(&mut out, str::len(s)); - for chars_each(s) |c| { + for s.each_char |c| { push_str(&mut out, char::escape_default(c)); } } @@ -2030,11 +2076,11 @@ pub pure fn escape_default(s: &str) -> ~str { } /// Escape each char in `s` with char::escape_unicode. -pub pure fn escape_unicode(s: &str) -> ~str { +pub fn escape_unicode(s: &str) -> ~str { let mut out: ~str = ~""; unsafe { reserve_at_least(&mut out, str::len(s)); - for chars_each(s) |c| { + for s.each_char |c| { push_str(&mut out, char::escape_unicode(c)); } } @@ -2111,7 +2157,7 @@ pub mod raw { * If begin is greater than end. * If end is greater than the length of the string. */ - pub unsafe fn slice_bytes(s: &str, begin: uint, end: uint) -> ~str { + pub unsafe fn slice_bytes_unique(s: &str, begin: uint, end: uint) -> ~str { do as_buf(s) |sbuf, n| { fail_unless!((begin <= end)); fail_unless!((end <= n)); @@ -2131,7 +2177,7 @@ pub mod raw { } /** - * Takes a bytewise (not UTF-8) view from a string. + * Takes a bytewise (not UTF-8) slice from a string. * * Returns the substring from [`begin`..`end`). * @@ -2141,7 +2187,7 @@ pub mod raw { * If end is greater than the length of the string. */ #[inline] - pub unsafe fn view_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| { fail_unless!((begin <= end)); fail_unless!((end <= n)); @@ -2183,7 +2229,7 @@ pub mod raw { let len = len(*s); fail_unless!((len > 0u)); let b = s[0]; - *s = unsafe { raw::slice_bytes(*s, 1u, len) }; + *s = unsafe { raw::slice_bytes_unique(*s, 1u, len) }; return b; } @@ -2209,25 +2255,6 @@ pub mod raw { } -pub trait Trimmable { - pure fn trim(&self) -> Self; - pure fn trim_left(&self) -> Self; - pure fn trim_right(&self) -> Self; -} - -/// Extension methods for strings -impl Trimmable for ~str { - /// Returns a string with leading and trailing whitespace removed - #[inline] - pure fn trim(&self) -> ~str { trim(*self) } - /// Returns a string with leading whitespace removed - #[inline] - pure fn trim_left(&self) -> ~str { trim_left(*self) } - /// Returns a string with trailing whitespace removed - #[inline] - pure fn trim_right(&self) -> ~str { trim_right(*self) } -} - #[cfg(notest)] pub mod traits { use ops::Add; @@ -2235,7 +2262,7 @@ pub mod traits { impl Add<&'self str,~str> for ~str { #[inline(always)] - pure fn add(&self, rhs: & &'self str) -> ~str { + fn add(&self, rhs: & &'self str) -> ~str { append(copy *self, (*rhs)) } } @@ -2245,35 +2272,44 @@ pub mod traits { pub mod traits {} pub trait StrSlice { - pure fn all(&self, it: &fn(char) -> bool) -> bool; - pure fn any(&self, it: &fn(char) -> bool) -> bool; - pure fn contains(&self, needle: &'a str) -> bool; - pure fn contains_char(&self, needle: char) -> bool; - pure fn each(&self, it: &fn(u8) -> bool); - pure fn eachi(&self, it: &fn(uint, u8) -> bool); - pure fn each_char(&self, it: &fn(char) -> bool); - pure fn each_chari(&self, it: &fn(uint, char) -> bool); - pure fn ends_with(&self, needle: &str) -> bool; - pure fn is_empty(&self) -> bool; - pure fn is_whitespace(&self) -> bool; - pure fn is_alphanumeric(&self) -> bool; - pure fn len(&self) -> uint; - pure fn slice(&self, begin: uint, end: uint) -> ~str; - pure fn split(&self, sepfn: &fn(char) -> bool) -> ~[~str]; - pure fn split_char(&self, sep: char) -> ~[~str]; - pure fn split_str(&self, sep: &'a str) -> ~[~str]; - pure fn starts_with(&self, needle: &'a str) -> bool; - pure fn substr(&self, begin: uint, n: uint) -> ~str; - pure fn to_lower(&self) -> ~str; - pure fn to_upper(&self) -> ~str; - pure fn escape_default(&self) -> ~str; - pure fn escape_unicode(&self) -> ~str; - pure fn trim(&self) -> ~str; - pure fn trim_left(&self) -> ~str; - pure fn trim_right(&self) -> ~str; - pure fn to_owned(&self) -> ~str; - pure fn to_managed(&self) -> @str; - pure fn char_at(&self, i: uint) -> char; + fn all(&self, it: &fn(char) -> bool) -> bool; + fn any(&self, it: &fn(char) -> bool) -> bool; + fn contains(&self, needle: &'a str) -> bool; + fn contains_char(&self, needle: char) -> bool; + fn each(&self, it: &fn(u8) -> bool); + fn eachi(&self, it: &fn(uint, u8) -> bool); + fn each_reverse(&self, it: &fn(u8) -> bool); + fn eachi_reverse(&self, it: &fn(uint, u8) -> bool); + fn each_char(&self, it: &fn(char) -> bool); + fn each_chari(&self, it: &fn(uint, char) -> bool); + fn each_char_reverse(&self, it: &fn(char) -> bool); + fn each_chari_reverse(&self, it: &fn(uint, char) -> bool); + fn ends_with(&self, needle: &str) -> bool; + fn is_empty(&self) -> bool; + fn is_whitespace(&self) -> bool; + fn is_alphanumeric(&self) -> bool; + fn len(&self) -> uint; + fn char_len(&self) -> uint; + fn slice(&self, begin: uint, end: uint) -> &'self str; + fn split(&self, sepfn: &fn(char) -> bool) -> ~[~str]; + fn split_char(&self, sep: char) -> ~[~str]; + fn split_str(&self, sep: &'a str) -> ~[~str]; + fn starts_with(&self, needle: &'a str) -> bool; + fn substr(&self, begin: uint, n: uint) -> &'self str; + fn to_lower(&self) -> ~str; + fn to_upper(&self) -> ~str; + fn escape_default(&self) -> ~str; + fn escape_unicode(&self) -> ~str; + fn trim(&self) -> &'self str; + fn trim_left(&self) -> &'self str; + fn trim_right(&self) -> &'self str; + fn trim_chars(&self, chars_to_trim: &[char]) -> &'self str; + fn trim_left_chars(&self, chars_to_trim: &[char]) -> &'self str; + fn trim_right_chars(&self, chars_to_trim: &[char]) -> &'self str; + fn to_owned(&self) -> ~str; + fn to_managed(&self) -> @str; + fn char_at(&self, i: uint) -> char; + fn char_at_reverse(&self, i: uint) -> char; fn to_bytes(&self) -> ~[u8]; } @@ -2284,62 +2320,86 @@ impl StrSlice for &'self str { * contains no characters */ #[inline] - pure fn all(&self, it: &fn(char) -> bool) -> bool { all(*self, it) } + fn all(&self, it: &fn(char) -> bool) -> bool { all(*self, it) } /** * Return true if a predicate matches any character (and false if it * matches none or there are no characters) */ #[inline] - pure fn any(&self, it: &fn(char) -> bool) -> bool { any(*self, it) } + fn any(&self, it: &fn(char) -> bool) -> bool { any(*self, it) } /// Returns true if one string contains another #[inline] - pure fn contains(&self, needle: &'a str) -> bool { + fn contains(&self, needle: &'a str) -> bool { contains(*self, needle) } /// Returns true if a string contains a char #[inline] - pure fn contains_char(&self, needle: char) -> bool { + fn contains_char(&self, needle: char) -> bool { contains_char(*self, needle) } /// Iterate over the bytes in a string #[inline] - pure fn each(&self, it: &fn(u8) -> bool) { each(*self, it) } + fn each(&self, it: &fn(u8) -> bool) { each(*self, it) } /// Iterate over the bytes in a string, with indices #[inline] - pure fn eachi(&self, it: &fn(uint, u8) -> bool) { eachi(*self, it) } + fn eachi(&self, it: &fn(uint, u8) -> bool) { eachi(*self, it) } + /// Iterate over the bytes in a string + #[inline] + fn each_reverse(&self, it: &fn(u8) -> bool) { + each_reverse(*self, it) + } + /// Iterate over the bytes in a string, with indices + #[inline] + fn eachi_reverse(&self, it: &fn(uint, u8) -> bool) { + eachi_reverse(*self, it) + } /// Iterate over the chars in a string #[inline] - pure fn each_char(&self, it: &fn(char) -> bool) { each_char(*self, it) } + fn each_char(&self, it: &fn(char) -> bool) { each_char(*self, it) } /// Iterate over the chars in a string, with indices #[inline] - pure fn each_chari(&self, it: &fn(uint, char) -> bool) { + fn each_chari(&self, it: &fn(uint, char) -> bool) { each_chari(*self, it) } + /// Iterate over the chars in a string in reverse + #[inline] + fn each_char_reverse(&self, it: &fn(char) -> bool) { + each_char_reverse(*self, it) + } + /// Iterate over the chars in a string in reverse, with indices from the + /// end + #[inline] + fn each_chari_reverse(&self, it: &fn(uint, char) -> bool) { + each_chari_reverse(*self, it) + } /// Returns true if one string ends with another #[inline] - pure fn ends_with(&self, needle: &str) -> bool { + fn ends_with(&self, needle: &str) -> bool { ends_with(*self, needle) } /// Returns true if the string has length 0 #[inline] - pure fn is_empty(&self) -> bool { is_empty(*self) } + fn is_empty(&self) -> bool { is_empty(*self) } /** * Returns true if the string contains only whitespace * * Whitespace characters are determined by `char::is_whitespace` */ #[inline] - pure fn is_whitespace(&self) -> bool { is_whitespace(*self) } + fn is_whitespace(&self) -> bool { is_whitespace(*self) } /** * Returns true if the string contains only alphanumerics * * Alphanumeric characters are determined by `char::is_alphanumeric` */ #[inline] - pure fn is_alphanumeric(&self) -> bool { is_alphanumeric(*self) } - #[inline] + fn is_alphanumeric(&self) -> bool { is_alphanumeric(*self) } /// Returns the size in bytes not counting the null terminator - pure fn len(&self) -> uint { len(*self) } + #[inline] + fn len(&self) -> uint { len(*self) } + /// Returns the number of characters that a string holds + #[inline] + fn char_len(&self) -> uint { char_len(*self) } /** * Returns a slice of the given string from the byte range * [`begin`..`end`) @@ -2348,28 +2408,28 @@ impl StrSlice for &'self str { * beyond the last character of the string */ #[inline] - pure fn slice(&self, begin: uint, end: uint) -> ~str { + fn slice(&self, begin: uint, end: uint) -> &'self str { slice(*self, begin, end) } /// Splits a string into substrings using a character function #[inline] - pure fn split(&self, sepfn: &fn(char) -> bool) -> ~[~str] { + fn split(&self, sepfn: &fn(char) -> bool) -> ~[~str] { split(*self, sepfn) } /** * Splits a string into substrings at each occurrence of a given character */ #[inline] - pure fn split_char(&self, sep: char) -> ~[~str] { split_char(*self, sep) } + fn split_char(&self, sep: char) -> ~[~str] { split_char(*self, sep) } /** * Splits a string into a vector of the substrings separated by a given * string */ #[inline] - pure fn split_str(&self, sep: &'a str) -> ~[~str] { split_str(*self, sep) } + fn split_str(&self, sep: &'a str) -> ~[~str] { split_str(*self, sep) } /// Returns true if one string starts with another #[inline] - pure fn starts_with(&self, needle: &'a str) -> bool { + fn starts_with(&self, needle: &'a str) -> bool { starts_with(*self, needle) } /** @@ -2379,37 +2439,51 @@ impl StrSlice for &'self str { * `begin`. */ #[inline] - pure fn substr(&self, begin: uint, n: uint) -> ~str { + fn substr(&self, begin: uint, n: uint) -> &'self str { substr(*self, begin, n) } /// Convert a string to lowercase #[inline] - pure fn to_lower(&self) -> ~str { to_lower(*self) } + fn to_lower(&self) -> ~str { to_lower(*self) } /// Convert a string to uppercase #[inline] - pure fn to_upper(&self) -> ~str { to_upper(*self) } + fn to_upper(&self) -> ~str { to_upper(*self) } /// Escape each char in `s` with char::escape_default. #[inline] - pure fn escape_default(&self) -> ~str { escape_default(*self) } + fn escape_default(&self) -> ~str { escape_default(*self) } /// Escape each char in `s` with char::escape_unicode. #[inline] - pure fn escape_unicode(&self) -> ~str { escape_unicode(*self) } + fn escape_unicode(&self) -> ~str { escape_unicode(*self) } /// Returns a string with leading and trailing whitespace removed #[inline] - pure fn trim(&self) -> ~str { trim(*self) } + fn trim(&self) -> &'self str { trim(*self) } /// Returns a string with leading whitespace removed #[inline] - pure fn trim_left(&self) -> ~str { trim_left(*self) } + fn trim_left(&self) -> &'self str { trim_left(*self) } /// Returns a string with trailing whitespace removed #[inline] - pure fn trim_right(&self) -> ~str { trim_right(*self) } + fn trim_right(&self) -> &'self str { trim_right(*self) } + + #[inline] + fn trim_chars(&self, chars_to_trim: &[char]) -> &'self str { + trim_chars(*self, chars_to_trim) + } + #[inline] + fn trim_left_chars(&self, chars_to_trim: &[char]) -> &'self str { + trim_left_chars(*self, chars_to_trim) + } + #[inline] + fn trim_right_chars(&self, chars_to_trim: &[char]) -> &'self str { + trim_right_chars(*self, chars_to_trim) + } + #[inline] - pure fn to_owned(&self) -> ~str { self.slice(0, self.len()) } + fn to_owned(&self) -> ~str { from_slice(*self) } #[inline] - pure fn to_managed(&self) -> @str { + fn to_managed(&self) -> @str { let v = at_vec::from_fn(self.len() + 1, |i| { if i == self.len() { 0 } else { self[i] } }); @@ -2417,7 +2491,12 @@ impl StrSlice for &'self str { } #[inline] - pure fn char_at(&self, i: uint) -> char { char_at(*self, i) } + fn char_at(&self, i: uint) -> char { char_at(*self, i) } + + #[inline] + fn char_at_reverse(&self, i: uint) -> char { + char_at_reverse(*self, i) + } fn to_bytes(&self) -> ~[u8] { to_bytes(*self) } } @@ -2464,8 +2543,8 @@ mod tests { #[test] fn test_eq_slice() { - fail_unless!((eq_slice(view("foobar", 0, 3), "foo"))); - fail_unless!((eq_slice(view("barfoo", 3, 6), "foo"))); + fail_unless!((eq_slice(slice("foobar", 0, 3), "foo"))); + fail_unless!((eq_slice(slice("barfoo", 3, 6), "foo"))); fail_unless!((!eq_slice("foo1", "foo2"))); } @@ -2610,6 +2689,35 @@ mod tests { } + #[test] + fn test_split_char_no_trailing() { + fn t(s: &str, c: char, u: &[~str]) { + debug!(~"split_byte: " + s); + let v = split_char_no_trailing(s, c); + debug!("split_byte to: %?", v); + fail_unless!(vec::all2(v, u, |a,b| a == b)); + } + t(~"abc.hello.there", '.', ~[~"abc", ~"hello", ~"there"]); + t(~".hello.there", '.', ~[~"", ~"hello", ~"there"]); + t(~"...hello.there.", '.', ~[~"", ~"", ~"", ~"hello", ~"there"]); + + fail_unless!(~[~"", ~"", ~"", ~"hello", ~"there"] + == split_char_no_trailing(~"...hello.there.", '.')); + + fail_unless!(~[] == split_char_no_trailing(~"", 'z')); + fail_unless!(~[~""] == split_char_no_trailing(~"z", 'z')); + fail_unless!(~[~"ok"] == split_char_no_trailing(~"ok", 'z')); + } + + #[test] + fn test_split_char_no_trailing_2() { + let data = ~"ประเทศไทย中华Việt Nam"; + fail_unless!(~[~"ประเทศไทย中华", ~"iệt Nam"] + == split_char_no_trailing(data, 'V')); + fail_unless!(~[~"ประเ", ~"ศไ", ~"ย中华Việt Nam"] + == split_char_no_trailing(data, 'ท')); + } + #[test] fn test_split_str() { fn t(s: &str, sep: &'a str, i: int, k: &str) { @@ -2663,28 +2771,45 @@ mod tests { fail_unless!(~[~"ok"] == split(~"ok", |cc| cc == 'z')); } + #[test] + fn test_split_no_trailing() { + let data = ~"ประเทศไทย中华Việt Nam"; + fail_unless!(~[~"ประเทศไทย中", ~"Việt Nam"] + == split_no_trailing (data, |cc| cc == '华')); + + fail_unless!(~[~"", ~"", ~"XXX", ~"YYY"] + == split_no_trailing(~"zzXXXzYYYz", char::is_lowercase)); + + fail_unless!(~[~"zz", ~"", ~"", ~"z", ~"", ~"", ~"z"] + == split_no_trailing(~"zzXXXzYYYz", char::is_uppercase)); + + fail_unless!(~[~""] == split_no_trailing(~"z", |cc| cc == 'z')); + fail_unless!(~[] == split_no_trailing(~"", |cc| cc == 'z')); + fail_unless!(~[~"ok"] == split_no_trailing(~"ok", |cc| cc == 'z')); + } + #[test] fn test_lines() { let lf = ~"\nMary had a little lamb\nLittle lamb\n"; let crlf = ~"\r\nMary had a little lamb\r\nLittle lamb\r\n"; - fail_unless!(~[~"", ~"Mary had a little lamb", ~"Little lamb", ~""] + fail_unless!(~[~"", ~"Mary had a little lamb", ~"Little lamb"] == lines(lf)); - fail_unless!(~[~"", ~"Mary had a little lamb", ~"Little lamb", ~""] + fail_unless!(~[~"", ~"Mary had a little lamb", ~"Little lamb"] == lines_any(lf)); fail_unless!(~[~"\r", ~"Mary had a little lamb\r", - ~"Little lamb\r", ~""] + ~"Little lamb\r"] == lines(crlf)); - fail_unless!(~[~"", ~"Mary had a little lamb", ~"Little lamb", ~""] + fail_unless!(~[~"", ~"Mary had a little lamb", ~"Little lamb"] == lines_any(crlf)); - fail_unless!(~[~""] == lines (~"")); - fail_unless!(~[~""] == lines_any(~"")); - fail_unless!(~[~"",~""] == lines (~"\n")); - fail_unless!(~[~"",~""] == lines_any(~"\n")); + fail_unless!(~[] == lines (~"")); + fail_unless!(~[] == lines_any(~"")); + fail_unless!(~[~""] == lines (~"\n")); + fail_unless!(~[~""] == lines_any(~"\n")); fail_unless!(~[~"banana"] == lines (~"banana")); fail_unless!(~[~"banana"] == lines_any(~"banana")); } @@ -2758,11 +2883,11 @@ mod tests { #[test] fn test_substr() { fn t(a: &str, b: &str, start: int) { - fail_unless!(substr(a, start as uint, len(b)) == b.to_str()); + fail_unless!(substr(a, start as uint, len(b)) == b); } - t(~"hello", ~"llo", 2); - t(~"hello", ~"el", 1); - fail_unless!(~"ะเทศไท" == substr(~"ประเทศไทย中华Việt Nam", 6u, 6u)); + t("hello", "llo", 2); + t("hello", "el", 1); + fail_unless!("ะเทศไท" == substr("ประเทศไทย中华Việt Nam", 6u, 6u)); } #[test] @@ -2832,25 +2957,24 @@ mod tests { #[test] fn test_unsafe_slice() { - unsafe { - fail_unless!(~"ab" == raw::slice_bytes(~"abc", 0, 2)); - fail_unless!(~"bc" == raw::slice_bytes(~"abc", 1, 3)); - fail_unless!(~"" == raw::slice_bytes(~"abc", 1, 1)); - fn a_million_letter_a() -> ~str { - let mut i = 0; - let mut rs = ~""; - while i < 100000 { push_str(&mut rs, ~"aaaaaaaaaa"); i += 1; } - rs - } - fn half_a_million_letter_a() -> ~str { - let mut i = 0; - let mut rs = ~""; - while i < 100000 { push_str(&mut rs, ~"aaaaa"); i += 1; } - rs - } - fail_unless!(half_a_million_letter_a() == - raw::slice_bytes(a_million_letter_a(), 0u, 500000)); + fail_unless!("ab" == unsafe {raw::slice_bytes("abc", 0, 2)}); + fail_unless!("bc" == unsafe {raw::slice_bytes("abc", 1, 3)}); + fail_unless!("" == unsafe {raw::slice_bytes("abc", 1, 1)}); + fn a_million_letter_a() -> ~str { + let mut i = 0; + let mut rs = ~""; + while i < 100000 { push_str(&mut rs, "aaaaaaaaaa"); i += 1; } + rs + } + fn half_a_million_letter_a() -> ~str { + let mut i = 0; + let mut rs = ~""; + while i < 100000 { push_str(&mut rs, "aaaaa"); i += 1; } + rs } + let letters = a_million_letter_a(); + fail_unless!(half_a_million_letter_a() == + unsafe {raw::slice_bytes(letters, 0u, 500000)}.to_owned()); } #[test] @@ -2930,22 +3054,22 @@ mod tests { #[test] fn test_slice() { - fail_unless!(~"ab" == slice(~"abc", 0, 2)); - fail_unless!(~"bc" == slice(~"abc", 1, 3)); - fail_unless!(~"" == slice(~"abc", 1, 1)); - fail_unless!(~"\u65e5" == slice(~"\u65e5\u672c", 0, 3)); + fail_unless!("ab" == slice("abc", 0, 2)); + fail_unless!("bc" == slice("abc", 1, 3)); + fail_unless!("" == slice("abc", 1, 1)); + fail_unless!("\u65e5" == slice("\u65e5\u672c", 0, 3)); - let data = ~"ประเทศไทย中华"; - fail_unless!(~"ป" == slice(data, 0, 3)); - fail_unless!(~"ร" == slice(data, 3, 6)); - fail_unless!(~"" == slice(data, 3, 3)); - fail_unless!(~"华" == slice(data, 30, 33)); + let data = "ประเทศไทย中华"; + fail_unless!("ป" == slice(data, 0, 3)); + fail_unless!("ร" == slice(data, 3, 6)); + fail_unless!("" == slice(data, 3, 3)); + fail_unless!("华" == slice(data, 30, 33)); fn a_million_letter_X() -> ~str { let mut i = 0; let mut rs = ~""; while i < 100000 { - push_str(&mut rs, ~"华华华华华华华华华华"); + push_str(&mut rs, "华华华华华华华华华华"); i += 1; } rs @@ -2953,27 +3077,28 @@ mod tests { fn half_a_million_letter_X() -> ~str { let mut i = 0; let mut rs = ~""; - while i < 100000 { push_str(&mut rs, ~"华华华华华"); i += 1; } + while i < 100000 { push_str(&mut rs, "华华华华华"); i += 1; } rs } + let letters = a_million_letter_X(); fail_unless!(half_a_million_letter_X() == - slice(a_million_letter_X(), 0u, 3u * 500000u)); + slice(letters, 0u, 3u * 500000u).to_owned()); } #[test] fn test_slice_2() { - let ss = ~"中华Việt Nam"; + let ss = "中华Việt Nam"; - fail_unless!(~"华" == slice(ss, 3u, 6u)); - fail_unless!(~"Việt Nam" == slice(ss, 6u, 16u)); + fail_unless!("华" == slice(ss, 3u, 6u)); + fail_unless!("Việt Nam" == slice(ss, 6u, 16u)); - fail_unless!(~"ab" == slice(~"abc", 0u, 2u)); - fail_unless!(~"bc" == slice(~"abc", 1u, 3u)); - fail_unless!(~"" == slice(~"abc", 1u, 1u)); + fail_unless!("ab" == slice("abc", 0u, 2u)); + fail_unless!("bc" == slice("abc", 1u, 3u)); + fail_unless!("" == slice("abc", 1u, 1u)); - fail_unless!(~"中" == slice(ss, 0u, 3u)); - fail_unless!(~"华V" == slice(ss, 3u, 7u)); - fail_unless!(~"" == slice(ss, 3u, 3u)); + fail_unless!("中" == slice(ss, 0u, 3u)); + fail_unless!("华V" == slice(ss, 3u, 7u)); + fail_unless!("" == slice(ss, 3u, 3u)); /*0: 中 3: 华 6: V @@ -2990,67 +3115,67 @@ mod tests { #[should_fail] #[ignore(cfg(windows))] fn test_slice_fail() { - slice(~"中华Việt Nam", 0u, 2u); + slice("中华Việt Nam", 0u, 2u); } #[test] fn test_trim_left_chars() { - fail_unless!(trim_left_chars(~" *** foo *** ", ~[]) == - ~" *** foo *** "); - fail_unless!(trim_left_chars(~" *** foo *** ", ~['*', ' ']) == - ~"foo *** "); - fail_unless!(trim_left_chars(~" *** *** ", ~['*', ' ']) == ~""); - fail_unless!(trim_left_chars(~"foo *** ", ~['*', ' ']) == - ~"foo *** "); + fail_unless!(trim_left_chars(" *** foo *** ", ~[]) == + " *** foo *** "); + fail_unless!(trim_left_chars(" *** foo *** ", ~['*', ' ']) == + "foo *** "); + fail_unless!(trim_left_chars(" *** *** ", ~['*', ' ']) == ""); + fail_unless!(trim_left_chars("foo *** ", ~['*', ' ']) == + "foo *** "); } #[test] fn test_trim_right_chars() { - fail_unless!(trim_right_chars(~" *** foo *** ", ~[]) == - ~" *** foo *** "); - fail_unless!(trim_right_chars(~" *** foo *** ", ~['*', ' ']) == - ~" *** foo"); - fail_unless!(trim_right_chars(~" *** *** ", ~['*', ' ']) == ~""); - fail_unless!(trim_right_chars(~" *** foo", ~['*', ' ']) == - ~" *** foo"); + fail_unless!(trim_right_chars(" *** foo *** ", ~[]) == + " *** foo *** "); + fail_unless!(trim_right_chars(" *** foo *** ", ~['*', ' ']) == + " *** foo"); + fail_unless!(trim_right_chars(" *** *** ", ~['*', ' ']) == ""); + fail_unless!(trim_right_chars(" *** foo", ~['*', ' ']) == + " *** foo"); } #[test] fn test_trim_chars() { - fail_unless!(trim_chars(~" *** foo *** ", ~[]) == ~" *** foo *** "); - fail_unless!(trim_chars(~" *** foo *** ", ~['*', ' ']) == ~"foo"); - fail_unless!(trim_chars(~" *** *** ", ~['*', ' ']) == ~""); - fail_unless!(trim_chars(~"foo", ~['*', ' ']) == ~"foo"); + fail_unless!(trim_chars(" *** foo *** ", ~[]) == " *** foo *** "); + fail_unless!(trim_chars(" *** foo *** ", ~['*', ' ']) == "foo"); + fail_unless!(trim_chars(" *** *** ", ~['*', ' ']) == ""); + fail_unless!(trim_chars("foo", ~['*', ' ']) == "foo"); } #[test] fn test_trim_left() { - fail_unless!((trim_left(~"") == ~"")); - fail_unless!((trim_left(~"a") == ~"a")); - fail_unless!((trim_left(~" ") == ~"")); - fail_unless!((trim_left(~" blah") == ~"blah")); - fail_unless!((trim_left(~" \u3000 wut") == ~"wut")); - fail_unless!((trim_left(~"hey ") == ~"hey ")); + fail_unless!((trim_left("") == "")); + fail_unless!((trim_left("a") == "a")); + fail_unless!((trim_left(" ") == "")); + fail_unless!((trim_left(" blah") == "blah")); + fail_unless!((trim_left(" \u3000 wut") == "wut")); + fail_unless!((trim_left("hey ") == "hey ")); } #[test] fn test_trim_right() { - fail_unless!((trim_right(~"") == ~"")); - fail_unless!((trim_right(~"a") == ~"a")); - fail_unless!((trim_right(~" ") == ~"")); - fail_unless!((trim_right(~"blah ") == ~"blah")); - fail_unless!((trim_right(~"wut \u3000 ") == ~"wut")); - fail_unless!((trim_right(~" hey") == ~" hey")); + fail_unless!((trim_right("") == "")); + fail_unless!((trim_right("a") == "a")); + fail_unless!((trim_right(" ") == "")); + fail_unless!((trim_right("blah ") == "blah")); + fail_unless!((trim_right("wut \u3000 ") == "wut")); + fail_unless!((trim_right(" hey") == " hey")); } #[test] fn test_trim() { - fail_unless!((trim(~"") == ~"")); - fail_unless!((trim(~"a") == ~"a")); - fail_unless!((trim(~" ") == ~"")); - fail_unless!((trim(~" blah ") == ~"blah")); - fail_unless!((trim(~"\nwut \u3000 ") == ~"wut")); - fail_unless!((trim(~" hey dude ") == ~"hey dude")); + fail_unless!((trim("") == "")); + fail_unless!((trim("a") == "a")); + fail_unless!((trim(" ") == "")); + fail_unless!((trim(" blah ") == "blah")); + fail_unless!((trim("\nwut \u3000 ") == "wut")); + fail_unless!((trim(" hey dude ") == "hey dude")); } #[test] @@ -3234,41 +3359,6 @@ mod tests { fail_unless!(!contains_char(~"", 'a')); } - #[test] - fn test_chars_each() { - let mut i = 0; - for chars_each(~"x\u03c0y") |ch| { - match i { - 0 => fail_unless!(ch == 'x'), - 1 => fail_unless!(ch == '\u03c0'), - 2 => fail_unless!(ch == 'y'), - _ => fail!(~"test_chars_each failed") - } - i += 1; - } - - chars_each(~"", |_ch| fail!() ); // should not fail - } - - #[test] - fn test_bytes_each() { - let mut i = 0; - - for bytes_each(~"xyz") |bb| { - match i { - 0 => fail_unless!(bb == 'x' as u8), - 1 => fail_unless!(bb == 'y' as u8), - 2 => fail_unless!(bb == 'z' as u8), - _ => fail!(~"test_bytes_each failed") - } - i += 1; - } - - for bytes_each(~"") |bb| { - fail_unless!(bb == 0u8); - } - } - #[test] fn test_split_char_each() { let data = ~"\nMary had a little lamb\nLittle lamb\n"; @@ -3335,7 +3425,6 @@ mod tests { 0 => fail_unless!("" == x), 1 => fail_unless!("Mary had a little lamb" == x), 2 => fail_unless!("Little lamb" == x), - 3 => fail_unless!("" == x), _ => () } ii += 1; @@ -3426,17 +3515,168 @@ mod tests { } } + #[test] + fn test_char_at() { + let s = ~"ศไทย中华Việt Nam"; + let v = ~['ศ','ไ','ท','ย','中','华','V','i','ệ','t',' ','N','a','m']; + let mut pos = 0; + for v.each |ch| { + fail_unless!(s.char_at(pos) == *ch); + pos += from_char(*ch).len(); + } + } + + #[test] + fn test_char_at_reverse() { + let s = ~"ศไทย中华Việt Nam"; + let v = ~['ศ','ไ','ท','ย','中','华','V','i','ệ','t',' ','N','a','m']; + let mut pos = s.len(); + for v.each_reverse |ch| { + fail_unless!(s.char_at_reverse(pos) == *ch); + pos -= from_char(*ch).len(); + } + } + + #[test] + fn test_each() { + let s = ~"ศไทย中华Việt Nam"; + let v = [ + 224, 184, 168, 224, 185, 132, 224, 184, 151, 224, 184, 162, 228, + 184, 173, 229, 141, 142, 86, 105, 225, 187, 135, 116, 32, 78, 97, + 109 + ]; + let mut pos = 0; + + for s.each |b| { + fail_unless!(b == v[pos]); + pos += 1; + } + } + + #[test] + fn test_each_empty() { + for "".each |b| { + fail_unless!(b == 0u8); + } + } + + #[test] + fn test_eachi() { + let s = ~"ศไทย中华Việt Nam"; + let v = [ + 224, 184, 168, 224, 185, 132, 224, 184, 151, 224, 184, 162, 228, + 184, 173, 229, 141, 142, 86, 105, 225, 187, 135, 116, 32, 78, 97, + 109 + ]; + let mut pos = 0; + + for s.eachi |i, b| { + fail_unless!(pos == i); + fail_unless!(b == v[pos]); + pos += 1; + } + } + + #[test] + fn test_eachi_empty() { + for "".eachi |i, b| { + fail_unless!(i == 0); + fail_unless!(b == 0); + } + } + + #[test] + fn test_each_reverse() { + let s = ~"ศไทย中华Việt Nam"; + let v = [ + 224, 184, 168, 224, 185, 132, 224, 184, 151, 224, 184, 162, 228, + 184, 173, 229, 141, 142, 86, 105, 225, 187, 135, 116, 32, 78, 97, + 109 + ]; + let mut pos = v.len(); + + for s.each_reverse |b| { + pos -= 1; + fail_unless!(b == v[pos]); + } + } + + #[test] + fn test_each_empty_reverse() { + for "".each_reverse |b| { + fail_unless!(b == 0u8); + } + } + + #[test] + fn test_eachi_reverse() { + let s = ~"ศไทย中华Việt Nam"; + let v = [ + 224, 184, 168, 224, 185, 132, 224, 184, 151, 224, 184, 162, 228, + 184, 173, 229, 141, 142, 86, 105, 225, 187, 135, 116, 32, 78, 97, + 109 + ]; + let mut pos = v.len(); + + for s.eachi_reverse |i, b| { + pos -= 1; + fail_unless!(pos == i); + fail_unless!(b == v[pos]); + } + } + + #[test] + fn test_eachi_reverse_empty() { + for "".eachi_reverse |i, b| { + fail_unless!(i == 0); + fail_unless!(b == 0); + } + } + #[test] fn test_each_char() { - let s = ~"abc"; - let mut found_b = false; - for each_char(s) |ch| { - if ch == 'b' { - found_b = true; - break; - } + let s = ~"ศไทย中华Việt Nam"; + let v = ~['ศ','ไ','ท','ย','中','华','V','i','ệ','t',' ','N','a','m']; + let mut pos = 0; + for s.each_char |ch| { + fail_unless!(ch == v[pos]); + pos += 1; + } + } + + #[test] + fn test_each_chari() { + let s = ~"ศไทย中华Việt Nam"; + let v = ~['ศ','ไ','ท','ย','中','华','V','i','ệ','t',' ','N','a','m']; + let mut pos = 0; + for s.each_chari |i, ch| { + fail_unless!(pos == i); + fail_unless!(ch == v[pos]); + pos += 1; + } + } + + #[test] + fn test_each_char_reverse() { + let s = ~"ศไทย中华Việt Nam"; + let v = ~['ศ','ไ','ท','ย','中','华','V','i','ệ','t',' ','N','a','m']; + let mut pos = v.len(); + for s.each_char_reverse |ch| { + pos -= 1; + fail_unless!(ch == v[pos]); + } + } + + #[test] + fn test_each_chari_reverse() { + let s = ~"ศไทย中华Việt Nam"; + let v = ~['ศ','ไ','ท','ย','中','华','V','i','ệ','t',' ','N','a','m']; + let mut pos = v.len(); + for s.each_chari_reverse |i, ch| { + pos -= 1; + fail_unless!(pos == i); + fail_unless!(ch == v[pos]); } - fail_unless!(found_b); } #[test] @@ -3470,7 +3710,7 @@ mod tests { #[test] fn test_to_managed() { fail_unless!((~"abc").to_managed() == @"abc"); - fail_unless!(view("abcdef", 1, 5).to_managed() == @"bcde"); + fail_unless!(slice("abcdef", 1, 5).to_managed() == @"bcde"); } #[test] diff --git a/src/libcore/sys.rs b/src/libcore/sys.rs index f7eceeebc1e62..706cb10dba9f7 100644 --- a/src/libcore/sys.rs +++ b/src/libcore/sys.rs @@ -60,15 +60,15 @@ pub mod rustrt { /// Compares contents of two pointers using the default method. /// Equivalent to `*x1 == *x2`. Useful for hashtables. -pub pure fn shape_eq(x1: &T, x2: &T) -> bool { +pub fn shape_eq(x1: &T, x2: &T) -> bool { *x1 == *x2 } -pub pure fn shape_lt(x1: &T, x2: &T) -> bool { +pub fn shape_lt(x1: &T, x2: &T) -> bool { *x1 < *x2 } -pub pure fn shape_le(x1: &T, x2: &T) -> bool { +pub fn shape_le(x1: &T, x2: &T) -> bool { *x1 <= *x2 } @@ -79,13 +79,13 @@ pub pure fn shape_le(x1: &T, x2: &T) -> bool { * performing dark magick. */ #[inline(always)] -pub pure fn get_type_desc() -> *TypeDesc { +pub fn get_type_desc() -> *TypeDesc { unsafe { rusti::get_tydesc::() as *TypeDesc } } /// Returns the size of a type #[inline(always)] -pub pure fn size_of() -> uint { +pub fn size_of() -> uint { unsafe { rusti::size_of::() } } @@ -95,7 +95,7 @@ pub pure fn size_of() -> uint { * Useful for building structures containing variable-length arrays. */ #[inline(always)] -pub pure fn nonzero_size_of() -> uint { +pub fn nonzero_size_of() -> uint { let s = size_of::(); if s == 0 { 1 } else { s } } @@ -107,26 +107,26 @@ pub pure fn nonzero_size_of() -> uint { * than the preferred alignment. */ #[inline(always)] -pub pure fn min_align_of() -> uint { +pub fn min_align_of() -> uint { unsafe { rusti::min_align_of::() } } /// Returns the preferred alignment of a type #[inline(always)] -pub pure fn pref_align_of() -> uint { +pub fn pref_align_of() -> uint { unsafe { rusti::pref_align_of::() } } /// Returns the refcount of a shared box (as just before calling this) #[inline(always)] -pub pure fn refcount(t: @T) -> uint { +pub fn refcount(t: @T) -> uint { unsafe { let ref_ptr: *uint = cast::reinterpret_cast(&t); *ref_ptr - 1 } } -pub pure fn log_str(t: &T) -> ~str { +pub fn log_str(t: &T) -> ~str { unsafe { do io::with_str_writer |wr| { repr::write_repr(wr, t) @@ -135,7 +135,7 @@ pub pure fn log_str(t: &T) -> ~str { } /** Initiate task failure */ -pub pure fn begin_unwind(msg: ~str, file: ~str, line: uint) -> ! { +pub fn begin_unwind(msg: ~str, file: ~str, line: uint) -> ! { do str::as_buf(msg) |msg_buf, _msg_len| { do str::as_buf(file) |file_buf, _file_len| { unsafe { @@ -148,7 +148,7 @@ pub pure fn begin_unwind(msg: ~str, file: ~str, line: uint) -> ! { } // FIXME #4427: Temporary until rt::rt_fail_ goes away -pub pure fn begin_unwind_(msg: *c_char, file: *c_char, line: size_t) -> ! { +pub fn begin_unwind_(msg: *c_char, file: *c_char, line: size_t) -> ! { unsafe { gc::cleanup_stack_for_failure(); rustrt::rust_upcall_fail(msg, file, line); @@ -156,7 +156,7 @@ pub pure fn begin_unwind_(msg: *c_char, file: *c_char, line: size_t) -> ! { } } -pub pure fn fail_assert(msg: &str, file: &str, line: uint) -> ! { +pub fn fail_assert(msg: &str, file: &str, line: uint) -> ! { unsafe { let (msg, file) = (msg.to_owned(), file.to_owned()); begin_unwind(~"assertion failed: " + msg, file, line) diff --git a/src/libcore/task/local_data_priv.rs b/src/libcore/task/local_data_priv.rs index 6a933ef515f1f..59f4942b3a4a7 100644 --- a/src/libcore/task/local_data_priv.rs +++ b/src/libcore/task/local_data_priv.rs @@ -24,14 +24,14 @@ pub trait LocalData { } impl LocalData for @T { } impl Eq for @LocalData { - pure fn eq(&self, other: &@LocalData) -> bool { + fn eq(&self, other: &@LocalData) -> bool { unsafe { let ptr_a: (uint, uint) = cast::reinterpret_cast(&(*self)); let ptr_b: (uint, uint) = cast::reinterpret_cast(other); return ptr_a == ptr_b; } } - pure fn ne(&self, other: &@LocalData) -> bool { !(*self).eq(other) } + fn ne(&self, other: &@LocalData) -> bool { !(*self).eq(other) } } // If TLS is used heavily in future, this could be made more efficient with a diff --git a/src/libcore/task/mod.rs b/src/libcore/task/mod.rs index 31c44531efec0..349a10bb80983 100644 --- a/src/libcore/task/mod.rs +++ b/src/libcore/task/mod.rs @@ -50,13 +50,13 @@ pub mod rt; pub mod spawn; /// A handle to a scheduler -#[deriving_eq] +#[deriving(Eq)] pub enum Scheduler { SchedulerHandle(sched_id) } /// A handle to a task -#[deriving_eq] +#[deriving(Eq)] pub enum Task { TaskHandle(task_id) } @@ -72,23 +72,14 @@ pub enum Task { * If you wish for this result's delivery to block until all linked and/or * children tasks complete, recommend using a result future. */ +#[deriving(Eq)] pub enum TaskResult { Success, Failure, } -impl Eq for TaskResult { - pure fn eq(&self, other: &TaskResult) -> bool { - match ((*self), (*other)) { - (Success, Success) | (Failure, Failure) => true, - (Success, _) | (Failure, _) => false - } - } - pure fn ne(&self, other: &TaskResult) -> bool { !(*self).eq(other) } -} - /// Scheduler modes -#[deriving_eq] +#[deriving(Eq)] pub enum SchedMode { /// Run task on the default scheduler DefaultScheduler, @@ -1160,7 +1151,7 @@ fn test_child_doesnt_ref_parent() { // climbing the task tree to dereference each ancestor. (See #1789) // (well, it would if the constant were 8000+ - I lowered it to be more // valgrind-friendly. try this at home, instead..!) - const generations: uint = 16; + static generations: uint = 16; fn child_no(x: uint) -> ~fn() { return || { if x < generations { diff --git a/src/libcore/task/spawn.rs b/src/libcore/task/spawn.rs index 40a6873ad6725..b97a682c4e5ca 100644 --- a/src/libcore/task/spawn.rs +++ b/src/libcore/task/spawn.rs @@ -126,7 +126,7 @@ type TaskGroupArc = unstable::Exclusive>; type TaskGroupInner = &'self mut Option; // A taskgroup is 'dead' when nothing can cause it to fail; only members can. -pure fn taskgroup_is_dead(tg: &TaskGroupData) -> bool { +fn taskgroup_is_dead(tg: &TaskGroupData) -> bool { (&const tg.members).is_empty() } diff --git a/src/libcore/to_bytes.rs b/src/libcore/to_bytes.rs index e5fbad16717a1..f379878c8eb0b 100644 --- a/src/libcore/to_bytes.rs +++ b/src/libcore/to_bytes.rs @@ -43,12 +43,12 @@ pub trait IterBytes { * left-to-right in declaration order, regardless of * underlying memory endianness. */ - pure fn iter_bytes(&self, lsb0: bool, f: Cb); + fn iter_bytes(&self, lsb0: bool, f: Cb); } impl IterBytes for bool { #[inline(always)] - pure fn iter_bytes(&self, _lsb0: bool, f: Cb) { + fn iter_bytes(&self, _lsb0: bool, f: Cb) { f([ *self as u8 ]); @@ -57,7 +57,7 @@ impl IterBytes for bool { impl IterBytes for u8 { #[inline(always)] - pure fn iter_bytes(&self, _lsb0: bool, f: Cb) { + fn iter_bytes(&self, _lsb0: bool, f: Cb) { f([ *self ]); @@ -66,7 +66,7 @@ impl IterBytes for u8 { impl IterBytes for u16 { #[inline(always)] - pure fn iter_bytes(&self, lsb0: bool, f: Cb) { + fn iter_bytes(&self, lsb0: bool, f: Cb) { if lsb0 { f([ *self as u8, @@ -83,7 +83,7 @@ impl IterBytes for u16 { impl IterBytes for u32 { #[inline(always)] - pure fn iter_bytes(&self, lsb0: bool, f: Cb) { + fn iter_bytes(&self, lsb0: bool, f: Cb) { if lsb0 { f([ *self as u8, @@ -104,7 +104,7 @@ impl IterBytes for u32 { impl IterBytes for u64 { #[inline(always)] - pure fn iter_bytes(&self, lsb0: bool, f: Cb) { + fn iter_bytes(&self, lsb0: bool, f: Cb) { if lsb0 { f([ *self as u8, @@ -133,35 +133,35 @@ impl IterBytes for u64 { impl IterBytes for i8 { #[inline(always)] - pure fn iter_bytes(&self, lsb0: bool, f: Cb) { + fn iter_bytes(&self, lsb0: bool, f: Cb) { (*self as u8).iter_bytes(lsb0, f) } } impl IterBytes for i16 { #[inline(always)] - pure fn iter_bytes(&self, lsb0: bool, f: Cb) { + fn iter_bytes(&self, lsb0: bool, f: Cb) { (*self as u16).iter_bytes(lsb0, f) } } impl IterBytes for i32 { #[inline(always)] - pure fn iter_bytes(&self, lsb0: bool, f: Cb) { + fn iter_bytes(&self, lsb0: bool, f: Cb) { (*self as u32).iter_bytes(lsb0, f) } } impl IterBytes for i64 { #[inline(always)] - pure fn iter_bytes(&self, lsb0: bool, f: Cb) { + fn iter_bytes(&self, lsb0: bool, f: Cb) { (*self as u64).iter_bytes(lsb0, f) } } impl IterBytes for char { #[inline(always)] - pure fn iter_bytes(&self, lsb0: bool, f: Cb) { + fn iter_bytes(&self, lsb0: bool, f: Cb) { (*self as u32).iter_bytes(lsb0, f) } } @@ -172,7 +172,7 @@ pub mod x32 { impl IterBytes for uint { #[inline(always)] - pure fn iter_bytes(&self, lsb0: bool, f: Cb) { + fn iter_bytes(&self, lsb0: bool, f: Cb) { (*self as u32).iter_bytes(lsb0, f) } } @@ -184,7 +184,7 @@ pub mod x64 { impl IterBytes for uint { #[inline(always)] - pure fn iter_bytes(&self, lsb0: bool, f: Cb) { + fn iter_bytes(&self, lsb0: bool, f: Cb) { (*self as u64).iter_bytes(lsb0, f) } } @@ -192,14 +192,14 @@ pub mod x64 { impl IterBytes for int { #[inline(always)] - pure fn iter_bytes(&self, lsb0: bool, f: Cb) { + fn iter_bytes(&self, lsb0: bool, f: Cb) { (*self as uint).iter_bytes(lsb0, f) } } impl IterBytes for &'self [A] { #[inline(always)] - pure fn iter_bytes(&self, lsb0: bool, f: Cb) { + fn iter_bytes(&self, lsb0: bool, f: Cb) { for (*self).each |elt| { do elt.iter_bytes(lsb0) |bytes| { f(bytes) @@ -210,7 +210,7 @@ impl IterBytes for &'self [A] { impl IterBytes for (A,B) { #[inline(always)] - pure fn iter_bytes(&self, lsb0: bool, f: Cb) { + fn iter_bytes(&self, lsb0: bool, f: Cb) { match *self { (ref a, ref b) => { iter_bytes_2(a, b, lsb0, f); @@ -221,7 +221,7 @@ impl IterBytes for (A,B) { impl IterBytes for (A,B,C) { #[inline(always)] - pure fn iter_bytes(&self, lsb0: bool, f: Cb) { + fn iter_bytes(&self, lsb0: bool, f: Cb) { match *self { (ref a, ref b, ref c) => { iter_bytes_3(a, b, c, lsb0, f); @@ -231,25 +231,25 @@ impl IterBytes for (A,B,C) { } // Move this to vec, probably. -pure fn borrow(a: &'x [A]) -> &'x [A] { +fn borrow(a: &'x [A]) -> &'x [A] { a } impl IterBytes for ~[A] { #[inline(always)] - pure fn iter_bytes(&self, lsb0: bool, f: Cb) { + fn iter_bytes(&self, lsb0: bool, f: Cb) { borrow(*self).iter_bytes(lsb0, f) } } impl IterBytes for @[A] { #[inline(always)] - pure fn iter_bytes(&self, lsb0: bool, f: Cb) { + fn iter_bytes(&self, lsb0: bool, f: Cb) { borrow(*self).iter_bytes(lsb0, f) } } -pub pure fn iter_bytes_2(a: &A, b: &B, +pub 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}); @@ -257,7 +257,7 @@ pub pure fn iter_bytes_2(a: &A, b: &B, b.iter_bytes(lsb0, |bytes| {flag = z(bytes); flag}); } -pub pure fn iter_bytes_3(a: &A, b: &B, c: &C, lsb0: bool, z: Cb) { @@ -269,7 +269,7 @@ pub pure fn iter_bytes_3(a: &A, b: &B, c: &C, @@ -285,7 +285,7 @@ pub pure fn iter_bytes_4 IterBytes for Option { #[inline(always)] - pure fn iter_bytes(&self, lsb0: bool, f: Cb) { + fn iter_bytes(&self, lsb0: bool, f: Cb) { match *self { Some(ref a) => iter_bytes_2(&0u8, a, lsb0, f), None => 1u8.iter_bytes(lsb0, f) @@ -391,21 +391,21 @@ impl IterBytes for Option { impl IterBytes for &'self A { #[inline(always)] - pure fn iter_bytes(&self, lsb0: bool, f: Cb) { + fn iter_bytes(&self, lsb0: bool, f: Cb) { (**self).iter_bytes(lsb0, f); } } impl IterBytes for @A { #[inline(always)] - pure fn iter_bytes(&self, lsb0: bool, f: Cb) { + fn iter_bytes(&self, lsb0: bool, f: Cb) { (**self).iter_bytes(lsb0, f); } } impl IterBytes for ~A { #[inline(always)] - pure fn iter_bytes(&self, lsb0: bool, f: Cb) { + fn iter_bytes(&self, lsb0: bool, f: Cb) { (**self).iter_bytes(lsb0, f); } } @@ -414,7 +414,7 @@ impl IterBytes for ~A { // to the target; it just gives you the pointer-bytes. impl IterBytes for *const A { #[inline(always)] - pure fn iter_bytes(&self, lsb0: bool, f: Cb) { + fn iter_bytes(&self, lsb0: bool, f: Cb) { (*self as uint).iter_bytes(lsb0, f); } } diff --git a/src/libcore/to_str.rs b/src/libcore/to_str.rs index 0f2fd69960442..576f794483d20 100644 --- a/src/libcore/to_str.rs +++ b/src/libcore/to_str.rs @@ -17,35 +17,23 @@ The `ToStr` trait for converting to strings use str; pub trait ToStr { - pure fn to_str(&self) -> ~str; + fn to_str(&self) -> ~str; } impl ToStr for bool { #[inline(always)] - pure fn to_str(&self) -> ~str { ::bool::to_str(*self) } + fn to_str(&self) -> ~str { ::bool::to_str(*self) } } impl ToStr for () { #[inline(always)] - pure fn to_str(&self) -> ~str { ~"()" } -} -impl ToStr for ~str { - #[inline(always)] - pure fn to_str(&self) -> ~str { copy *self } -} -impl ToStr for &'self str { - #[inline(always)] - pure fn to_str(&self) -> ~str { ::str::from_slice(*self) } -} -impl ToStr for @str { - #[inline(always)] - pure fn to_str(&self) -> ~str { ::str::from_slice(*self) } + fn to_str(&self) -> ~str { ~"()" } } // FIXME #4898: impl for one-tuples impl ToStr for (A, B) { #[inline(always)] - pure fn to_str(&self) -> ~str { + fn to_str(&self) -> ~str { // FIXME(#4760): this causes an llvm assertion //let &(ref a, ref b) = self; match *self { @@ -57,7 +45,7 @@ impl ToStr for (A, B) { } impl ToStr for (A, B, C) { #[inline(always)] - pure fn to_str(&self) -> ~str { + fn to_str(&self) -> ~str { // FIXME(#4760): this causes an llvm assertion //let &(ref a, ref b, ref c) = self; match *self { @@ -74,7 +62,7 @@ impl ToStr for (A, B, C) { impl ToStr for &'self [A] { #[inline(always)] - pure fn to_str(&self) -> ~str { + fn to_str(&self) -> ~str { unsafe { // FIXME #4568 // Bleh -- not really unsafe @@ -95,7 +83,7 @@ impl ToStr for &'self [A] { impl ToStr for ~[A] { #[inline(always)] - pure fn to_str(&self) -> ~str { + fn to_str(&self) -> ~str { unsafe { // FIXME #4568 // Bleh -- not really unsafe @@ -116,7 +104,7 @@ impl ToStr for ~[A] { impl ToStr for @[A] { #[inline(always)] - pure fn to_str(&self) -> ~str { + fn to_str(&self) -> ~str { unsafe { // FIXME #4568 // Bleh -- not really unsafe diff --git a/src/libcore/trie.rs b/src/libcore/trie.rs index 6b2f2bb6a7dbe..012e005567434 100644 --- a/src/libcore/trie.rs +++ b/src/libcore/trie.rs @@ -8,15 +8,14 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -//! A radix trie for storing integers in sorted order +//! An ordered map and set for integer keys implemented as a radix trie use prelude::*; -// FIXME: #3469: need to manually update TrieNode when SHIFT changes // FIXME: #5244: need to manually update the TrieNode constructor -const SHIFT: uint = 4; -const SIZE: uint = 1 << SHIFT; -const MASK: uint = SIZE - 1; +static SHIFT: uint = 4; +static SIZE: uint = 1 << SHIFT; +static MASK: uint = SIZE - 1; enum Child { Internal(~TrieNode), @@ -32,17 +31,17 @@ pub struct TrieMap { impl BaseIter<(uint, &'self T)> for TrieMap { /// Visit all key-value pairs in order #[inline(always)] - pure fn each(&self, f: &fn(&(uint, &'self T)) -> bool) { + fn each(&self, f: &fn(&(uint, &'self T)) -> bool) { self.root.each(f); } #[inline(always)] - pure fn size_hint(&self) -> Option { Some(self.len()) } + fn size_hint(&self) -> Option { Some(self.len()) } } impl ReverseIter<(uint, &'self T)> for TrieMap { /// Visit all key-value pairs in reverse order #[inline(always)] - pure fn each_reverse(&self, f: &fn(&(uint, &'self T)) -> bool) { + fn each_reverse(&self, f: &fn(&(uint, &'self T)) -> bool) { self.root.each_reverse(f); } } @@ -50,11 +49,11 @@ impl ReverseIter<(uint, &'self T)> for TrieMap { impl Container for TrieMap { /// Return the number of elements in the map #[inline(always)] - pure fn len(&const self) -> uint { self.length } + fn len(&const self) -> uint { self.length } /// Return true if the map contains no elements #[inline(always)] - pure fn is_empty(&const self) -> bool { self.len() == 0 } + fn is_empty(&const self) -> bool { self.len() == 0 } } impl Mutable for TrieMap { @@ -69,19 +68,19 @@ impl Mutable for TrieMap { impl Map for TrieMap { /// Return true if the map contains a value for the specified key #[inline(always)] - pure fn contains_key(&self, key: &uint) -> bool { + fn contains_key(&self, key: &uint) -> bool { self.find(key).is_some() } /// Visit all keys in order #[inline(always)] - pure fn each_key(&self, f: &fn(&uint) -> bool) { + fn each_key(&self, f: &fn(&uint) -> bool) { self.each(|&(k, _)| f(&k)) } /// Visit all values in order #[inline(always)] - pure fn each_value(&self, f: &fn(&T) -> bool) { + fn each_value(&self, f: &fn(&T) -> bool) { self.each(|&(_, v)| f(v)) } @@ -91,9 +90,9 @@ impl Map for TrieMap { self.root.mutate_values(f); } - /// Return the value corresponding to the key in the map + /// Return a reference to the value corresponding to the key #[inline(hint)] - pure fn find(&self, key: &uint) -> Option<&'self T> { + fn find(&self, key: &uint) -> Option<&'self T> { let mut node: &'self TrieNode = &self.root; let mut idx = 0; loop { @@ -112,6 +111,12 @@ impl Map for TrieMap { } } + /// Return a mutable reference to the value corresponding to the key + #[inline(always)] + fn find_mut(&mut self, key: &uint) -> Option<&'self mut T> { + find_mut(&mut self.root.children[chunk(*key, 0)], *key, 1) + } + /// Insert a key-value pair into the map. An existing value for a /// key is replaced by the new value. Return true if the key did /// not already exist in the map. @@ -136,24 +141,22 @@ impl Map for TrieMap { } } -impl TrieMap { +pub impl TrieMap { /// Create an empty TrieMap #[inline(always)] - static pure fn new() -> TrieMap { + fn new() -> TrieMap { TrieMap{root: TrieNode::new(), length: 0} } -} -impl TrieMap { /// Visit all keys in reverse order #[inline(always)] - pure fn each_key_reverse(&self, f: &fn(&uint) -> bool) { + fn each_key_reverse(&self, f: &fn(&uint) -> bool) { self.each_reverse(|&(k, _)| f(&k)) } /// Visit all values in reverse order #[inline(always)] - pure fn each_value_reverse(&self, f: &fn(&T) -> bool) { + fn each_value_reverse(&self, f: &fn(&T) -> bool) { self.each_reverse(|&(_, v)| f(v)) } } @@ -164,13 +167,16 @@ pub struct TrieSet { impl BaseIter for TrieSet { /// Visit all values in order - pure fn each(&self, f: &fn(&uint) -> bool) { self.map.each_key(f) } - pure fn size_hint(&self) -> Option { Some(self.len()) } + #[inline(always)] + fn each(&self, f: &fn(&uint) -> bool) { self.map.each_key(f) } + #[inline(always)] + fn size_hint(&self) -> Option { Some(self.len()) } } impl ReverseIter for TrieSet { /// Visit all values in reverse order - pure fn each_reverse(&self, f: &fn(&uint) -> bool) { + #[inline(always)] + fn each_reverse(&self, f: &fn(&uint) -> bool) { self.map.each_key_reverse(f) } } @@ -178,11 +184,11 @@ impl ReverseIter for TrieSet { impl Container for TrieSet { /// Return the number of elements in the set #[inline(always)] - pure fn len(&const self) -> uint { self.map.len() } + fn len(&const self) -> uint { self.map.len() } /// Return true if the set contains no elements #[inline(always)] - pure fn is_empty(&const self) -> bool { self.map.is_empty() } + fn is_empty(&const self) -> bool { self.map.is_empty() } } impl Mutable for TrieSet { @@ -191,16 +197,16 @@ impl Mutable for TrieSet { fn clear(&mut self) { self.map.clear() } } -impl TrieSet { +pub impl TrieSet { /// Create an empty TrieSet #[inline(always)] - static pure fn new() -> TrieSet { + fn new() -> TrieSet { TrieSet{map: TrieMap::new()} } /// Return true if the set contains a value #[inline(always)] - pure fn contains(&self, value: &uint) -> bool { + fn contains(&self, value: &uint) -> bool { self.map.contains_key(value) } @@ -217,12 +223,12 @@ impl TrieSet { struct TrieNode { count: uint, - children: [Child * 16] // FIXME: #3469: can't use the SIZE constant yet + children: [Child * SIZE] } impl TrieNode { #[inline(always)] - static pure fn new() -> TrieNode { + fn new() -> TrieNode { // FIXME: #5244: [Nothing, ..SIZE] should be possible without Copy TrieNode{count: 0, children: [Nothing, Nothing, Nothing, Nothing, @@ -233,7 +239,7 @@ impl TrieNode { } impl TrieNode { - pure fn each(&self, f: &fn(&(uint, &'self T)) -> bool) -> bool { + fn each(&self, f: &fn(&(uint, &'self T)) -> bool) -> bool { for uint::range(0, self.children.len()) |idx| { match self.children[idx] { Internal(ref x) => if !x.each(f) { return false }, @@ -244,7 +250,7 @@ impl TrieNode { true } - pure fn each_reverse(&self, f: &fn(&(uint, &'self T)) -> bool) -> bool { + fn each_reverse(&self, f: &fn(&(uint, &'self T)) -> bool) -> bool { for uint::range_rev(self.children.len(), 0) |idx| { match self.children[idx - 1] { Internal(ref x) => if !x.each_reverse(f) { return false }, @@ -271,11 +277,22 @@ impl TrieNode { // if this was done via a trait, the key could be generic #[inline(always)] -pure fn chunk(n: uint, idx: uint) -> uint { +fn chunk(n: uint, idx: uint) -> uint { let sh = uint::bits - (SHIFT * (idx + 1)); (n >> sh) & MASK } +fn find_mut(child: &'r mut Child, key: uint, idx: uint) -> Option<&'r mut T> { + unsafe { // FIXME(#4903)---requires flow-sensitive borrow checker + (match *child { + External(_, ref value) => Some(cast::transmute_mut(value)), + Internal(ref x) => find_mut(cast::transmute_mut(&x.children[chunk(key, idx)]), + key, idx + 1), + Nothing => None + }).map_consume(|x| cast::transmute_mut_region(x)) + } +} + fn insert(count: &mut uint, child: &mut Child, key: uint, value: T, idx: uint) -> bool { let mut tmp = Nothing; @@ -303,7 +320,6 @@ fn insert(count: &mut uint, child: &mut Child, key: uint, value: T, added = insert(&mut x.count, &mut x.children[chunk(key, idx)], key, value, idx + 1); Internal(x) - } Nothing => { *count += 1; @@ -358,8 +374,22 @@ pub fn check_integrity(trie: &TrieNode) { #[cfg(test)] mod tests { use super::*; + use core::option::{Some, None}; use uint; + #[test] + fn test_find_mut() { + let mut m = TrieMap::new(); + fail_unless!(m.insert(1, 12)); + fail_unless!(m.insert(2, 8)); + fail_unless!(m.insert(5, 14)); + let new = 100; + match m.find_mut(&5) { + None => fail!(), Some(x) => *x = new + } + assert_eq!(m.find(&5), Some(&new)); + } + #[test] fn test_step() { let mut trie = TrieMap::new(); diff --git a/src/libcore/tuple.rs b/src/libcore/tuple.rs index b4f68466c2754..fc7834a7514ac 100644 --- a/src/libcore/tuple.rs +++ b/src/libcore/tuple.rs @@ -16,30 +16,30 @@ use vec; #[cfg(notest)] use cmp::{Eq, Ord}; pub trait CopyableTuple { - pure fn first(&self) -> T; - pure fn second(&self) -> U; - pure fn swap(&self) -> (U, T); + fn first(&self) -> T; + fn second(&self) -> U; + fn swap(&self) -> (U, T); } impl CopyableTuple for (T, U) { /// Return the first element of self #[inline(always)] - pure fn first(&self) -> T { + fn first(&self) -> T { let (t, _) = *self; return t; } /// Return the second element of self #[inline(always)] - pure fn second(&self) -> U { + fn second(&self) -> U { let (_, u) = *self; return u; } /// Return the results of swapping the two elements of self #[inline(always)] - pure fn swap(&self) -> (U, T) { + fn swap(&self) -> (U, T) { let (t, u) = *self; return (u, t); } @@ -47,19 +47,19 @@ impl CopyableTuple for (T, U) { } pub trait ImmutableTuple { - pure fn first_ref(&self) -> &'self T; - pure fn second_ref(&self) -> &'self U; + fn first_ref(&self) -> &'self T; + fn second_ref(&self) -> &'self U; } impl ImmutableTuple for (T, U) { #[inline(always)] - pure fn first_ref(&self) -> &'self T { + fn first_ref(&self) -> &'self T { match *self { (ref t, _) => t, } } #[inline(always)] - pure fn second_ref(&self) -> &'self U { + fn second_ref(&self) -> &'self U { match *self { (_, ref u) => u, } @@ -117,7 +117,7 @@ impl ExtendedTupleOps for (~[A], ~[B]) { #[cfg(notest)] impl Eq for (A, B) { #[inline(always)] - pure fn eq(&self, other: &(A, B)) -> bool { + fn eq(&self, other: &(A, B)) -> bool { match (*self) { (ref self_a, ref self_b) => match other { &(ref other_a, ref other_b) => { @@ -127,13 +127,13 @@ impl Eq for (A, B) { } } #[inline(always)] - pure fn ne(&self, other: &(A, B)) -> bool { !(*self).eq(other) } + fn ne(&self, other: &(A, B)) -> bool { !(*self).eq(other) } } #[cfg(notest)] impl Ord for (A, B) { #[inline(always)] - pure fn lt(&self, other: &(A, B)) -> bool { + fn lt(&self, other: &(A, B)) -> bool { match (*self) { (ref self_a, ref self_b) => { match (*other) { @@ -148,17 +148,17 @@ impl Ord for (A, B) { } } #[inline(always)] - pure fn le(&self, other: &(A, B)) -> bool { !(*other).lt(&(*self)) } + fn le(&self, other: &(A, B)) -> bool { !(*other).lt(&(*self)) } #[inline(always)] - pure fn ge(&self, other: &(A, B)) -> bool { !(*self).lt(other) } + fn ge(&self, other: &(A, B)) -> bool { !(*self).lt(other) } #[inline(always)] - pure fn gt(&self, other: &(A, B)) -> bool { (*other).lt(&(*self)) } + fn gt(&self, other: &(A, B)) -> bool { (*other).lt(&(*self)) } } #[cfg(notest)] impl Eq for (A, B, C) { #[inline(always)] - pure fn eq(&self, other: &(A, B, C)) -> bool { + fn eq(&self, other: &(A, B, C)) -> bool { match (*self) { (ref self_a, ref self_b, ref self_c) => match other { &(ref other_a, ref other_b, ref other_c) => { @@ -169,13 +169,13 @@ impl Eq for (A, B, C) { } } #[inline(always)] - pure fn ne(&self, other: &(A, B, C)) -> bool { !(*self).eq(other) } + fn ne(&self, other: &(A, B, C)) -> bool { !(*self).eq(other) } } #[cfg(notest)] impl Ord for (A, B, C) { #[inline(always)] - pure fn lt(&self, other: &(A, B, C)) -> bool { + fn lt(&self, other: &(A, B, C)) -> bool { match (*self) { (ref self_a, ref self_b, ref self_c) => { match (*other) { @@ -192,11 +192,11 @@ impl Ord for (A, B, C) { } } #[inline(always)] - pure fn le(&self, other: &(A, B, C)) -> bool { !(*other).lt(&(*self)) } + fn le(&self, other: &(A, B, C)) -> bool { !(*other).lt(&(*self)) } #[inline(always)] - pure fn ge(&self, other: &(A, B, C)) -> bool { !(*self).lt(other) } + fn ge(&self, other: &(A, B, C)) -> bool { !(*self).lt(other) } #[inline(always)] - pure fn gt(&self, other: &(A, B, C)) -> bool { (*other).lt(&(*self)) } + fn gt(&self, other: &(A, B, C)) -> bool { (*other).lt(&(*self)) } } #[test] diff --git a/src/libcore/unicode.rs b/src/libcore/unicode.rs index ff3b908186a18..9f2ab66d5c207 100644 --- a/src/libcore/unicode.rs +++ b/src/libcore/unicode.rs @@ -11,7 +11,7 @@ #[doc(hidden)]; // FIXME #3538 pub mod general_category { - pub pure fn Cc(c: char) -> bool { + pub fn Cc(c: char) -> bool { return match c { '\x00' .. '\x1f' | '\x7f' .. '\x9f' => true, @@ -19,7 +19,7 @@ pub mod general_category { }; } - pub pure fn Cf(c: char) -> bool { + pub fn Cf(c: char) -> bool { return match c { '\xad' | '\u0600' .. '\u0603' @@ -38,21 +38,21 @@ pub mod general_category { }; } - pub pure fn Co(c: char) -> bool { + pub fn Co(c: char) -> bool { return match c { '\ue000' .. '\uf8ff' => true, _ => false }; } - pub pure fn Cs(c: char) -> bool { + pub fn Cs(c: char) -> bool { return match c { '\ud800' .. '\udfff' => true, _ => false }; } - pub pure fn Ll(c: char) -> bool { + pub fn Ll(c: char) -> bool { return match c { '\x61' .. '\x7a' | '\xaa' @@ -657,7 +657,7 @@ pub mod general_category { }; } - pub pure fn Lm(c: char) -> bool { + pub fn Lm(c: char) -> bool { return match c { '\u02b0' .. '\u02c1' | '\u02c6' .. '\u02d1' @@ -713,7 +713,7 @@ pub mod general_category { }; } - pub pure fn Lo(c: char) -> bool { + pub fn Lo(c: char) -> bool { return match c { '\u01bb' | '\u01c0' .. '\u01c3' @@ -899,7 +899,7 @@ pub mod general_category { }; } - pub pure fn Lt(c: char) -> bool { + pub fn Lt(c: char) -> bool { return match c { '\u01c5' | '\u01c8' @@ -916,7 +916,7 @@ pub mod general_category { }; } - pub pure fn Lu(c: char) -> bool { + pub fn Lu(c: char) -> bool { return match c { '\x41' .. '\x5a' | '\xc0' .. '\xd6' @@ -1508,7 +1508,7 @@ pub mod general_category { }; } - pub pure fn Mc(c: char) -> bool { + pub fn Mc(c: char) -> bool { return match c { '\u0903' | '\u093b' @@ -1619,7 +1619,7 @@ pub mod general_category { }; } - pub pure fn Me(c: char) -> bool { + pub fn Me(c: char) -> bool { return match c { '\u0488' .. '\u0489' | '\u20dd' .. '\u20e0' @@ -1630,7 +1630,7 @@ pub mod general_category { }; } - pub pure fn Mn(c: char) -> bool { + pub fn Mn(c: char) -> bool { return match c { '\u0300' .. '\u036f' | '\u0483' .. '\u0487' @@ -1823,7 +1823,7 @@ pub mod general_category { }; } - pub pure fn Nd(c: char) -> bool { + pub fn Nd(c: char) -> bool { return match c { '\x30' .. '\x39' | '\u0660' .. '\u0669' @@ -1867,7 +1867,7 @@ pub mod general_category { }; } - pub pure fn Nl(c: char) -> bool { + pub fn Nl(c: char) -> bool { return match c { '\u16ee' .. '\u16f0' | '\u2160' .. '\u2182' @@ -1886,7 +1886,7 @@ pub mod general_category { }; } - pub pure fn No(c: char) -> bool { + pub fn No(c: char) -> bool { return match c { '\xb2' .. '\xb3' | '\xb9' @@ -1934,7 +1934,7 @@ pub mod general_category { }; } - pub pure fn Pc(c: char) -> bool { + pub fn Pc(c: char) -> bool { return match c { '\x5f' | '\u203f' .. '\u2040' @@ -1947,7 +1947,7 @@ pub mod general_category { }; } - pub pure fn Pd(c: char) -> bool { + pub fn Pd(c: char) -> bool { return match c { '\x2d' | '\u058a' @@ -1969,7 +1969,7 @@ pub mod general_category { }; } - pub pure fn Pe(c: char) -> bool { + pub fn Pe(c: char) -> bool { return match c { '\x29' | '\x5d' @@ -2046,7 +2046,7 @@ pub mod general_category { }; } - pub pure fn Pf(c: char) -> bool { + pub fn Pf(c: char) -> bool { return match c { '\xbb' | '\u2019' @@ -2063,7 +2063,7 @@ pub mod general_category { }; } - pub pure fn Pi(c: char) -> bool { + pub fn Pi(c: char) -> bool { return match c { '\xab' | '\u2018' @@ -2081,7 +2081,7 @@ pub mod general_category { }; } - pub pure fn Po(c: char) -> bool { + pub fn Po(c: char) -> bool { return match c { '\x21' .. '\x23' | '\x25' .. '\x27' @@ -2214,7 +2214,7 @@ pub mod general_category { }; } - pub pure fn Ps(c: char) -> bool { + pub fn Ps(c: char) -> bool { return match c { '\x28' | '\x5b' @@ -2293,7 +2293,7 @@ pub mod general_category { }; } - pub pure fn Sc(c: char) -> bool { + pub fn Sc(c: char) -> bool { return match c { '\x24' | '\xa2' .. '\xa5' @@ -2316,7 +2316,7 @@ pub mod general_category { }; } - pub pure fn Sk(c: char) -> bool { + pub fn Sk(c: char) -> bool { return match c { '\x5e' | '\x60' @@ -2350,7 +2350,7 @@ pub mod general_category { }; } - pub pure fn Sm(c: char) -> bool { + pub fn Sm(c: char) -> bool { return match c { '\x2b' | '\x3c' .. '\x3e' @@ -2421,7 +2421,7 @@ pub mod general_category { }; } - pub pure fn So(c: char) -> bool { + pub fn So(c: char) -> bool { return match c { '\xa6' .. '\xa7' | '\xa9' @@ -2540,21 +2540,21 @@ pub mod general_category { }; } - pub pure fn Zl(c: char) -> bool { + pub fn Zl(c: char) -> bool { return match c { '\u2028' => true, _ => false }; } - pub pure fn Zp(c: char) -> bool { + pub fn Zp(c: char) -> bool { return match c { '\u2029' => true, _ => false }; } - pub pure fn Zs(c: char) -> bool { + pub fn Zs(c: char) -> bool { return match c { '\x20' | '\xa0' @@ -2572,7 +2572,7 @@ pub mod general_category { } mod derived_property { /// Check if a character has the alphabetic unicode property - pub pure fn Alphabetic(c: char) -> bool { + pub fn Alphabetic(c: char) -> bool { return match c { '\x41' .. '\x5a' | '\x61' .. '\x7a' @@ -3310,7 +3310,7 @@ mod derived_property { }; } - pub pure fn XID_Continue(c: char) -> bool { + pub fn XID_Continue(c: char) -> bool { return match c { '\x30' .. '\x39' | '\x41' .. '\x5a' @@ -4181,7 +4181,7 @@ mod derived_property { }; } - pub pure fn XID_Start(c: char) -> bool { + pub fn XID_Start(c: char) -> bool { return match c { '\x41' .. '\x5a' | '\x61' .. '\x7a' diff --git a/src/libcore/unstable.rs b/src/libcore/unstable.rs index 899d01cd9963c..6f0c9ba23dfd5 100644 --- a/src/libcore/unstable.rs +++ b/src/libcore/unstable.rs @@ -35,8 +35,6 @@ pub mod extfmt; #[path = "unstable/lang.rs"] #[cfg(notest)] pub mod lang; -#[path = "unstable/uvll.rs"] -pub mod uvll; mod rustrt { use unstable::{raw_thread, rust_little_lock}; @@ -118,6 +116,7 @@ struct ArcDestruct { mut data: *libc::c_void, } +#[unsafe_destructor] impl Drop for ArcDestruct{ fn finalize(&self) { unsafe { diff --git a/src/libcore/unstable/extfmt.rs b/src/libcore/unstable/extfmt.rs index b682f88b70e53..6773a015c6a36 100644 --- a/src/libcore/unstable/extfmt.rs +++ b/src/libcore/unstable/extfmt.rs @@ -97,13 +97,13 @@ pub mod ct { use prelude::*; use str; - #[deriving_eq] + #[deriving(Eq)] pub enum Signedness { Signed, Unsigned, } - #[deriving_eq] + #[deriving(Eq)] pub enum Caseness { CaseUpper, CaseLower, } - #[deriving_eq] + #[deriving(Eq)] pub enum Ty { TyBool, TyStr, @@ -116,7 +116,7 @@ pub mod ct { TyPoly, } - #[deriving_eq] + #[deriving(Eq)] pub enum Flag { FlagLeftJustify, FlagLeftZeroPad, @@ -125,7 +125,7 @@ pub mod ct { FlagAlternate, } - #[deriving_eq] + #[deriving(Eq)] pub enum Count { CountIs(uint), CountIsParam(uint), @@ -133,20 +133,20 @@ pub mod ct { CountImplied, } - #[deriving_eq] + #[deriving(Eq)] struct Parsed { val: T, next: uint } pub impl Parsed { - static pure fn new(&self, val: T, next: uint) -> Parsed { + fn new(val: T, next: uint) -> Parsed { Parsed {val: val, next: next} } } // A formatted conversion from an expression to a string - #[deriving_eq] + #[deriving(Eq)] pub struct Conv { param: Option, flags: ~[Flag], @@ -156,7 +156,7 @@ pub mod ct { } // A fragment of the output sequence - #[deriving_eq] + #[deriving(Eq)] pub enum Piece { PieceString(~str), PieceConv(Conv), } pub type ErrorFn = @fn(&str) -> !; @@ -164,7 +164,7 @@ pub mod ct { pub fn parse_fmt_string(s: &str, err: ErrorFn) -> ~[Piece] { fn push_slice(ps: &mut ~[Piece], s: &str, from: uint, to: uint) { if to > from { - ps.push(PieceString(s.slice(from, to))); + ps.push(PieceString(s.slice(from, to).to_owned())); } } @@ -470,20 +470,25 @@ pub mod ct { // decisions made a runtime. If it proves worthwhile then some of these // conditions can be evaluated at compile-time. For now though it's cleaner to // implement it this way, I think. +#[cfg(stage1)] +#[cfg(stage2)] +#[cfg(stage3)] #[doc(hidden)] pub mod rt { use float; use str; use sys; + use int; use uint; use vec; + use option::{Some, None, Option}; - pub const flag_none : u32 = 0u32; - pub const flag_left_justify : u32 = 0b00000000000001u32; - pub const flag_left_zero_pad : u32 = 0b00000000000010u32; - pub const flag_space_for_sign : u32 = 0b00000000000100u32; - pub const flag_sign_always : u32 = 0b00000000001000u32; - pub const flag_alternate : u32 = 0b00000000010000u32; + pub static flag_none : u32 = 0u32; + pub static flag_left_justify : u32 = 0b00000000000001u32; + pub static flag_left_zero_pad : u32 = 0b00000000000010u32; + pub static flag_space_for_sign : u32 = 0b00000000000100u32; + pub static flag_sign_always : u32 = 0b00000000001000u32; + pub static flag_alternate : u32 = 0b00000000010000u32; pub enum Count { CountIs(uint), CountImplied, } @@ -496,7 +501,210 @@ pub mod rt { ty: Ty, } - pub pure fn conv_int(cv: Conv, i: int) -> ~str { + pub fn conv_int(cv: Conv, i: int, buf: &mut ~str) { + let radix = 10; + let prec = get_int_precision(cv); + let mut s : ~str = uint_to_str_prec(int::abs(i) as uint, radix, prec); + + let head = if i >= 0 { + if have_flag(cv.flags, flag_sign_always) { + Some('+') + } else if have_flag(cv.flags, flag_space_for_sign) { + Some(' ') + } else { + None + } + } else { Some('-') }; + unsafe { pad(cv, s, head, PadSigned, buf) }; + } + pub fn conv_uint(cv: Conv, u: uint, buf: &mut ~str) { + let prec = get_int_precision(cv); + let mut rs = + match cv.ty { + TyDefault => uint_to_str_prec(u, 10, prec), + TyHexLower => uint_to_str_prec(u, 16, prec), + TyHexUpper => str::to_upper(uint_to_str_prec(u, 16, prec)), + TyBits => uint_to_str_prec(u, 2, prec), + TyOctal => uint_to_str_prec(u, 8, prec) + }; + unsafe { pad(cv, rs, None, PadUnsigned, buf) }; + } + pub fn conv_bool(cv: Conv, b: bool, buf: &mut ~str) { + let s = if b { "true" } else { "false" }; + // run the boolean conversion through the string conversion logic, + // giving it the same rules for precision, etc. + conv_str(cv, s, buf); + } + pub fn conv_char(cv: Conv, c: char, buf: &mut ~str) { + unsafe { pad(cv, "", Some(c), PadNozero, buf) }; + } + pub fn conv_str(cv: Conv, s: &str, buf: &mut ~str) { + // For strings, precision is the maximum characters + // displayed + let mut unpadded = match cv.precision { + CountImplied => s, + CountIs(max) => if (max as uint) < str::char_len(s) { + str::slice(s, 0, max as uint) + } else { + s + } + }; + unsafe { pad(cv, unpadded, None, PadNozero, buf) }; + } + pub fn conv_float(cv: Conv, f: float, buf: &mut ~str) { + let (to_str, digits) = match cv.precision { + CountIs(c) => (float::to_str_exact, c as uint), + CountImplied => (float::to_str_digits, 6u) + }; + let mut s = unsafe { to_str(f, digits) }; + let head = if 0.0 <= f { + if have_flag(cv.flags, flag_sign_always) { + Some('+') + } else if have_flag(cv.flags, flag_space_for_sign) { + Some(' ') + } else { + None + } + } else { None }; + unsafe { pad(cv, s, head, PadFloat, buf) }; + } + pub fn conv_poly(cv: Conv, v: &T, buf: &mut ~str) { + let s = sys::log_str(v); + conv_str(cv, s, buf); + } + + // Convert a uint to string with a minimum number of digits. If precision + // is 0 and num is 0 then the result is the empty string. Could move this + // to uint: but it doesn't seem all that useful. + pub fn uint_to_str_prec(num: uint, radix: uint, prec: uint) -> ~str { + return if prec == 0u && num == 0u { + ~"" + } else { + let s = uint::to_str_radix(num, radix); + let len = str::char_len(s); + if len < prec { + let diff = prec - len; + let pad = str::from_chars(vec::from_elem(diff, '0')); + pad + s + } else { s } + }; + } + pub fn get_int_precision(cv: Conv) -> uint { + return match cv.precision { + CountIs(c) => c as uint, + CountImplied => 1u + }; + } + + #[deriving(Eq)] + pub enum PadMode { PadSigned, PadUnsigned, PadNozero, PadFloat } + + pub fn pad(cv: Conv, mut s: &str, head: Option, mode: PadMode, + buf: &mut ~str) { + let headsize = match head { Some(_) => 1, _ => 0 }; + let uwidth : uint = match cv.width { + CountImplied => { + for head.each |&c| { + buf.push_char(c); + } + return buf.push_str(s); + } + CountIs(width) => { width as uint } + }; + let strlen = str::char_len(s) + headsize; + if uwidth <= strlen { + for head.each |&c| { + buf.push_char(c); + } + return buf.push_str(s); + } + let mut padchar = ' '; + let diff = uwidth - strlen; + if have_flag(cv.flags, flag_left_justify) { + for head.each |&c| { + buf.push_char(c); + } + buf.push_str(s); + for diff.times { + buf.push_char(padchar); + } + return; + } + let (might_zero_pad, signed) = match mode { + PadNozero => (false, true), + PadSigned => (true, true), + PadFloat => (true, true), + PadUnsigned => (true, false) + }; + fn have_precision(cv: Conv) -> bool { + return match cv.precision { CountImplied => false, _ => true }; + } + let zero_padding = { + if might_zero_pad && have_flag(cv.flags, flag_left_zero_pad) && + (!have_precision(cv) || mode == PadFloat) { + padchar = '0'; + true + } else { + false + } + }; + let padstr = str::from_chars(vec::from_elem(diff, padchar)); + // This is completely heinous. If we have a signed value then + // potentially rip apart the intermediate result and insert some + // zeros. It may make sense to convert zero padding to a precision + // instead. + + if signed && zero_padding { + for head.each |&head| { + if head == '+' || head == '-' || head == ' ' { + buf.push_char(head); + buf.push_str(padstr); + buf.push_str(s); + return; + } + } + } + buf.push_str(padstr); + for head.each |&c| { + buf.push_char(c); + } + buf.push_str(s); + } + #[inline(always)] + pub fn have_flag(flags: u32, f: u32) -> bool { + flags & f != 0 + } +} + +// XXX: remove after a snapshot of the above changes have gone in +#[cfg(stage0)] +#[doc(hidden)] +pub mod rt { + use float; + use str; + use sys; + use uint; + use vec; + + pub static flag_none : u32 = 0u32; + pub static flag_left_justify : u32 = 0b00000000000001u32; + pub static flag_left_zero_pad : u32 = 0b00000000000010u32; + pub static flag_space_for_sign : u32 = 0b00000000000100u32; + pub static flag_sign_always : u32 = 0b00000000001000u32; + pub static flag_alternate : u32 = 0b00000000010000u32; + + pub enum Count { CountIs(uint), CountImplied, } + + pub enum Ty { TyDefault, TyBits, TyHexUpper, TyHexLower, TyOctal, } + + pub struct Conv { + flags: u32, + width: Count, + precision: Count, + ty: Ty, + } + + pub fn conv_int(cv: Conv, i: int) -> ~str { let radix = 10; let prec = get_int_precision(cv); let mut s : ~str = int_to_str_prec(i, radix, prec); @@ -509,7 +717,7 @@ pub mod rt { } return unsafe { pad(cv, s, PadSigned) }; } - pub pure fn conv_uint(cv: Conv, u: uint) -> ~str { + pub fn conv_uint(cv: Conv, u: uint) -> ~str { let prec = get_int_precision(cv); let mut rs = match cv.ty { @@ -521,30 +729,30 @@ pub mod rt { }; return unsafe { pad(cv, rs, PadUnsigned) }; } - pub pure fn conv_bool(cv: Conv, b: bool) -> ~str { + pub fn conv_bool(cv: Conv, b: bool) -> ~str { let s = if b { ~"true" } else { ~"false" }; // run the boolean conversion through the string conversion logic, // giving it the same rules for precision, etc. return conv_str(cv, s); } - pub pure fn conv_char(cv: Conv, c: char) -> ~str { + pub fn conv_char(cv: Conv, c: char) -> ~str { let mut s = str::from_char(c); return unsafe { pad(cv, s, PadNozero) }; } - pub pure fn conv_str(cv: Conv, s: &str) -> ~str { + pub fn conv_str(cv: Conv, s: &str) -> ~str { // For strings, precision is the maximum characters // displayed let mut unpadded = match cv.precision { CountImplied => s.to_owned(), - CountIs(max) => if max as uint < str::char_len(s) { - str::substr(s, 0, max as uint) + CountIs(max) => if (max as uint) < str::char_len(s) { + str::substr(s, 0, max as uint).to_owned() } else { s.to_owned() } }; return unsafe { pad(cv, unpadded, PadNozero) }; } - pub pure fn conv_float(cv: Conv, f: float) -> ~str { + pub fn conv_float(cv: Conv, f: float) -> ~str { let (to_str, digits) = match cv.precision { CountIs(c) => (float::to_str_exact, c as uint), CountImplied => (float::to_str_digits, 6u) @@ -559,14 +767,14 @@ pub mod rt { } return unsafe { pad(cv, s, PadFloat) }; } - pub pure fn conv_poly(cv: Conv, v: &T) -> ~str { + pub fn conv_poly(cv: Conv, v: &T) -> ~str { let s = sys::log_str(v); return conv_str(cv, s); } // Convert an int to string with minimum number of digits. If precision is // 0 and num is 0 then the result is the empty string. - pub pure fn int_to_str_prec(num: int, radix: uint, prec: uint) -> ~str { + pub fn int_to_str_prec(num: int, radix: uint, prec: uint) -> ~str { return if num < 0 { ~"-" + uint_to_str_prec(-num as uint, radix, prec) } else { uint_to_str_prec(num as uint, radix, prec) }; @@ -575,7 +783,7 @@ pub mod rt { // Convert a uint to string with a minimum number of digits. If precision // is 0 and num is 0 then the result is the empty string. Could move this // to uint: but it doesn't seem all that useful. - pub pure fn uint_to_str_prec(num: uint, radix: uint, + pub fn uint_to_str_prec(num: uint, radix: uint, prec: uint) -> ~str { return if prec == 0u && num == 0u { ~"" @@ -589,14 +797,14 @@ pub mod rt { } else { s } }; } - pub pure fn get_int_precision(cv: Conv) -> uint { + pub fn get_int_precision(cv: Conv) -> uint { return match cv.precision { CountIs(c) => c as uint, CountImplied => 1u }; } - #[deriving_eq] + #[deriving(Eq)] pub enum PadMode { PadSigned, PadUnsigned, PadNozero, PadFloat } pub fn pad(cv: Conv, s: ~str, mode: PadMode) -> ~str { @@ -619,7 +827,7 @@ pub mod rt { PadFloat => (true, true), PadUnsigned => (true, false) }; - pure fn have_precision(cv: Conv) -> bool { + fn have_precision(cv: Conv) -> bool { return match cv.precision { CountImplied => false, _ => true }; } let zero_padding = { @@ -649,7 +857,7 @@ pub mod rt { } return padstr + s; } - pub pure fn have_flag(flags: u32, f: u32) -> bool { + pub fn have_flag(flags: u32, f: u32) -> bool { flags & f != 0 } } diff --git a/src/libcore/unstable/finally.rs b/src/libcore/unstable/finally.rs index e8c27ff7d92d2..04d1d6f11b929 100644 --- a/src/libcore/unstable/finally.rs +++ b/src/libcore/unstable/finally.rs @@ -41,11 +41,12 @@ impl Finally for &'self fn() -> T { } } -struct Finallyalizer { +struct Finallyalizer<'self> { dtor: &'self fn() } -impl Drop for Finallyalizer/&self { +#[unsafe_destructor] +impl<'self> Drop for Finallyalizer<'self> { fn finalize(&self) { (self.dtor)(); } diff --git a/src/libcore/unstable/global.rs b/src/libcore/unstable/global.rs index 660336055590e..32e1b35d7db9f 100644 --- a/src/libcore/unstable/global.rs +++ b/src/libcore/unstable/global.rs @@ -159,7 +159,7 @@ impl Drop for GlobalState { fn get_global_state() -> Exclusive { - const POISON: int = -1; + static POISON: int = -1; // FIXME #4728: Doing atomic_cxchg to initialize the global state // lazily, which wouldn't be necessary with a runtime written diff --git a/src/libcore/unstable/lang.rs b/src/libcore/unstable/lang.rs index db0b1cc33cd67..5d7920ce820eb 100644 --- a/src/libcore/unstable/lang.rs +++ b/src/libcore/unstable/lang.rs @@ -22,9 +22,9 @@ use cast::transmute; pub type rust_task = c_void; #[cfg(target_word_size = "32")] -pub const FROZEN_BIT: uint = 0x80000000; +pub static FROZEN_BIT: uint = 0x80000000; #[cfg(target_word_size = "64")] -pub const FROZEN_BIT: uint = 0x8000000000000000; +pub static FROZEN_BIT: uint = 0x8000000000000000; pub mod rustrt { use libc::{c_char, uintptr_t}; @@ -120,16 +120,25 @@ pub unsafe fn strdup_uniq(ptr: *c_uchar, len: uint) -> ~str { #[lang="start"] pub fn start(main: *u8, argc: int, argv: *c_char, crate_map: *u8) -> int { + use libc::getenv; + use rt::start; + + unsafe { + let use_new_rt = do str::as_c_str("RUST_NEWRT") |s| { + getenv(s).is_null() + }; + if use_new_rt { + return rust_start(main as *c_void, argc as c_int, argv, + crate_map as *c_void) as int; + } else { + return start(main, argc, argv, crate_map); + } + } extern { fn rust_start(main: *c_void, argc: c_int, argv: *c_char, crate_map: *c_void) -> c_int; } - - unsafe { - return rust_start(main as *c_void, argc as c_int, argv, - crate_map as *c_void) as int; - } } // Local Variables: diff --git a/src/libcore/util.rs b/src/libcore/util.rs index 214a9dea8d18c..739314bf61908 100644 --- a/src/libcore/util.rs +++ b/src/libcore/util.rs @@ -18,11 +18,11 @@ use prelude::*; /// The identity function. #[inline(always)] -pub pure fn id(x: T) -> T { x } +pub fn id(x: T) -> T { x } /// Ignores a value. #[inline(always)] -pub pure fn ignore(_x: T) { } +pub fn ignore(_x: T) { } /// Sets `*ptr` to `new_value`, invokes `op()`, and then restores the /// original value of `*ptr`. diff --git a/src/libcore/vec.rs b/src/libcore/vec.rs index dc220eaed1bee..9def28fd3aa78 100644 --- a/src/libcore/vec.rs +++ b/src/libcore/vec.rs @@ -47,12 +47,12 @@ pub mod rustrt { } /// Returns true if a vector contains no elements -pub pure fn is_empty(v: &[const T]) -> bool { +pub fn is_empty(v: &[const T]) -> bool { as_const_buf(v, |_p, len| len == 0u) } /// Returns true if two vectors have the same length -pub pure fn same_length(xs: &[const T], ys: &[const U]) -> bool { +pub fn same_length(xs: &[const T], ys: &[const U]) -> bool { xs.len() == ys.len() } @@ -105,7 +105,7 @@ pub fn reserve_at_least(v: &mut ~[T], n: uint) { /// Returns the number of elements the vector can hold without reallocating #[inline(always)] -pub pure fn capacity(v: &const ~[T]) -> uint { +pub fn capacity(v: &const ~[T]) -> uint { unsafe { let repr: **raw::VecRepr = ::cast::transmute(v); (**repr).unboxed.alloc / sys::nonzero_size_of::() @@ -114,12 +114,12 @@ pub pure fn capacity(v: &const ~[T]) -> uint { /// Returns the length of a vector #[inline(always)] -pub pure fn len(v: &[const T]) -> uint { +pub fn len(v: &[const T]) -> uint { as_const_buf(v, |_p, len| len) } // A botch to tide us over until core and std are fully demuted. -pub pure fn uniq_len(v: &const ~[T]) -> uint { +pub fn uniq_len(v: &const ~[T]) -> uint { unsafe { let v: &~[T] = ::cast::transmute(v); as_const_buf(*v, |_p, len| len) @@ -132,7 +132,7 @@ pub pure fn uniq_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`. */ -pub pure fn from_fn(n_elts: uint, op: iter::InitOp) -> ~[T] { +pub 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| { @@ -154,16 +154,16 @@ pub 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`. */ -pub pure fn from_elem(n_elts: uint, t: T) -> ~[T] { +pub 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 -pub pure fn from_slice(t: &[T]) -> ~[T] { +pub fn from_slice(t: &[T]) -> ~[T] { from_fn(t.len(), |i| t[i]) } -pub pure fn with_capacity(capacity: uint) -> ~[T] { +pub fn with_capacity(capacity: uint) -> ~[T] { let mut vec = ~[]; unsafe { reserve(&mut vec, capacity); } vec @@ -182,8 +182,7 @@ pub pure fn with_capacity(capacity: uint) -> ~[T] { * onto the vector being constructed. */ #[inline(always)] -pub pure fn build_sized(size: uint, - builder: &fn(push: &pure fn(v: A))) -> ~[A] { +pub fn build_sized(size: uint, builder: &fn(push: &fn(v: A))) -> ~[A] { let mut vec = with_capacity(size); builder(|x| unsafe { vec.push(x) }); vec @@ -200,7 +199,7 @@ pub pure fn build_sized(size: uint, * onto the vector being constructed. */ #[inline(always)] -pub pure fn build(builder: &fn(push: &pure fn(v: A))) -> ~[A] { +pub fn build(builder: &fn(push: &fn(v: A))) -> ~[A] { build_sized(4, builder) } @@ -217,54 +216,55 @@ pub pure fn build(builder: &fn(push: &pure fn(v: A))) -> ~[A] { * onto the vector being constructed. */ #[inline(always)] -pub pure fn build_sized_opt(size: Option, - builder: &fn(push: &pure fn(v: A))) -> ~[A] { +pub fn build_sized_opt(size: Option, + builder: &fn(push: &fn(v: A))) + -> ~[A] { build_sized(size.get_or_default(4), builder) } // Accessors /// Returns the first element of a vector -pub pure fn head(v: &'r [T]) -> &'r T { +pub fn head(v: &'r [T]) -> &'r T { if v.len() == 0 { fail!(~"head: empty vector") } &v[0] } /// Returns `Some(x)` where `x` is the first element of the slice `v`, /// or `None` if the vector is empty. -pub pure fn head_opt(v: &'r [T]) -> Option<&'r T> { +pub fn head_opt(v: &'r [T]) -> Option<&'r T> { if v.len() == 0 { None } else { Some(&v[0]) } } /// Returns a vector containing all but the first element of a slice -pub pure fn tail(v: &'r [T]) -> &'r [T] { slice(v, 1, v.len()) } +pub fn tail(v: &'r [T]) -> &'r [T] { slice(v, 1, v.len()) } /// Returns a vector containing all but the first `n` elements of a slice -pub pure fn tailn(v: &'r [T], n: uint) -> &'r [T] { slice(v, n, v.len()) } +pub fn tailn(v: &'r [T], n: uint) -> &'r [T] { slice(v, n, v.len()) } /// Returns a vector containing all but the last element of a slice -pub pure fn init(v: &'r [T]) -> &'r [T] { slice(v, 0, v.len() - 1) } +pub fn init(v: &'r [T]) -> &'r [T] { slice(v, 0, v.len() - 1) } /// Returns a vector containing all but the last `n' elements of a slice -pub pure fn initn(v: &'r [T], n: uint) -> &'r [T] { +pub fn initn(v: &'r [T], n: uint) -> &'r [T] { slice(v, 0, v.len() - n) } /// Returns the last element of the slice `v`, failing if the slice is empty. -pub pure fn last(v: &'r [T]) -> &'r T { +pub fn last(v: &'r [T]) -> &'r T { if v.len() == 0 { fail!(~"last: empty vector") } &v[v.len() - 1] } /// Returns `Some(x)` where `x` is the last element of the slice `v`, or /// `None` if the vector is empty. -pub pure fn last_opt(v: &'r [T]) -> Option<&'r T> { +pub fn last_opt(v: &'r [T]) -> Option<&'r T> { if v.len() == 0 { None } else { Some(&v[v.len() - 1]) } } /// Return a slice that points into another slice. #[inline(always)] -pub pure fn slice(v: &'r [T], start: uint, end: uint) -> &'r [T] { +pub fn slice(v: &'r [T], start: uint, end: uint) -> &'r [T] { fail_unless!(start <= end); fail_unless!(end <= len(v)); do as_imm_buf(v) |p, _len| { @@ -278,10 +278,7 @@ pub pure fn slice(v: &'r [T], start: uint, end: uint) -> &'r [T] { /// Return a slice that points into another slice. #[inline(always)] -pub pure fn mut_slice(v: &'r mut [T], - start: uint, - end: uint) - -> &'r mut [T] { +pub fn mut_slice(v: &'r mut [T], start: uint, end: uint) -> &'r mut [T] { fail_unless!(start <= end); fail_unless!(end <= v.len()); do as_mut_buf(v) |p, _len| { @@ -295,10 +292,8 @@ pub pure fn mut_slice(v: &'r mut [T], /// Return a slice that points into another slice. #[inline(always)] -pub pure fn const_slice(v: &'r [const T], - start: uint, - end: uint) - -> &'r [const T] { +pub fn const_slice(v: &'r [const T], start: uint, end: uint) + -> &'r [const T] { fail_unless!(start <= end); fail_unless!(end <= len(v)); do as_const_buf(v) |p, _len| { @@ -434,7 +429,7 @@ pub fn partition(v: ~[T], f: &fn(&T) -> bool) -> (~[T], ~[T]) { * Partitions a vector into two new vectors: those that satisfies the * predicate, and those that do not. */ -pub pure fn partitioned(v: &[T], f: &fn(&T) -> bool) -> (~[T], ~[T]) { +pub fn partitioned(v: &[T], f: &fn(&T) -> bool) -> (~[T], ~[T]) { let mut lefts = ~[]; let mut rights = ~[]; @@ -713,7 +708,7 @@ pub fn dedup(v: &mut ~[T]) { // Appending #[inline(always)] -pub pure fn append(lhs: ~[T], rhs: &[const T]) -> ~[T] { +pub fn append(lhs: ~[T], rhs: &[const T]) -> ~[T] { let mut v = lhs; unsafe { v.push_all(rhs); @@ -722,7 +717,7 @@ pub pure fn append(lhs: ~[T], rhs: &[const T]) -> ~[T] { } #[inline(always)] -pub pure fn append_one(lhs: ~[T], x: T) -> ~[T] { +pub fn append_one(lhs: ~[T], x: T) -> ~[T] { let mut v = lhs; unsafe { v.push(x); } v @@ -788,7 +783,7 @@ pub fn grow_set(v: &mut ~[T], index: uint, initval: &T, val: T) { // Functional utilities /// Apply a function to each element of a vector and return the results -pub pure fn map(v: &[T], f: &fn(t: &T) -> U) -> ~[U] { +pub fn map(v: &[T], f: &fn(t: &T) -> U) -> ~[U] { let mut result = with_capacity(len(v)); for each(v) |elem| { unsafe { @@ -807,7 +802,7 @@ pub fn map_consume(v: ~[T], f: &fn(v: T) -> U) -> ~[U] { } /// Apply a function to each element of a vector and return the results -pub pure fn mapi(v: &[T], f: &fn(uint, t: &T) -> U) -> ~[U] { +pub fn mapi(v: &[T], f: &fn(uint, t: &T) -> U) -> ~[U] { let mut i = 0; do map(v) |e| { i += 1; @@ -819,14 +814,14 @@ pub pure fn mapi(v: &[T], f: &fn(uint, t: &T) -> U) -> ~[U] { * Apply a function to each element of a vector and return a concatenation * of each result vector */ -pub pure fn flat_map(v: &[T], f: &fn(t: &T) -> ~[U]) -> ~[U] { +pub fn flat_map(v: &[T], f: &fn(t: &T) -> ~[U]) -> ~[U] { let mut result = ~[]; for each(v) |elem| { unsafe{ result.push_all_move(f(elem)); } } result } /// Apply a function to each pair of elements and return the results -pub pure fn map2(v0: &[T], v1: &[U], +pub 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!(); } @@ -860,7 +855,7 @@ pub fn filter_map( result } -pub pure fn filter_mapped( +pub fn filter_mapped( v: &[T], f: &fn(t: &T) -> Option) -> ~[U] { @@ -904,7 +899,7 @@ pub fn filter(v: ~[T], f: &fn(t: &T) -> bool) -> ~[T] { * Apply function `f` to each element of `v` and return a vector containing * only those elements for which `f` returned true. */ -pub pure fn filtered(v: &[T], f: &fn(t: &T) -> bool) -> ~[T] { +pub fn filtered(v: &[T], f: &fn(t: &T) -> bool) -> ~[T] { let mut result = ~[]; for each(v) |elem| { if f(elem) { unsafe { result.push(*elem); } } @@ -915,7 +910,7 @@ pub pure fn filtered(v: &[T], f: &fn(t: &T) -> bool) -> ~[T] { /** * Like `filter()`, but in place. Preserves order of `v`. Linear time. */ -pub fn retain(v: &mut ~[T], f: &pure fn(t: &T) -> bool) { +pub fn retain(v: &mut ~[T], f: &fn(t: &T) -> bool) { let len = v.len(); let mut deleted: uint = 0; @@ -937,14 +932,14 @@ pub fn retain(v: &mut ~[T], f: &pure fn(t: &T) -> bool) { * * Flattens a vector of vectors of T into a single vector of T. */ -pub pure fn concat(v: &[~[T]]) -> ~[T] { +pub fn concat(v: &[~[T]]) -> ~[T] { let mut r = ~[]; for each(v) |inner| { unsafe { r.push_all(*inner); } } r } /// Concatenate a vector of vectors, placing a given separator between each -pub pure fn connect(v: &[~[T]], sep: &T) -> ~[T] { +pub fn connect(v: &[~[T]], sep: &T) -> ~[T] { let mut r: ~[T] = ~[]; let mut first = true; for each(v) |inner| { @@ -971,7 +966,7 @@ pub pure fn connect(v: &[~[T]], sep: &T) -> ~[T] { * ~~~ * */ -pub pure fn foldl(z: T, v: &[U], p: &fn(t: T, u: &U) -> T) -> T { +pub fn foldl(z: T, v: &[U], p: &fn(t: T, u: &U) -> T) -> T { let mut accum = z; let mut i = 0; let l = v.len(); @@ -1003,9 +998,9 @@ pub pure fn foldl(z: T, v: &[U], p: &fn(t: T, u: &U) -> T) -> T { * ~~~ * */ -pub pure fn foldr(v: &[T], z: U, p: &fn(t: &T, u: U) -> U) -> U { +pub fn foldr(v: &[T], z: U, p: &fn(t: &T, u: U) -> U) -> U { let mut accum = z; - for rev_each(v) |elt| { + for v.each_reverse |elt| { accum = p(elt, accum); } accum @@ -1016,7 +1011,7 @@ pub pure fn foldr(v: &[T], z: U, p: &fn(t: &T, u: U) -> U) -> U { * * If the vector contains no elements then false is returned. */ -pub pure fn any(v: &[T], f: &fn(t: &T) -> bool) -> bool { +pub fn any(v: &[T], f: &fn(t: &T) -> bool) -> bool { for each(v) |elem| { if f(elem) { return true; } } false } @@ -1026,7 +1021,7 @@ pub pure fn any(v: &[T], f: &fn(t: &T) -> bool) -> bool { * * If the vectors contains no elements then false is returned. */ -pub pure fn any2(v0: &[T], v1: &[U], +pub fn any2(v0: &[T], v1: &[U], f: &fn(a: &T, b: &U) -> bool) -> bool { let v0_len = len(v0); let v1_len = len(v1); @@ -1043,7 +1038,7 @@ pub pure fn any2(v0: &[T], v1: &[U], * * If the vector contains no elements then true is returned. */ -pub pure fn all(v: &[T], f: &fn(t: &T) -> bool) -> bool { +pub fn all(v: &[T], f: &fn(t: &T) -> bool) -> bool { for each(v) |elem| { if !f(elem) { return false; } } true } @@ -1053,7 +1048,7 @@ pub pure fn all(v: &[T], f: &fn(t: &T) -> bool) -> bool { * * If the vector contains no elements then true is returned. */ -pub pure fn alli(v: &[T], f: &fn(uint, t: &T) -> bool) -> bool { +pub fn alli(v: &[T], f: &fn(uint, t: &T) -> bool) -> bool { for eachi(v) |i, elem| { if !f(i, elem) { return false; } } true } @@ -1063,7 +1058,7 @@ pub pure fn alli(v: &[T], f: &fn(uint, t: &T) -> bool) -> bool { * * If the vectors are not the same size then false is returned. */ -pub pure fn all2(v0: &[T], v1: &[U], +pub 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; } @@ -1073,13 +1068,13 @@ pub pure fn all2(v0: &[T], v1: &[U], } /// Return true if a vector contains an element with the given value -pub pure fn contains(v: &[T], x: &T) -> bool { +pub fn contains(v: &[T], x: &T) -> bool { for each(v) |elt| { if *x == *elt { return true; } } false } /// Returns the number of elements that are equal to a given value -pub pure fn count(v: &[T], x: &T) -> uint { +pub fn count(v: &[T], x: &T) -> uint { let mut cnt = 0u; for each(v) |elt| { if *x == *elt { cnt += 1u; } } cnt @@ -1092,7 +1087,7 @@ pub 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. */ -pub pure fn find(v: &[T], f: &fn(t: &T) -> bool) -> Option { +pub fn find(v: &[T], f: &fn(t: &T) -> bool) -> Option { find_between(v, 0u, len(v), f) } @@ -1103,7 +1098,7 @@ pub pure fn find(v: &[T], f: &fn(t: &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. */ -pub pure fn find_between(v: &[T], start: uint, end: uint, +pub 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]) } @@ -1115,7 +1110,7 @@ pub 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. */ -pub pure fn rfind(v: &[T], f: &fn(t: &T) -> bool) -> Option { +pub fn rfind(v: &[T], f: &fn(t: &T) -> bool) -> Option { rfind_between(v, 0u, len(v), f) } @@ -1126,13 +1121,16 @@ pub pure fn rfind(v: &[T], f: &fn(t: &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 return. */ -pub pure fn rfind_between(v: &[T], start: uint, end: uint, - f: &fn(t: &T) -> bool) -> Option { +pub 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 -pub pure fn position_elem(v: &[T], x: &T) -> Option { +pub fn position_elem(v: &[T], x: &T) -> Option { position(v, |y| *x == *y) } @@ -1143,7 +1141,7 @@ pub 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. */ -pub pure fn position(v: &[T], f: &fn(t: &T) -> bool) -> Option { +pub fn position(v: &[T], f: &fn(t: &T) -> bool) -> Option { position_between(v, 0u, len(v), f) } @@ -1154,8 +1152,11 @@ pub pure fn position(v: &[T], f: &fn(t: &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. */ -pub pure fn position_between(v: &[T], start: uint, end: uint, - f: &fn(t: &T) -> bool) -> Option { +pub fn position_between(v: &[T], + start: uint, + end: uint, + f: &fn(t: &T) -> bool) + -> Option { fail_unless!(start <= end); fail_unless!(end <= len(v)); let mut i = start; @@ -1164,7 +1165,7 @@ pub pure fn position_between(v: &[T], start: uint, end: uint, } /// Find the last index containing a matching value -pure fn rposition_elem(v: &[T], x: &T) -> Option { +pub fn rposition_elem(v: &[T], x: &T) -> Option { rposition(v, |y| *x == *y) } @@ -1175,7 +1176,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. */ -pub pure fn rposition(v: &[T], f: &fn(t: &T) -> bool) -> Option { +pub fn rposition(v: &[T], f: &fn(t: &T) -> bool) -> Option { rposition_between(v, 0u, len(v), f) } @@ -1187,7 +1188,7 @@ pub pure fn rposition(v: &[T], f: &fn(t: &T) -> bool) -> Option { * containing the index is returned. If `f` matches no elements then none is * returned. */ -pub pure fn rposition_between(v: &[T], start: uint, end: uint, +pub fn rposition_between(v: &[T], start: uint, end: uint, f: &fn(t: &T) -> bool) -> Option { fail_unless!(start <= end); fail_unless!(end <= len(v)); @@ -1206,7 +1207,7 @@ pub 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]) { +pub fn unzip_slice(v: &[(T, U)]) -> (~[T], ~[U]) { let mut ts = ~[], us = ~[]; for each(v) |p| { let (t, u) = *p; @@ -1226,7 +1227,7 @@ 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. */ -pub pure fn unzip(v: ~[(T, U)]) -> (~[T], ~[U]) { +pub fn unzip(v: ~[(T, U)]) -> (~[T], ~[U]) { let mut ts = ~[], us = ~[]; unsafe { do consume(v) |_i, p| { @@ -1241,7 +1242,7 @@ pub pure fn unzip(v: ~[(T, U)]) -> (~[T], ~[U]) { /** * Convert two vectors to a vector of pairs, by reference. As zip(). */ -pub pure fn zip_slice(v: &[const T], u: &[const U]) +pub fn zip_slice(v: &[const T], u: &[const U]) -> ~[(T, U)] { let mut zipped = ~[]; let sz = len(v); @@ -1259,7 +1260,7 @@ pub 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. */ -pub pure fn zip(mut v: ~[T], mut u: ~[U]) -> ~[(T, U)] { +pub fn zip(mut v: ~[T], mut u: ~[U]) -> ~[(T, U)] { let mut i = len(v); fail_unless!(i == len(u)); let mut w = with_capacity(i); @@ -1292,7 +1293,7 @@ pub fn reverse(v: &mut [T]) { } /// Returns a vector with the order of elements reversed -pub pure fn reversed(v: &[const T]) -> ~[T] { +pub fn reversed(v: &[const T]) -> ~[T] { let mut rs: ~[T] = ~[]; let mut i = len::(v); if i == 0 { return (rs); } else { i -= 1; } @@ -1342,7 +1343,7 @@ pub pure fn reversed(v: &[const T]) -> ~[T] { * ~~~ */ #[inline(always)] -pub pure fn each(v: &'r [T], f: &fn(&'r T) -> bool) { +pub 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 @@ -1380,7 +1381,7 @@ pub fn each_mut(v: &'r mut [T], f: &fn(elem: &'r mut T) -> bool) { /// Like `each()`, but for the case where you have a vector that *may or may /// not* have mutable contents. #[inline(always)] -pub pure fn each_const(v: &[const T], f: &fn(elem: &const T) -> bool) { +pub fn each_const(v: &[const T], f: &fn(elem: &const T) -> bool) { let mut i = 0; let n = v.len(); while i < n { @@ -1397,7 +1398,7 @@ pub pure fn each_const(v: &[const T], f: &fn(elem: &const T) -> bool) { * Return true to continue, false to break. */ #[inline(always)] -pub pure fn eachi(v: &'r [T], f: &fn(uint, v: &'r T) -> bool) { +pub 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; } @@ -1411,8 +1412,8 @@ pub pure fn eachi(v: &'r [T], f: &fn(uint, v: &'r T) -> bool) { * Return true to continue, false to break. */ #[inline(always)] -pub pure fn rev_each(v: &'r [T], blk: &fn(v: &'r T) -> bool) { - rev_eachi(v, |_i, v| blk(v)) +pub fn each_reverse(v: &'r [T], blk: &fn(v: &'r T) -> bool) { + eachi_reverse(v, |_i, v| blk(v)) } /** @@ -1421,7 +1422,7 @@ pub pure fn rev_each(v: &'r [T], blk: &fn(v: &'r T) -> bool) { * Return true to continue, false to break. */ #[inline(always)] -pub pure fn rev_eachi(v: &'r [T], blk: &fn(i: uint, v: &'r T) -> bool) { +pub fn eachi_reverse(v: &'r [T], blk: &fn(i: uint, v: &'r T) -> bool) { let mut i = v.len(); while i > 0 { i -= 1; @@ -1439,7 +1440,7 @@ pub pure fn rev_eachi(v: &'r [T], blk: &fn(i: uint, v: &'r T) -> bool) { * Both vectors must have the same length */ #[inline] -pub pure fn each2(v1: &[U], v2: &[T], f: &fn(u: &U, t: &T) -> bool) { +pub fn each2(v1: &[U], v2: &[T], f: &fn(u: &U, t: &T) -> bool) { fail_unless!(len(v1) == len(v2)); for uint::range(0u, len(v1)) |i| { if !f(&v1[i], &v2[i]) { @@ -1458,7 +1459,7 @@ pub pure fn each2(v1: &[U], v2: &[T], f: &fn(u: &U, t: &T) -> bool) { * The total number of permutations produced is `len(v)!`. If `v` contains * repeated elements, then some permutations are repeated. */ -pub pure fn each_permutation(v: &[T], put: &fn(ts: &[T]) -> bool) { +pub fn each_permutation(v: &[T], put: &fn(ts: &[T]) -> bool) { let ln = len(v); if ln <= 1 { put(v); @@ -1482,7 +1483,7 @@ pub pure fn each_permutation(v: &[T], put: &fn(ts: &[T]) -> bool) { } } -pub pure fn windowed(nn: uint, xx: &[TT]) -> ~[~[TT]] { +pub fn windowed(nn: uint, xx: &[TT]) -> ~[~[TT]] { let mut ww = ~[]; fail_unless!(1u <= nn); for vec::eachi (xx) |ii, _x| { @@ -1503,9 +1504,9 @@ pub pure fn windowed(nn: uint, xx: &[TT]) -> ~[~[TT]] { * foreign interop. */ #[inline(always)] -pub pure fn as_imm_buf(s: &[T], - /* NB---this CANNOT be const, see below */ - f: &fn(*T, uint) -> U) -> U { +pub 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 @@ -1523,9 +1524,7 @@ pub pure fn as_imm_buf(s: &[T], /// Similar to `as_imm_buf` but passing a `*const T` #[inline(always)] -pub pure fn as_const_buf(s: &[const T], - f: &fn(*const T, uint) -> U) -> U { - +pub fn as_const_buf(s: &[const T], f: &fn(*const T, uint) -> U) -> U { unsafe { let v : *(*const T,uint) = ::cast::reinterpret_cast(&addr_of(&s)); @@ -1536,9 +1535,7 @@ pub pure fn as_const_buf(s: &[const T], /// Similar to `as_imm_buf` but passing a `*mut T` #[inline(always)] -pub pure fn as_mut_buf(s: &mut [T], - f: &fn(*mut T, uint) -> U) -> U { - +pub fn as_mut_buf(s: &mut [T], f: &fn(*mut T, uint) -> U) -> U { unsafe { let v : *(*mut T,uint) = ::cast::reinterpret_cast(&addr_of(&s)); @@ -1549,7 +1546,7 @@ pub pure fn as_mut_buf(s: &mut [T], // Equality -pure fn eq(a: &[T], b: &[T]) -> bool { +fn eq(a: &[T], b: &[T]) -> bool { let (a_len, b_len) = (a.len(), b.len()); if a_len != b_len { return false; } @@ -1565,37 +1562,37 @@ pure fn eq(a: &[T], b: &[T]) -> bool { #[cfg(notest)] impl Eq for &'self [T] { #[inline(always)] - pure fn eq(&self, other: & &'self [T]) -> bool { eq((*self), (*other)) } + fn eq(&self, other: & &'self [T]) -> bool { eq((*self), (*other)) } #[inline(always)] - pure fn ne(&self, other: & &'self [T]) -> bool { !(*self).eq(other) } + fn ne(&self, other: & &'self [T]) -> bool { !(*self).eq(other) } } #[cfg(notest)] impl Eq for ~[T] { #[inline(always)] - pure fn eq(&self, other: &~[T]) -> bool { eq((*self), (*other)) } + fn eq(&self, other: &~[T]) -> bool { eq((*self), (*other)) } #[inline(always)] - pure fn ne(&self, other: &~[T]) -> bool { !(*self).eq(other) } + fn ne(&self, other: &~[T]) -> bool { !(*self).eq(other) } } #[cfg(notest)] impl Eq for @[T] { #[inline(always)] - pure fn eq(&self, other: &@[T]) -> bool { eq((*self), (*other)) } + fn eq(&self, other: &@[T]) -> bool { eq((*self), (*other)) } #[inline(always)] - pure fn ne(&self, other: &@[T]) -> bool { !(*self).eq(other) } + fn ne(&self, other: &@[T]) -> bool { !(*self).eq(other) } } #[cfg(notest)] impl Equiv<~[T]> for &'self [T] { #[inline(always)] - pure fn equiv(&self, other: &~[T]) -> bool { eq(*self, *other) } + fn equiv(&self, other: &~[T]) -> bool { eq(*self, *other) } } // Lexicographical comparison -pure fn cmp(a: &[T], b: &[T]) -> Ordering { +fn cmp(a: &[T], b: &[T]) -> Ordering { let low = uint::min(a.len(), b.len()); for uint::range(0, low) |idx| { @@ -1612,22 +1609,22 @@ pure fn cmp(a: &[T], b: &[T]) -> Ordering { #[cfg(notest)] impl TotalOrd for &'self [T] { #[inline(always)] - pure fn cmp(&self, other: & &'self [T]) -> Ordering { cmp(*self, *other) } + fn cmp(&self, other: & &'self [T]) -> Ordering { cmp(*self, *other) } } #[cfg(notest)] impl TotalOrd for ~[T] { #[inline(always)] - pure fn cmp(&self, other: &~[T]) -> Ordering { cmp(*self, *other) } + fn cmp(&self, other: &~[T]) -> Ordering { cmp(*self, *other) } } #[cfg(notest)] impl TotalOrd for @[T] { #[inline(always)] - pure fn cmp(&self, other: &@[T]) -> Ordering { cmp(*self, *other) } + fn cmp(&self, other: &@[T]) -> Ordering { cmp(*self, *other) } } -pure fn lt(a: &[T], b: &[T]) -> bool { +fn lt(a: &[T], b: &[T]) -> bool { let (a_len, b_len) = (a.len(), b.len()); let mut end = uint::min(a_len, b_len); @@ -1642,44 +1639,44 @@ pure fn lt(a: &[T], b: &[T]) -> bool { a_len < b_len } -pure fn le(a: &[T], b: &[T]) -> bool { !lt(b, a) } -pure fn ge(a: &[T], b: &[T]) -> bool { !lt(a, b) } -pure fn gt(a: &[T], b: &[T]) -> bool { lt(b, a) } +fn le(a: &[T], b: &[T]) -> bool { !lt(b, a) } +fn ge(a: &[T], b: &[T]) -> bool { !lt(a, b) } +fn gt(a: &[T], b: &[T]) -> bool { lt(b, a) } #[cfg(notest)] impl Ord for &'self [T] { #[inline(always)] - pure fn lt(&self, other: & &'self [T]) -> bool { lt((*self), (*other)) } + fn lt(&self, other: & &'self [T]) -> bool { lt((*self), (*other)) } #[inline(always)] - pure fn le(&self, other: & &'self [T]) -> bool { le((*self), (*other)) } + fn le(&self, other: & &'self [T]) -> bool { le((*self), (*other)) } #[inline(always)] - pure fn ge(&self, other: & &'self [T]) -> bool { ge((*self), (*other)) } + fn ge(&self, other: & &'self [T]) -> bool { ge((*self), (*other)) } #[inline(always)] - pure fn gt(&self, other: & &'self [T]) -> bool { gt((*self), (*other)) } + fn gt(&self, other: & &'self [T]) -> bool { gt((*self), (*other)) } } #[cfg(notest)] impl Ord for ~[T] { #[inline(always)] - pure fn lt(&self, other: &~[T]) -> bool { lt((*self), (*other)) } + fn lt(&self, other: &~[T]) -> bool { lt((*self), (*other)) } #[inline(always)] - pure fn le(&self, other: &~[T]) -> bool { le((*self), (*other)) } + fn le(&self, other: &~[T]) -> bool { le((*self), (*other)) } #[inline(always)] - pure fn ge(&self, other: &~[T]) -> bool { ge((*self), (*other)) } + fn ge(&self, other: &~[T]) -> bool { ge((*self), (*other)) } #[inline(always)] - pure fn gt(&self, other: &~[T]) -> bool { gt((*self), (*other)) } + fn gt(&self, other: &~[T]) -> bool { gt((*self), (*other)) } } #[cfg(notest)] impl Ord for @[T] { #[inline(always)] - pure fn lt(&self, other: &@[T]) -> bool { lt((*self), (*other)) } + fn lt(&self, other: &@[T]) -> bool { lt((*self), (*other)) } #[inline(always)] - pure fn le(&self, other: &@[T]) -> bool { le((*self), (*other)) } + fn le(&self, other: &@[T]) -> bool { le((*self), (*other)) } #[inline(always)] - pure fn ge(&self, other: &@[T]) -> bool { ge((*self), (*other)) } + fn ge(&self, other: &@[T]) -> bool { ge((*self), (*other)) } #[inline(always)] - pure fn gt(&self, other: &@[T]) -> bool { gt((*self), (*other)) } + fn gt(&self, other: &@[T]) -> bool { gt((*self), (*other)) } } #[cfg(notest)] @@ -1690,7 +1687,7 @@ pub mod traits { impl Add<&'self [const T],~[T]> for ~[T] { #[inline(always)] - pure fn add(&self, rhs: & &'self [const T]) -> ~[T] { + fn add(&self, rhs: & &'self [const T]) -> ~[T] { append(copy *self, (*rhs)) } } @@ -1699,107 +1696,123 @@ pub mod traits { impl Container for &'self [const T] { /// Returns true if a vector contains no elements #[inline] - pure fn is_empty(&const self) -> bool { is_empty(*self) } + fn is_empty(&const self) -> bool { is_empty(*self) } /// Returns the length of a vector #[inline] - pure fn len(&const self) -> uint { len(*self) } + fn len(&const self) -> uint { len(*self) } } pub trait CopyableVector { - pure fn slice(&self, start: uint, end: uint) -> ~[T]; + fn to_owned(&self) -> ~[T]; } /// Extension methods for vectors impl CopyableVector for &'self [const T] { - /// Returns a copy of the elements from [`start`..`end`) from `v`. + /// Returns a copy of `v`. #[inline] - pure fn slice(&self, start: uint, end: uint) -> ~[T] { - // XXX: Purity workaround for stage0. + fn to_owned(&self) -> ~[T] { + let mut result = ~[]; + // FIXME: #4568 unsafe { - let mut result = ~[]; - for uint::range(start, end) |i| { - result.push(copy self[i]); + reserve(&mut result, self.len()); + for self.each |e| { + result.push(copy *e); } - result } + result + } } pub trait ImmutableVector { - pure fn view(&self, start: uint, end: uint) -> &'self [T]; - pure fn head(&self) -> &'self T; - pure fn head_opt(&self) -> Option<&'self T>; - pure fn tail(&self) -> &'self [T]; - pure fn tailn(&self, n: uint) -> &'self [T]; - pure fn init(&self) -> &'self [T]; - pure fn initn(&self, n: uint) -> &'self [T]; - pure fn last(&self) -> &'self T; - pure fn last_opt(&self) -> Option<&'self T>; - pure fn foldr(&self, z: U, p: &fn(t: &T, u: U) -> U) -> U; - pure fn map(&self, f: &fn(t: &T) -> U) -> ~[U]; - pure fn mapi(&self, f: &fn(uint, t: &T) -> U) -> ~[U]; + fn slice(&self, start: uint, end: uint) -> &'self [T]; + fn head(&self) -> &'self T; + fn head_opt(&self) -> Option<&'self T>; + fn tail(&self) -> &'self [T]; + fn tailn(&self, n: uint) -> &'self [T]; + fn init(&self) -> &'self [T]; + fn initn(&self, n: uint) -> &'self [T]; + fn last(&self) -> &'self T; + fn last_opt(&self) -> Option<&'self T>; + fn each_reverse(&self, blk: &fn(&T) -> bool); + fn eachi_reverse(&self, blk: &fn(uint, &T) -> bool); + fn foldr(&self, z: U, p: &fn(t: &T, u: U) -> U) -> U; + fn map(&self, f: &fn(t: &T) -> U) -> ~[U]; + fn mapi(&self, f: &fn(uint, t: &T) -> U) -> ~[U]; fn map_r(&self, f: &fn(x: &T) -> U) -> ~[U]; - pure fn alli(&self, f: &fn(uint, t: &T) -> bool) -> bool; - pure fn flat_map(&self, f: &fn(t: &T) -> ~[U]) -> ~[U]; - pure fn filter_mapped(&self, f: &fn(t: &T) -> Option) -> ~[U]; + fn alli(&self, f: &fn(uint, t: &T) -> bool) -> bool; + fn flat_map(&self, f: &fn(t: &T) -> ~[U]) -> ~[U]; + fn filter_mapped(&self, f: &fn(t: &T) -> Option) -> ~[U]; } /// Extension methods for vectors impl ImmutableVector for &'self [T] { /// Return a slice that points into another slice. #[inline] - pure fn view(&self, start: uint, end: uint) -> &'self [T] { + fn slice(&self, start: uint, end: uint) -> &'self [T] { slice(*self, start, end) } /// Returns the first element of a vector, failing if the vector is empty. #[inline] - pure fn head(&self) -> &'self T { head(*self) } + fn head(&self) -> &'self T { head(*self) } /// Returns the first element of a vector #[inline] - pure fn head_opt(&self) -> Option<&'self T> { head_opt(*self) } + fn head_opt(&self) -> Option<&'self T> { head_opt(*self) } /// Returns all but the first element of a vector #[inline] - pure fn tail(&self) -> &'self [T] { tail(*self) } + fn tail(&self) -> &'self [T] { tail(*self) } /// Returns all but the first `n' elements of a vector #[inline] - pure fn tailn(&self, n: uint) -> &'self [T] { tailn(*self, n) } + fn tailn(&self, n: uint) -> &'self [T] { tailn(*self, n) } /// Returns all but the last elemnt of a vector #[inline] - pure fn init(&self) -> &'self [T] { init(*self) } + fn init(&self) -> &'self [T] { init(*self) } /// Returns all but the last `n' elemnts of a vector #[inline] - pure fn initn(&self, n: uint) -> &'self [T] { initn(*self, n) } + fn initn(&self, n: uint) -> &'self [T] { initn(*self, n) } /// Returns the last element of a `v`, failing if the vector is empty. #[inline] - pure fn last(&self) -> &'self T { last(*self) } + fn last(&self) -> &'self T { last(*self) } /// Returns the last element of a `v`, failing if the vector is empty. #[inline] - pure fn last_opt(&self) -> Option<&'self T> { last_opt(*self) } + fn last_opt(&self) -> Option<&'self T> { last_opt(*self) } + + /// Iterates over a vector's elements in reverse. + #[inline] + fn each_reverse(&self, blk: &fn(&T) -> bool) { + each_reverse(*self, blk) + } + + /// Iterates over a vector's elements and indices in reverse. + #[inline] + fn eachi_reverse(&self, blk: &fn(uint, &T) -> bool) { + eachi_reverse(*self, blk) + } /// Reduce a vector from right to left #[inline] - pure fn foldr(&self, z: U, p: &fn(t: &T, u: U) -> U) -> U { + fn foldr(&self, 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(&self, f: &fn(t: &T) -> U) -> ~[U] { map(*self, f) } + fn map(&self, 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(&self, f: &fn(uint, t: &T) -> U) -> ~[U] { + fn mapi(&self, f: &fn(uint, t: &T) -> U) -> ~[U] { mapi(*self, f) } @@ -1819,7 +1832,7 @@ impl ImmutableVector for &'self [T] { * * If the vector is empty, true is returned. */ - pure fn alli(&self, f: &fn(uint, t: &T) -> bool) -> bool { + fn alli(&self, f: &fn(uint, t: &T) -> bool) -> bool { alli(*self, f) } /** @@ -1827,7 +1840,7 @@ impl ImmutableVector for &'self [T] { * of each result vector */ #[inline] - pure fn flat_map(&self, f: &fn(t: &T) -> ~[U]) -> ~[U] { + fn flat_map(&self, f: &fn(t: &T) -> ~[U]) -> ~[U] { flat_map(*self, f) } /** @@ -1837,16 +1850,16 @@ impl ImmutableVector for &'self [T] { * the resulting vector. */ #[inline] - pure fn filter_mapped(&self, f: &fn(t: &T) -> Option) -> ~[U] { + fn filter_mapped(&self, f: &fn(t: &T) -> Option) -> ~[U] { filter_mapped(*self, f) } } pub trait ImmutableEqVector { - pure fn position(&self, f: &fn(t: &T) -> bool) -> Option; - pure fn position_elem(&self, t: &T) -> Option; - pure fn rposition(&self, f: &fn(t: &T) -> bool) -> Option; - pure fn rposition_elem(&self, t: &T) -> Option; + fn position(&self, f: &fn(t: &T) -> bool) -> Option; + fn position_elem(&self, t: &T) -> Option; + fn rposition(&self, f: &fn(t: &T) -> bool) -> Option; + fn rposition_elem(&self, t: &T) -> Option; } impl ImmutableEqVector for &'self [T] { @@ -1858,13 +1871,13 @@ impl ImmutableEqVector for &'self [T] { * elements then none is returned. */ #[inline] - pure fn position(&self, f: &fn(t: &T) -> bool) -> Option { + fn position(&self, f: &fn(t: &T) -> bool) -> Option { position(*self, f) } /// Find the first index containing a matching value #[inline] - pure fn position_elem(&self, x: &T) -> Option { + fn position_elem(&self, x: &T) -> Option { position_elem(*self, x) } @@ -1876,21 +1889,21 @@ impl ImmutableEqVector for &'self [T] { * returned. If `f` matches no elements then none is returned. */ #[inline] - pure fn rposition(&self, f: &fn(t: &T) -> bool) -> Option { + fn rposition(&self, f: &fn(t: &T) -> bool) -> Option { rposition(*self, f) } /// Find the last index containing a matching value #[inline] - pure fn rposition_elem(&self, t: &T) -> Option { + fn rposition_elem(&self, t: &T) -> Option { rposition_elem(*self, t) } } pub trait ImmutableCopyableVector { - pure fn filtered(&self, f: &fn(&T) -> bool) -> ~[T]; - pure fn rfind(&self, f: &fn(t: &T) -> bool) -> Option; - pure fn partitioned(&self, f: &fn(&T) -> bool) -> (~[T], ~[T]); + fn filtered(&self, f: &fn(&T) -> bool) -> ~[T]; + fn rfind(&self, f: &fn(t: &T) -> bool) -> Option; + fn partitioned(&self, f: &fn(&T) -> bool) -> (~[T], ~[T]); } /// Extension methods for vectors @@ -1903,7 +1916,7 @@ impl ImmutableCopyableVector for &'self [T] { * containing only those elements for which `f` returned true. */ #[inline] - pure fn filtered(&self, f: &fn(t: &T) -> bool) -> ~[T] { + fn filtered(&self, f: &fn(t: &T) -> bool) -> ~[T] { filtered(*self, f) } @@ -1915,7 +1928,7 @@ impl ImmutableCopyableVector for &'self [T] { * returned. If `f` matches no elements then none is returned. */ #[inline] - pure fn rfind(&self, f: &fn(t: &T) -> bool) -> Option { + fn rfind(&self, f: &fn(t: &T) -> bool) -> Option { rfind(*self, f) } @@ -1924,7 +1937,7 @@ impl ImmutableCopyableVector for &'self [T] { * those that do not. */ #[inline] - pure fn partitioned(&self, f: &fn(&T) -> bool) -> (~[T], ~[T]) { + fn partitioned(&self, f: &fn(&T) -> bool) -> (~[T], ~[T]) { partitioned(*self, f) } } @@ -1939,10 +1952,10 @@ pub trait OwnedVector { fn remove(&mut self, i: uint) -> T; fn swap_remove(&mut self, index: uint) -> T; fn truncate(&mut self, newlen: uint); - fn retain(&mut self, f: &pure fn(t: &T) -> bool); + fn retain(&mut self, f: &fn(t: &T) -> bool); fn consume(self, f: &fn(uint, v: T)); fn filter(self, f: &fn(t: &T) -> bool) -> ~[T]; - fn partition(self, f: &pure fn(&T) -> bool) -> (~[T], ~[T]); + fn partition(self, f: &fn(&T) -> bool) -> (~[T], ~[T]); fn grow_fn(&mut self, n: uint, op: iter::InitOp); } @@ -1993,7 +2006,7 @@ impl OwnedVector for ~[T] { } #[inline] - fn retain(&mut self, f: &pure fn(t: &T) -> bool) { + fn retain(&mut self, f: &fn(t: &T) -> bool) { retain(self, f); } @@ -2242,7 +2255,7 @@ pub mod bytes { use vec; /// Bytewise string comparison - pub pure fn memcmp(a: &~[u8], b: &~[u8]) -> int { + pub fn memcmp(a: &~[u8], b: &~[u8]) -> int { let a_len = a.len(); let b_len = b.len(); let n = uint::min(a_len, b_len) as libc::size_t; @@ -2263,22 +2276,22 @@ pub mod bytes { } /// Bytewise less than or equal - pub pure fn lt(a: &~[u8], b: &~[u8]) -> bool { memcmp(a, b) < 0 } + pub fn lt(a: &~[u8], b: &~[u8]) -> bool { memcmp(a, b) < 0 } /// Bytewise less than or equal - pub pure fn le(a: &~[u8], b: &~[u8]) -> bool { memcmp(a, b) <= 0 } + pub fn le(a: &~[u8], b: &~[u8]) -> bool { memcmp(a, b) <= 0 } /// Bytewise equality - pub pure fn eq(a: &~[u8], b: &~[u8]) -> bool { memcmp(a, b) == 0 } + pub fn eq(a: &~[u8], b: &~[u8]) -> bool { memcmp(a, b) == 0 } /// Bytewise inequality - pub pure fn ne(a: &~[u8], b: &~[u8]) -> bool { memcmp(a, b) != 0 } + pub fn ne(a: &~[u8], b: &~[u8]) -> bool { memcmp(a, b) != 0 } /// Bytewise greater than or equal - pub pure fn ge(a: &~[u8], b: &~[u8]) -> bool { memcmp(a, b) >= 0 } + pub fn ge(a: &~[u8], b: &~[u8]) -> bool { memcmp(a, b) >= 0 } /// Bytewise greater than - pub pure fn gt(a: &~[u8], b: &~[u8]) -> bool { memcmp(a, b) > 0 } + pub fn gt(a: &~[u8], b: &~[u8]) -> bool { memcmp(a, b) > 0 } /** * Copies data from one vector to another. @@ -2298,25 +2311,25 @@ pub mod bytes { impl iter::BaseIter for &'self [A] { #[inline(always)] - pure fn each(&self, blk: &fn(v: &'self A) -> bool) { each(*self, blk) } + fn each(&self, blk: &fn(v: &'self A) -> bool) { each(*self, blk) } #[inline(always)] - pure fn size_hint(&self) -> Option { Some(self.len()) } + fn size_hint(&self) -> Option { Some(self.len()) } } // FIXME(#4148): This should be redundant impl iter::BaseIter for ~[A] { #[inline(always)] - pure fn each(&self, blk: &fn(v: &'self A) -> bool) { each(*self, blk) } + fn each(&self, blk: &fn(v: &'self A) -> bool) { each(*self, blk) } #[inline(always)] - pure fn size_hint(&self) -> Option { Some(self.len()) } + fn size_hint(&self) -> Option { Some(self.len()) } } // FIXME(#4148): This should be redundant impl iter::BaseIter for @[A] { #[inline(always)] - pure fn each(&self, blk: &fn(v: &'self A) -> bool) { each(*self, blk) } + fn each(&self, blk: &fn(v: &'self A) -> bool) { each(*self, blk) } #[inline(always)] - pure fn size_hint(&self) -> Option { Some(self.len()) } + fn size_hint(&self) -> Option { Some(self.len()) } } impl iter::MutableIter for &'self mut [A] { @@ -2343,25 +2356,25 @@ impl iter::MutableIter for @mut [A] { } impl iter::ExtendedIter for &'self [A] { - pub pure fn eachi(&self, blk: &fn(uint, v: &A) -> bool) { + pub fn eachi(&self, blk: &fn(uint, v: &A) -> bool) { iter::eachi(self, blk) } - pub pure fn all(&self, blk: &fn(&A) -> bool) -> bool { + pub fn all(&self, blk: &fn(&A) -> bool) -> bool { iter::all(self, blk) } - pub pure fn any(&self, blk: &fn(&A) -> bool) -> bool { + pub fn any(&self, blk: &fn(&A) -> bool) -> bool { iter::any(self, blk) } - pub pure fn foldl(&self, b0: B, blk: &fn(&B, &A) -> B) -> B { + pub fn foldl(&self, b0: B, blk: &fn(&B, &A) -> B) -> B { iter::foldl(self, b0, blk) } - pub pure fn position(&self, f: &fn(&A) -> bool) -> Option { + pub fn position(&self, f: &fn(&A) -> bool) -> Option { iter::position(self, f) } - pure fn map_to_vec(&self, op: &fn(&A) -> B) -> ~[B] { + fn map_to_vec(&self, op: &fn(&A) -> B) -> ~[B] { iter::map_to_vec(self, op) } - pure fn flat_map_to_vec>(&self, op: &fn(&A) -> IB) + fn flat_map_to_vec>(&self, op: &fn(&A) -> IB) -> ~[B] { iter::flat_map_to_vec(self, op) } @@ -2369,25 +2382,25 @@ impl iter::ExtendedIter for &'self [A] { // FIXME(#4148): This should be redundant impl iter::ExtendedIter for ~[A] { - pub pure fn eachi(&self, blk: &fn(uint, v: &A) -> bool) { + pub fn eachi(&self, blk: &fn(uint, v: &A) -> bool) { iter::eachi(self, blk) } - pub pure fn all(&self, blk: &fn(&A) -> bool) -> bool { + pub fn all(&self, blk: &fn(&A) -> bool) -> bool { iter::all(self, blk) } - pub pure fn any(&self, blk: &fn(&A) -> bool) -> bool { + pub fn any(&self, blk: &fn(&A) -> bool) -> bool { iter::any(self, blk) } - pub pure fn foldl(&self, b0: B, blk: &fn(&B, &A) -> B) -> B { + pub fn foldl(&self, b0: B, blk: &fn(&B, &A) -> B) -> B { iter::foldl(self, b0, blk) } - pub pure fn position(&self, f: &fn(&A) -> bool) -> Option { + pub fn position(&self, f: &fn(&A) -> bool) -> Option { iter::position(self, f) } - pure fn map_to_vec(&self, op: &fn(&A) -> B) -> ~[B] { + fn map_to_vec(&self, op: &fn(&A) -> B) -> ~[B] { iter::map_to_vec(self, op) } - pure fn flat_map_to_vec>(&self, op: &fn(&A) -> IB) + fn flat_map_to_vec>(&self, op: &fn(&A) -> IB) -> ~[B] { iter::flat_map_to_vec(self, op) } @@ -2395,98 +2408,98 @@ impl iter::ExtendedIter for ~[A] { // FIXME(#4148): This should be redundant impl iter::ExtendedIter for @[A] { - pub pure fn eachi(&self, blk: &fn(uint, v: &A) -> bool) { + pub fn eachi(&self, blk: &fn(uint, v: &A) -> bool) { iter::eachi(self, blk) } - pub pure fn all(&self, blk: &fn(&A) -> bool) -> bool { + pub fn all(&self, blk: &fn(&A) -> bool) -> bool { iter::all(self, blk) } - pub pure fn any(&self, blk: &fn(&A) -> bool) -> bool { + pub fn any(&self, blk: &fn(&A) -> bool) -> bool { iter::any(self, blk) } - pub pure fn foldl(&self, b0: B, blk: &fn(&B, &A) -> B) -> B { + pub fn foldl(&self, b0: B, blk: &fn(&B, &A) -> B) -> B { iter::foldl(self, b0, blk) } - pub pure fn position(&self, f: &fn(&A) -> bool) -> Option { + pub fn position(&self, f: &fn(&A) -> bool) -> Option { iter::position(self, f) } - pure fn map_to_vec(&self, op: &fn(&A) -> B) -> ~[B] { + fn map_to_vec(&self, op: &fn(&A) -> B) -> ~[B] { iter::map_to_vec(self, op) } - pure fn flat_map_to_vec>(&self, op: &fn(&A) -> IB) + fn flat_map_to_vec>(&self, op: &fn(&A) -> IB) -> ~[B] { iter::flat_map_to_vec(self, op) } } impl iter::EqIter for &'self [A] { - pub pure fn contains(&self, x: &A) -> bool { iter::contains(self, x) } - pub pure fn count(&self, x: &A) -> uint { iter::count(self, x) } + pub fn contains(&self, x: &A) -> bool { iter::contains(self, x) } + pub fn count(&self, x: &A) -> uint { iter::count(self, x) } } // FIXME(#4148): This should be redundant impl iter::EqIter for ~[A] { - pub pure fn contains(&self, x: &A) -> bool { iter::contains(self, x) } - pub pure fn count(&self, x: &A) -> uint { iter::count(self, x) } + pub fn contains(&self, x: &A) -> bool { iter::contains(self, x) } + pub fn count(&self, x: &A) -> uint { iter::count(self, x) } } // FIXME(#4148): This should be redundant impl iter::EqIter for @[A] { - pub pure fn contains(&self, x: &A) -> bool { iter::contains(self, x) } - pub pure fn count(&self, x: &A) -> uint { iter::count(self, x) } + pub fn contains(&self, x: &A) -> bool { iter::contains(self, x) } + pub fn count(&self, x: &A) -> uint { iter::count(self, x) } } impl iter::CopyableIter for &'self [A] { - pure fn filter_to_vec(&self, pred: &fn(&A) -> bool) -> ~[A] { + fn filter_to_vec(&self, pred: &fn(&A) -> bool) -> ~[A] { iter::filter_to_vec(self, pred) } - pure fn to_vec(&self) -> ~[A] { iter::to_vec(self) } - pub pure fn find(&self, f: &fn(&A) -> bool) -> Option { + fn to_vec(&self) -> ~[A] { iter::to_vec(self) } + pub fn find(&self, f: &fn(&A) -> bool) -> Option { iter::find(self, f) } } // FIXME(#4148): This should be redundant impl iter::CopyableIter for ~[A] { - pure fn filter_to_vec(&self, pred: &fn(&A) -> bool) -> ~[A] { + fn filter_to_vec(&self, pred: &fn(&A) -> bool) -> ~[A] { iter::filter_to_vec(self, pred) } - pure fn to_vec(&self) -> ~[A] { iter::to_vec(self) } - pub pure fn find(&self, f: &fn(&A) -> bool) -> Option { + fn to_vec(&self) -> ~[A] { iter::to_vec(self) } + pub fn find(&self, f: &fn(&A) -> bool) -> Option { iter::find(self, f) } } // FIXME(#4148): This should be redundant impl iter::CopyableIter for @[A] { - pure fn filter_to_vec(&self, pred: &fn(&A) -> bool) -> ~[A] { + fn filter_to_vec(&self, pred: &fn(&A) -> bool) -> ~[A] { iter::filter_to_vec(self, pred) } - pure fn to_vec(&self) -> ~[A] { iter::to_vec(self) } - pub pure fn find(&self, f: &fn(&A) -> bool) -> Option { + fn to_vec(&self) -> ~[A] { iter::to_vec(self) } + pub fn find(&self, f: &fn(&A) -> bool) -> Option { iter::find(self, f) } } impl iter::CopyableOrderedIter for &'self [A] { - pure fn min(&self) -> A { iter::min(self) } - pure fn max(&self) -> A { iter::max(self) } + fn min(&self) -> A { iter::min(self) } + fn max(&self) -> A { iter::max(self) } } // FIXME(#4148): This should be redundant impl iter::CopyableOrderedIter for ~[A] { - pure fn min(&self) -> A { iter::min(self) } - pure fn max(&self) -> A { iter::max(self) } + fn min(&self) -> A { iter::min(self) } + fn max(&self) -> A { iter::max(self) } } // FIXME(#4148): This should be redundant impl iter::CopyableOrderedIter for @[A] { - pure fn min(&self) -> A { iter::min(self) } - pure fn max(&self) -> A { iter::max(self) } + fn min(&self) -> A { iter::min(self) } + fn max(&self) -> A { iter::max(self) } } impl iter::CopyableNonstrictIter for &'self [A] { - pure fn each_val(&const self, f: &fn(A) -> bool) { + fn each_val(&const self, f: &fn(A) -> bool) { let mut i = 0; while i < self.len() { if !f(copy self[i]) { break; } @@ -2497,7 +2510,7 @@ impl iter::CopyableNonstrictIter for &'self [A] { // FIXME(#4148): This should be redundant impl iter::CopyableNonstrictIter for ~[A] { - pure fn each_val(&const self, f: &fn(A) -> bool) { + fn each_val(&const self, f: &fn(A) -> bool) { let mut i = 0; while i < uniq_len(self) { if !f(copy self[i]) { break; } @@ -2508,7 +2521,7 @@ impl iter::CopyableNonstrictIter for ~[A] { // FIXME(#4148): This should be redundant impl iter::CopyableNonstrictIter for @[A] { - pure fn each_val(&const self, f: &fn(A) -> bool) { + fn each_val(&const self, f: &fn(A) -> bool) { let mut i = 0; while i < self.len() { if !f(copy self[i]) { break; } @@ -2520,12 +2533,7 @@ impl iter::CopyableNonstrictIter for @[A] { impl Clone for ~[A] { #[inline] fn clone(&self) -> ~[A] { - let mut dolly = ~[]; - vec::reserve(&mut dolly, self.len()); - for self.each |item| { - dolly.push(item.clone()); - } - return dolly; + self.map(|item| item.clone()) } } @@ -2534,7 +2542,6 @@ impl Clone for ~[A] { #[cfg(test)] mod tests { use option::{None, Option, Some}; - use option; use sys; use vec::*; use cmp::*; @@ -2543,11 +2550,11 @@ mod tests { fn square_ref(n: &uint) -> uint { square(*n) } - pure fn is_three(n: &uint) -> bool { *n == 3u } + fn is_three(n: &uint) -> bool { *n == 3u } - pure fn is_odd(n: &uint) -> bool { *n % 2u == 1u } + fn is_odd(n: &uint) -> bool { *n % 2u == 1u } - pure fn is_equal(x: &uint, y:&uint) -> bool { *x == *y } + fn is_equal(x: &uint, y:&uint) -> bool { *x == *y } fn square_if_odd_r(n: &uint) -> Option { if *n % 2u == 1u { Some(*n * *n) } else { None } @@ -3131,16 +3138,17 @@ mod tests { } #[test] - fn test_reach_empty() { - for rev_each::(~[]) |_v| { + fn test_each_reverse_empty() { + let v: ~[int] = ~[]; + for v.each_reverse |_v| { fail!(); // should never execute } } #[test] - fn test_reach_nonempty() { + fn test_each_reverse_nonempty() { let mut i = 0; - for rev_each(~[1, 2, 3]) |v| { + for each_reverse(~[1, 2, 3]) |v| { if i == 0 { fail_unless!(*v == 3); } i += *v } @@ -3148,9 +3156,9 @@ mod tests { } #[test] - fn test_reachi() { + fn test_eachi_reverse() { let mut i = 0; - for rev_eachi(~[0, 1, 2]) |j, v| { + for eachi_reverse(~[0, 1, 2]) |j, v| { if i == 0 { fail_unless!(*v == 2); } fail_unless!(j == *v as uint); i += *v; @@ -3158,6 +3166,14 @@ mod tests { fail_unless!(i == 3); } + #[test] + fn test_eachi_reverse_empty() { + let v: ~[int] = ~[]; + for v.eachi_reverse |_i, _v| { + fail!(); // should never execute + } + } + #[test] fn test_each_permutation() { let mut results: ~[~[int]]; @@ -3590,9 +3606,9 @@ mod tests { } #[test] - fn test_view() { + fn test_slice_2() { let v = ~[1, 2, 3, 4, 5]; - let v = v.view(1u, 3u); + let v = v.slice(1u, 3u); fail_unless!(v.len() == 2u); fail_unless!(v[0] == 2); fail_unless!(v[1] == 3); diff --git a/src/libfuzzer/ast_match.rs b/src/libfuzzer/ast_match.rs index 81048a69ca91d..eedd3bebedfc4 100644 --- a/src/libfuzzer/ast_match.rs +++ b/src/libfuzzer/ast_match.rs @@ -25,8 +25,8 @@ fn vec_equal(v: ~[T], return true; } -pure fn builtin_equal(&&a: T, &&b: T) -> bool { return a == b; } -pure fn builtin_equal_int(&&a: int, &&b: int) -> bool { return a == b; } +fn builtin_equal(&&a: T, &&b: T) -> bool { return a == b; } +fn builtin_equal_int(&&a: int, &&b: int) -> bool { return a == b; } fn main() { fail_unless!((builtin_equal(5, 5))); diff --git a/src/libfuzzer/cycles.rs b/src/libfuzzer/cycles.rs index 7ea74b369404c..dcf9a493c558a 100644 --- a/src/libfuzzer/cycles.rs +++ b/src/libfuzzer/cycles.rs @@ -26,8 +26,8 @@ fn choice(r : rand::rng, v : ~[const T]) -> T { fn likelihood(r : rand::rng, k : uint, n : uint) -> bool { under(r, n) < k } -const iters : uint = 1000u; -const vlen : uint = 100u; +static iters : uint = 1000u; +static vlen : uint = 100u; enum maybe_pointy { none, diff --git a/src/libfuzzer/fuzzer.rc b/src/libfuzzer/fuzzer.rc index ce554f3473163..3580edb581462 100644 --- a/src/libfuzzer/fuzzer.rc +++ b/src/libfuzzer/fuzzer.rc @@ -25,7 +25,6 @@ #[allow(non_camel_case_types)]; #[allow(deprecated_mode)]; #[allow(deprecated_pattern)]; -#[deny(deprecated_self)]; extern mod core(vers = "0.6"); extern mod std(vers = "0.6"); @@ -39,7 +38,7 @@ use syntax::parse; use syntax::print::pprust; use syntax::diagnostic; -#[deriving_eq] +#[deriving(Eq)] pub enum test_mode { tm_converge, tm_run, } pub struct Context { mode: test_mode } // + rng @@ -95,11 +94,11 @@ pub fn common_exprs() -> ~[ast::expr] { ] } -pub pure fn safe_to_steal_expr(e: @ast::expr, tm: test_mode) -> bool { +pub fn safe_to_steal_expr(e: @ast::expr, tm: test_mode) -> bool { safe_to_use_expr(*e, tm) } -pub pure fn safe_to_use_expr(e: ast::expr, tm: test_mode) -> bool { +pub fn safe_to_use_expr(e: ast::expr, tm: test_mode) -> bool { match tm { tm_converge => { match e.node { @@ -336,7 +335,7 @@ pub fn check_variants_T( pub fn last_part(filename: ~str) -> ~str { let ix = option::get(str::rfind_char(filename, '/')); - str::slice(filename, ix + 1u, str::len(filename) - 3u) + str::slice(filename, ix + 1u, str::len(filename) - 3u).to_owned() } pub enum happiness { diff --git a/src/librust/rust.rc b/src/librust/rust.rc index 3ca4ef5efbd95..e590586abbb39 100644 --- a/src/librust/rust.rc +++ b/src/librust/rust.rc @@ -12,8 +12,6 @@ // FIXME #2238 Make commands run and test emit proper file endings on winds // FIXME #2238 Make run only accept source that emits an executable -#[deny(deprecated_self)]; - #[link(name = "rust", vers = "0.6", uuid = "4a24da33-5cc8-4037-9352-2cbe9bd9d27c", @@ -47,14 +45,14 @@ enum UsageSource { UsgStr(&'self str) } -struct Command { +struct Command<'self> { cmd: &'self str, - action: Action/&self, + action: Action<'self>, usage_line: &'self str, - usage_full: UsageSource/&self + usage_full: UsageSource<'self>, } -const commands: &'static [Command/&static] = &[ +static commands: &'static [Command<'static>] = &[ Command{ cmd: "build", action: Exec("rustc"), @@ -199,7 +197,7 @@ fn do_command(command: &Command, args: &[~str]) -> ValidUsage { } fn usage() { - const indent: uint = 8; + static indent: uint = 8; io::print( "The rust tool is a convenience for managing rust source code.\n\ diff --git a/src/librustc/back/abi.rs b/src/librustc/back/abi.rs index 06625c1ddd965..70a029ede6f8d 100644 --- a/src/librustc/back/abi.rs +++ b/src/librustc/back/abi.rs @@ -11,64 +11,64 @@ -pub const rc_base_field_refcnt: uint = 0u; +pub static rc_base_field_refcnt: uint = 0u; -pub const task_field_refcnt: uint = 0u; +pub static task_field_refcnt: uint = 0u; -pub const task_field_stk: uint = 2u; +pub static task_field_stk: uint = 2u; -pub const task_field_runtime_sp: uint = 3u; +pub static task_field_runtime_sp: uint = 3u; -pub const task_field_rust_sp: uint = 4u; +pub static task_field_rust_sp: uint = 4u; -pub const task_field_gc_alloc_chain: uint = 5u; +pub static task_field_gc_alloc_chain: uint = 5u; -pub const task_field_dom: uint = 6u; +pub static task_field_dom: uint = 6u; -pub const n_visible_task_fields: uint = 7u; +pub static n_visible_task_fields: uint = 7u; -pub const dom_field_interrupt_flag: uint = 1u; +pub static dom_field_interrupt_flag: uint = 1u; -pub const frame_glue_fns_field_mark: uint = 0u; +pub static frame_glue_fns_field_mark: uint = 0u; -pub const frame_glue_fns_field_drop: uint = 1u; +pub static frame_glue_fns_field_drop: uint = 1u; -pub const frame_glue_fns_field_reloc: uint = 2u; +pub static frame_glue_fns_field_reloc: uint = 2u; -pub const box_field_refcnt: uint = 0u; -pub const box_field_tydesc: uint = 1u; -pub const box_field_prev: uint = 2u; -pub const box_field_next: uint = 3u; -pub const box_field_body: uint = 4u; +pub static box_field_refcnt: uint = 0u; +pub static box_field_tydesc: uint = 1u; +pub static box_field_prev: uint = 2u; +pub static box_field_next: uint = 3u; +pub static box_field_body: uint = 4u; -pub const general_code_alignment: uint = 16u; +pub static general_code_alignment: uint = 16u; -pub const tydesc_field_size: uint = 0u; -pub const tydesc_field_align: uint = 1u; -pub const tydesc_field_take_glue: uint = 2u; -pub const tydesc_field_drop_glue: uint = 3u; -pub const tydesc_field_free_glue: uint = 4u; -pub const tydesc_field_visit_glue: uint = 5u; -pub const tydesc_field_shape: uint = 6u; -pub const tydesc_field_shape_tables: uint = 7u; -pub const n_tydesc_fields: uint = 8u; +pub static tydesc_field_size: uint = 0u; +pub static tydesc_field_align: uint = 1u; +pub static tydesc_field_take_glue: uint = 2u; +pub static tydesc_field_drop_glue: uint = 3u; +pub static tydesc_field_free_glue: uint = 4u; +pub static tydesc_field_visit_glue: uint = 5u; +pub static tydesc_field_shape: uint = 6u; +pub static tydesc_field_shape_tables: uint = 7u; +pub static n_tydesc_fields: uint = 8u; // The two halves of a closure: code and environment. -pub const fn_field_code: uint = 0u; -pub const fn_field_box: uint = 1u; +pub static fn_field_code: uint = 0u; +pub static fn_field_box: uint = 1u; -pub const vec_elt_fill: uint = 0u; +pub static vec_elt_fill: uint = 0u; -pub const vec_elt_alloc: uint = 1u; +pub static vec_elt_alloc: uint = 1u; -pub const vec_elt_elems: uint = 2u; +pub static vec_elt_elems: uint = 2u; -pub const slice_elt_base: uint = 0u; -pub const slice_elt_len: uint = 1u; +pub static slice_elt_base: uint = 0u; +pub static slice_elt_len: uint = 1u; -pub const worst_case_glue_call_args: uint = 7u; +pub static worst_case_glue_call_args: uint = 7u; -pub const abi_version: uint = 1u; +pub static abi_version: uint = 1u; pub fn memcpy_glue_name() -> ~str { return ~"rust_memcpy_glue"; } diff --git a/src/librustc/back/link.rs b/src/librustc/back/link.rs index 9965a4a6fcdd6..5f9a3e606f201 100644 --- a/src/librustc/back/link.rs +++ b/src/librustc/back/link.rs @@ -38,7 +38,7 @@ use syntax::ast_map::{path, path_mod, path_name}; use syntax::attr; use syntax::print::pprust; -#[deriving_eq] +#[deriving(Eq)] pub enum output_type { output_type_none, output_type_bitcode, @@ -656,7 +656,7 @@ pub fn get_symbol_hash(ccx: @CrateContext, t: ty::t) -> @str { // gas doesn't! pub fn sanitize(s: &str) -> ~str { let mut result = ~""; - for str::chars_each(s) |c| { + for str::each_char(s) |c| { match c { '@' => result += ~"_sbox_", '~' => result += ~"_ubox_", @@ -771,7 +771,7 @@ pub fn link_binary(sess: Session, fn unlib(config: @session::config, +stem: ~str) -> ~str { if stem.starts_with("lib") && config.os != session::os_win32 { - stem.slice(3, stem.len()) + stem.slice(3, stem.len()).to_owned() } else { stem } @@ -849,11 +849,7 @@ pub fn link_binary(sess: Session, do cstore::iter_crate_data(cstore) |crate_num, _| { let link_args = csearch::get_link_args_for_crate(cstore, crate_num); do vec::consume(link_args) |_, link_arg| { - // Linker arguments that don't begin with - are likely file names, - // so they should not be necessary. - if link_arg.starts_with("-") { - cc_args.push(link_arg); - } + cc_args.push(link_arg); } } diff --git a/src/librustc/back/rpath.rs b/src/librustc/back/rpath.rs index 1911764da3c38..1137b2a2c08a0 100644 --- a/src/librustc/back/rpath.rs +++ b/src/librustc/back/rpath.rs @@ -20,7 +20,7 @@ use core::util; use core::vec; use core::hashmap::linear::LinearSet; -pure fn not_win32(os: session::os) -> bool { +fn not_win32(os: session::os) -> bool { match os { session::os_win32 => false, _ => true diff --git a/src/librustc/driver/driver.rs b/src/librustc/driver/driver.rs index dfac6a0162f2e..360a5ddccfd2a 100644 --- a/src/librustc/driver/driver.rs +++ b/src/librustc/driver/driver.rs @@ -21,10 +21,10 @@ use metadata::{creader, cstore, filesearch}; use metadata; use middle::{trans, freevars, kind, ty, typeck, lint, astencode}; use middle; +use util::common::time; use util::ppaux; use core::int; -use core::io::WriterUtil; use core::io; use core::os; use core::str; @@ -32,7 +32,6 @@ use core::vec; use std::getopts::groups::{optopt, optmulti, optflag, optflagopt, getopts}; use std::getopts::{opt_present}; use std::getopts; -use std; use syntax::ast; use syntax::attr; use syntax::codemap; @@ -161,17 +160,7 @@ pub fn parse_input(sess: Session, +cfg: ast::crate_cfg, input: input) } } -pub fn time(do_it: bool, what: ~str, thunk: &fn() -> T) -> T { - if !do_it { return thunk(); } - let start = std::time::precise_time_s(); - let rv = thunk(); - let end = std::time::precise_time_s(); - io::stdout().write_str(fmt!("time: %3.3f s\t%s\n", - end - start, what)); - rv -} - -#[deriving_eq] +#[deriving(Eq)] pub enum compile_upto { cu_parse, cu_expand, @@ -251,11 +240,9 @@ pub fn compile_rest(sess: Session, cfg: ast::crate_cfg, let ty_cx = ty::mk_ctxt(sess, def_map, ast_map, freevars, region_map, rp_set, lang_items, crate); - let (method_map, vtable_map) = - time(time_passes, ~"typechecking", || - typeck::check_crate(ty_cx, - trait_map, - crate)); + // passes are timed inside typeck + let (method_map, vtable_map) = typeck::check_crate( + ty_cx, trait_map, crate); // These next two const passes can probably be merged time(time_passes, ~"const marking", || diff --git a/src/librustc/driver/session.rs b/src/librustc/driver/session.rs index 75400c5e3244c..28ebc3f424ef0 100644 --- a/src/librustc/driver/session.rs +++ b/src/librustc/driver/session.rs @@ -27,10 +27,10 @@ use syntax::parse::ParseSess; use syntax::{ast, codemap}; use syntax; -#[deriving_eq] +#[deriving(Eq)] pub enum os { os_win32, os_macos, os_linux, os_android, os_freebsd, } -#[deriving_eq] +#[deriving(Eq)] pub enum arch { arch_x86, arch_x86_64, arch_arm, arch_mips, } pub enum crate_type { bin_crate, lib_crate, unknown_crate, } @@ -44,29 +44,29 @@ pub struct config { float_type: float_ty } -pub const verbose: uint = 1 << 0; -pub const time_passes: uint = 1 << 1; -pub const count_llvm_insns: uint = 1 << 2; -pub const time_llvm_passes: uint = 1 << 3; -pub const trans_stats: uint = 1 << 4; -pub const no_asm_comments: uint = 1 << 5; -pub const no_verify: uint = 1 << 6; -pub const trace: uint = 1 << 7; -pub const coherence: uint = 1 << 8; -pub const borrowck_stats: uint = 1 << 9; -pub const borrowck_note_pure: uint = 1 << 10; -pub const borrowck_note_loan: uint = 1 << 11; -pub const no_landing_pads: uint = 1 << 12; -pub const debug_llvm: uint = 1 << 13; -pub const count_type_sizes: uint = 1 << 14; -pub const meta_stats: uint = 1 << 15; -pub const no_opt: uint = 1 << 16; -pub const no_monomorphic_collapse: uint = 1 << 17; -pub const gc: uint = 1 << 18; -pub const jit: uint = 1 << 19; -pub const debug_info: uint = 1 << 20; -pub const extra_debug_info: uint = 1 << 21; -pub const static: uint = 1 << 22; +pub static verbose: uint = 1 << 0; +pub static time_passes: uint = 1 << 1; +pub static count_llvm_insns: uint = 1 << 2; +pub static time_llvm_passes: uint = 1 << 3; +pub static trans_stats: uint = 1 << 4; +pub static no_asm_comments: uint = 1 << 5; +pub static no_verify: uint = 1 << 6; +pub static trace: uint = 1 << 7; +pub static coherence: uint = 1 << 8; +pub static borrowck_stats: uint = 1 << 9; +pub static borrowck_note_pure: uint = 1 << 10; +pub static borrowck_note_loan: uint = 1 << 11; +pub static no_landing_pads: uint = 1 << 12; +pub static debug_llvm: uint = 1 << 13; +pub static count_type_sizes: uint = 1 << 14; +pub static meta_stats: uint = 1 << 15; +pub static no_opt: uint = 1 << 16; +pub static no_monomorphic_collapse: uint = 1 << 17; +pub static gc: uint = 1 << 18; +pub static jit: uint = 1 << 19; +pub static debug_info: uint = 1 << 20; +pub static extra_debug_info: uint = 1 << 21; +pub static static: uint = 1 << 22; pub fn debugging_opts_map() -> ~[(~str, ~str, uint)] { ~[(~"verbose", ~"in general, enable more debug printouts", verbose), @@ -104,7 +104,7 @@ pub fn debugging_opts_map() -> ~[(~str, ~str, uint)] { ] } -#[deriving_eq] +#[deriving(Eq)] pub enum OptLevel { No, // -O0 Less, // -O1 diff --git a/src/librustc/front/core_inject.rs b/src/librustc/front/core_inject.rs index 0766dcd245086..6e134d25ff2cf 100644 --- a/src/librustc/front/core_inject.rs +++ b/src/librustc/front/core_inject.rs @@ -19,7 +19,7 @@ use syntax::codemap; use syntax::codemap::dummy_sp; use syntax::fold; -const CORE_VERSION: &'static str = "0.6"; +static CORE_VERSION: &'static str = "0.6"; pub fn maybe_inject_libcore_ref(sess: Session, crate: @ast::crate) -> @ast::crate { diff --git a/src/librustc/front/test.rs b/src/librustc/front/test.rs index 434d992f50197..401005310107d 100644 --- a/src/librustc/front/test.rs +++ b/src/librustc/front/test.rs @@ -257,7 +257,7 @@ mod __test { std::test::test_main_static(::os::args(), tests) } - const tests : &'static [std::test::TestDescAndFn] = &[ + static tests : &'static [std::test::TestDescAndFn] = &[ ... the list of tests in the crate ... ]; } @@ -352,7 +352,6 @@ fn path_node_global(+ids: ~[ast::ident]) -> @ast::path { types: ~[] } } -#[cfg(stage0)] fn mk_tests(cx: &TestCtxt) -> @ast::item { let ext_cx = cx.ext_cx; @@ -361,23 +360,7 @@ fn mk_tests(cx: &TestCtxt) -> @ast::item { let test_descs = mk_test_descs(cx); (quote_item!( - pub const tests : &static/[self::std::test::TestDescAndFn] = - $test_descs - ; - )).get() -} - -#[cfg(stage1)] -#[cfg(stage2)] -fn mk_tests(cx: &TestCtxt) -> @ast::item { - - let ext_cx = cx.ext_cx; - - // The vector of test_descs for this crate - let test_descs = mk_test_descs(cx); - - (quote_item!( - pub const tests : &'static [self::std::test::TestDescAndFn] = + pub static tests : &'static [self::std::test::TestDescAndFn] = $test_descs ; )).get() diff --git a/src/librustc/lib/llvm.rs b/src/librustc/lib/llvm.rs index e5234dff91d13..e01c4ae7d727d 100644 --- a/src/librustc/lib/llvm.rs +++ b/src/librustc/lib/llvm.rs @@ -20,8 +20,8 @@ use std::oldmap::HashMap; pub type Opcode = u32; pub type Bool = c_uint; -pub const True: Bool = 1 as Bool; -pub const False: Bool = 0 as Bool; +pub static True: Bool = 1 as Bool; +pub static False: Bool = 0 as Bool; // Consts for the LLVM CallConv type, pre-cast to uint. @@ -127,7 +127,7 @@ pub enum RealPredicate { // enum for the LLVM TypeKind type - must stay in sync with the def of // LLVMTypeKind in llvm/include/llvm-c/Core.h -#[deriving_eq] +#[deriving(Eq)] pub enum TypeKind { Void = 0, Half = 1, diff --git a/src/librustc/metadata/common.rs b/src/librustc/metadata/common.rs index 38b76c4ace29f..920631a55b4ec 100644 --- a/src/librustc/metadata/common.rs +++ b/src/librustc/metadata/common.rs @@ -11,84 +11,84 @@ // EBML enum definitions and utils shared by the encoder and decoder -pub const tag_items: uint = 0x02u; +pub static tag_items: uint = 0x02u; -pub const tag_paths_data_name: uint = 0x04u; +pub static tag_paths_data_name: uint = 0x04u; -pub const tag_def_id: uint = 0x07u; +pub static tag_def_id: uint = 0x07u; -pub const tag_items_data: uint = 0x08u; +pub static tag_items_data: uint = 0x08u; -pub const tag_items_data_item: uint = 0x09u; +pub static tag_items_data_item: uint = 0x09u; -pub const tag_items_data_item_family: uint = 0x0au; +pub static tag_items_data_item_family: uint = 0x0au; -pub const tag_items_data_item_ty_param_bounds: uint = 0x0bu; +pub static tag_items_data_item_ty_param_bounds: uint = 0x0bu; -pub const tag_items_data_item_type: uint = 0x0cu; +pub static tag_items_data_item_type: uint = 0x0cu; -pub const tag_items_data_item_symbol: uint = 0x0du; +pub static tag_items_data_item_symbol: uint = 0x0du; -pub const tag_items_data_item_variant: uint = 0x0eu; +pub static tag_items_data_item_variant: uint = 0x0eu; -pub const tag_items_data_parent_item: uint = 0x0fu; +pub static tag_items_data_parent_item: uint = 0x0fu; -pub const tag_index: uint = 0x11u; +pub static tag_index: uint = 0x11u; -pub const tag_index_buckets: uint = 0x12u; +pub static tag_index_buckets: uint = 0x12u; -pub const tag_index_buckets_bucket: uint = 0x13u; +pub static tag_index_buckets_bucket: uint = 0x13u; -pub const tag_index_buckets_bucket_elt: uint = 0x14u; +pub static tag_index_buckets_bucket_elt: uint = 0x14u; -pub const tag_index_table: uint = 0x15u; +pub static tag_index_table: uint = 0x15u; -pub const tag_meta_item_name_value: uint = 0x18u; +pub static tag_meta_item_name_value: uint = 0x18u; -pub const tag_meta_item_name: uint = 0x19u; +pub static tag_meta_item_name: uint = 0x19u; -pub const tag_meta_item_value: uint = 0x20u; +pub static tag_meta_item_value: uint = 0x20u; -pub const tag_attributes: uint = 0x21u; +pub static tag_attributes: uint = 0x21u; -pub const tag_attribute: uint = 0x22u; +pub static tag_attribute: uint = 0x22u; -pub const tag_meta_item_word: uint = 0x23u; +pub static tag_meta_item_word: uint = 0x23u; -pub const tag_meta_item_list: uint = 0x24u; +pub static tag_meta_item_list: uint = 0x24u; // The list of crates that this crate depends on -pub const tag_crate_deps: uint = 0x25u; +pub static tag_crate_deps: uint = 0x25u; // A single crate dependency -pub const tag_crate_dep: uint = 0x26u; +pub static tag_crate_dep: uint = 0x26u; -pub const tag_crate_hash: uint = 0x28u; +pub static tag_crate_hash: uint = 0x28u; -pub const tag_parent_item: uint = 0x29u; +pub static tag_parent_item: uint = 0x29u; -pub const tag_crate_dep_name: uint = 0x2au; -pub const tag_crate_dep_hash: uint = 0x2bu; -pub const tag_crate_dep_vers: uint = 0x2cu; +pub static tag_crate_dep_name: uint = 0x2au; +pub static tag_crate_dep_hash: uint = 0x2bu; +pub static tag_crate_dep_vers: uint = 0x2cu; -pub const tag_mod_impl: uint = 0x30u; +pub static tag_mod_impl: uint = 0x30u; -pub const tag_item_trait_method: uint = 0x31u; -pub const tag_impl_trait: uint = 0x32u; +pub static tag_item_trait_method: uint = 0x31u; +pub static tag_impl_trait: uint = 0x32u; // discriminator value for variants -pub const tag_disr_val: uint = 0x34u; +pub static tag_disr_val: uint = 0x34u; // used to encode ast_map::path and ast_map::path_elt -pub const tag_path: uint = 0x40u; -pub const tag_path_len: uint = 0x41u; -pub const tag_path_elt_mod: uint = 0x42u; -pub const tag_path_elt_name: uint = 0x43u; -pub const tag_item_field: uint = 0x44u; -pub const tag_struct_mut: uint = 0x45u; - -pub const tag_region_param: uint = 0x46u; -pub const tag_mod_impl_trait: uint = 0x47u; +pub static tag_path: uint = 0x40u; +pub static tag_path_len: uint = 0x41u; +pub static tag_path_elt_mod: uint = 0x42u; +pub static tag_path_elt_name: uint = 0x43u; +pub static tag_item_field: uint = 0x44u; +pub static tag_struct_mut: uint = 0x45u; + +pub static tag_region_param: uint = 0x46u; +pub static tag_mod_impl_trait: uint = 0x47u; /* trait items contain tag_item_trait_method elements, impl items contain tag_item_impl_method elements, and classes @@ -97,16 +97,16 @@ pub const tag_mod_impl_trait: uint = 0x47u; both, tag_item_trait_method and tag_item_impl_method have to be two different tags. */ -pub const tag_item_impl_method: uint = 0x48u; -pub const tag_item_dtor: uint = 0x49u; -pub const tag_item_trait_method_self_ty: uint = 0x4b; -pub const tag_item_trait_method_self_ty_region: uint = 0x4c; +pub static tag_item_impl_method: uint = 0x48u; +pub static tag_item_dtor: uint = 0x49u; +pub static tag_item_trait_method_self_ty: uint = 0x4b; +pub static tag_item_trait_method_self_ty_region: uint = 0x4c; // Reexports are found within module tags. Each reexport contains def_ids // and names. -pub const tag_items_data_item_reexport: uint = 0x4d; -pub const tag_items_data_item_reexport_def_id: uint = 0x4e; -pub const tag_items_data_item_reexport_name: uint = 0x4f; +pub static tag_items_data_item_reexport: uint = 0x4d; +pub static tag_items_data_item_reexport_def_id: uint = 0x4e; +pub static tag_items_data_item_reexport_name: uint = 0x4f; // used to encode crate_ctxt side tables pub enum astencode_tag { // Reserves 0x50 -- 0x6f @@ -136,9 +136,9 @@ pub enum astencode_tag { // Reserves 0x50 -- 0x6f tag_table_capture_map = 0x64 } -pub const tag_item_trait_method_sort: uint = 0x70; +pub static tag_item_trait_method_sort: uint = 0x70; -pub const tag_item_impl_type_basename: uint = 0x71; +pub static tag_item_impl_type_basename: uint = 0x71; // Language items are a top-level directory (for speed). Hierarchy: // @@ -147,17 +147,17 @@ pub const tag_item_impl_type_basename: uint = 0x71; // - tag_lang_items_item_id: u32 // - tag_lang_items_item_node_id: u32 -pub const tag_lang_items: uint = 0x72; -pub const tag_lang_items_item: uint = 0x73; -pub const tag_lang_items_item_id: uint = 0x74; -pub const tag_lang_items_item_node_id: uint = 0x75; +pub static tag_lang_items: uint = 0x72; +pub static tag_lang_items_item: uint = 0x73; +pub static tag_lang_items_item_id: uint = 0x74; +pub static tag_lang_items_item_node_id: uint = 0x75; -pub const tag_item_unnamed_field: uint = 0x76; -pub const tag_items_data_item_struct_ctor: uint = 0x77; -pub const tag_items_data_item_visibility: uint = 0x78; +pub static tag_item_unnamed_field: uint = 0x76; +pub static tag_items_data_item_struct_ctor: uint = 0x77; +pub static tag_items_data_item_visibility: uint = 0x78; -pub const tag_link_args: uint = 0x79; -pub const tag_link_args_arg: uint = 0x7a; +pub static tag_link_args: uint = 0x79; +pub static tag_link_args_arg: uint = 0x7a; pub struct LinkMeta { name: @str, diff --git a/src/librustc/metadata/csearch.rs b/src/librustc/metadata/csearch.rs index 47ee477210b78..16b896f11d6a4 100644 --- a/src/librustc/metadata/csearch.rs +++ b/src/librustc/metadata/csearch.rs @@ -229,11 +229,11 @@ pub fn struct_dtor(cstore: @mut cstore::CStore, def: ast::def_id) decoder::struct_dtor(cdata, def.node) } -pub fn get_method_visibility(cstore: @mut cstore::CStore, - def_id: ast::def_id) - -> ast::visibility { +pub fn get_item_visibility(cstore: @mut cstore::CStore, + def_id: ast::def_id) + -> ast::visibility { let cdata = cstore::get_crate_data(cstore, def_id.crate); - decoder::get_method_visibility(cdata, def_id.node) + decoder::get_item_visibility(cdata, def_id.node) } pub fn get_link_args_for_crate(cstore: @mut cstore::CStore, diff --git a/src/librustc/metadata/cstore.rs b/src/librustc/metadata/cstore.rs index ee52b48bc328b..581ad5336de0f 100644 --- a/src/librustc/metadata/cstore.rs +++ b/src/librustc/metadata/cstore.rs @@ -141,24 +141,28 @@ pub fn find_extern_mod_stmt_cnum(cstore: @mut CStore, extern_mod_crate_map.find(&emod_id) } -// returns hashes of crates directly used by this crate. Hashes are -// sorted by crate name. +// returns hashes of crates directly used by this crate. Hashes are sorted by +// (crate name, crate version, crate hash) in lexicographic order (not semver) pub fn get_dep_hashes(cstore: @mut CStore) -> ~[~str] { - struct crate_hash { name: @~str, hash: @~str } + struct crate_hash { name: @~str, vers: @~str, hash: @~str } let mut result = ~[]; let extern_mod_crate_map = cstore.extern_mod_crate_map; for extern_mod_crate_map.each_value |&cnum| { let cdata = cstore::get_crate_data(cstore, cnum); let hash = decoder::get_crate_hash(cdata.data); - debug!("Add hash[%s]: %s", *cdata.name, *hash); + let vers = decoder::get_crate_vers(cdata.data); + debug!("Add hash[%s]: %s %s", *cdata.name, *vers, *hash); result.push(crate_hash { name: cdata.name, + vers: vers, hash: hash }); } - let sorted = std::sort::merge_sort(result, |a, b| a.name <= b.name); + let sorted = do std::sort::merge_sort(result) |a, b| { + (a.name, a.vers, a.hash) <= (b.name, b.vers, b.hash) + }; debug!("sorted:"); for sorted.each |x| { diff --git a/src/librustc/metadata/decoder.rs b/src/librustc/metadata/decoder.rs index c4644a611648d..b952aff9e1ce1 100644 --- a/src/librustc/metadata/decoder.rs +++ b/src/librustc/metadata/decoder.rs @@ -93,7 +93,7 @@ fn lookup_item(item_id: int, data: @~[u8]) -> ebml::Doc { } } -#[deriving_eq] +#[deriving(Eq)] enum Family { Const, // c Fn, // f @@ -145,13 +145,16 @@ fn item_family(item: ebml::Doc) -> Family { } fn item_visibility(item: ebml::Doc) -> ast::visibility { - let visibility = reader::get_doc(item, tag_items_data_item_visibility); - debug!("item visibility for %?", item_family(item)); - match reader::doc_as_u8(visibility) as char { - 'y' => ast::public, - 'n' => ast::private, - 'i' => ast::inherited, - _ => fail!(~"unknown visibility character"), + match reader::maybe_get_doc(item, tag_items_data_item_visibility) { + None => ast::public, + Some(visibility_doc) => { + match reader::doc_as_u8(visibility_doc) as char { + 'y' => ast::public, + 'n' => ast::private, + 'i' => ast::inherited, + _ => fail!(~"unknown visibility character") + } + } } } @@ -869,7 +872,7 @@ pub fn get_item_attrs(cdata: cmd, } } -pure fn struct_field_family_to_visibility(family: Family) -> ast::visibility { +fn struct_field_family_to_visibility(family: Family) -> ast::visibility { match family { PublicField => ast::public, PrivateField => ast::private, @@ -909,8 +912,8 @@ pub fn get_struct_fields(intr: @ident_interner, cdata: cmd, id: ast::node_id) result } -pub fn get_method_visibility(cdata: cmd, id: ast::node_id) - -> ast::visibility { +pub fn get_item_visibility(cdata: cmd, id: ast::node_id) + -> ast::visibility { item_visibility(lookup_item(id, cdata.data)) } diff --git a/src/librustc/metadata/encoder.rs b/src/librustc/metadata/encoder.rs index f057b04e06698..ccc29fbbccb26 100644 --- a/src/librustc/metadata/encoder.rs +++ b/src/librustc/metadata/encoder.rs @@ -1239,7 +1239,7 @@ fn encode_crate_deps(ecx: @EncodeContext, } // mut -> immutable hack for vec::map - deps.slice(0, deps.len()) + deps.slice(0, deps.len()).to_owned() } // We're just going to write a list of crate 'name-hash-version's, with @@ -1313,7 +1313,7 @@ fn encode_hash(ebml_w: writer::Encoder, hash: &str) { } // NB: Increment this as you change the metadata encoding version. -pub const metadata_encoding_version : &'static [u8] = +pub static metadata_encoding_version : &'static [u8] = &[0x72, //'r' as u8, 0x75, //'u' as u8, 0x73, //'s' as u8, diff --git a/src/librustc/middle/borrowck/check_loans.rs b/src/librustc/middle/borrowck/check_loans.rs index 17bdf318e0708..6dfcf6ddf9168 100644 --- a/src/librustc/middle/borrowck/check_loans.rs +++ b/src/librustc/middle/borrowck/check_loans.rs @@ -51,7 +51,7 @@ struct CheckLoanCtxt { } // if we are enforcing purity, why are we doing so? -#[deriving_eq] +#[deriving(Eq)] enum purity_cause { // enforcing purity because fn was declared pure: pc_pure_fn, @@ -80,7 +80,7 @@ pub fn check_loans(bccx: @BorrowckCtxt, visit::visit_crate(*crate, clcx, vt); } -#[deriving_eq] +#[deriving(Eq)] enum assignment_type { at_straight_up, at_swap diff --git a/src/librustc/middle/borrowck/gather_loans.rs b/src/librustc/middle/borrowck/gather_loans.rs index 83fe2db79ef73..bab652a3d1e2f 100644 --- a/src/librustc/middle/borrowck/gather_loans.rs +++ b/src/librustc/middle/borrowck/gather_loans.rs @@ -145,7 +145,7 @@ fn req_loans_in_expr(ex: @ast::expr, // make sure that the thing we are pointing out stays valid // for the lifetime `scope_r` of the resulting ptr: - let scope_r = ty_region(tcx.ty(ex)); + let scope_r = ty_region(tcx, ex.span, tcx.ty(ex)); self.guarantee_valid(base_cmt, mutbl, scope_r); visit::visit_expr(ex, self, vt); } @@ -599,7 +599,8 @@ pub impl GatherLoanCtxt { // find the region of the resulting pointer (note that // the type of such a pattern will *always* be a // region pointer) - let scope_r = ty_region(self.tcx().ty(pat)); + let scope_r = ty_region(self.tcx(), pat.span, + self.tcx().ty(pat)); // if the scope of the region ptr turns out to be // specific to this arm, wrap the categorization with diff --git a/src/librustc/middle/borrowck/mod.rs b/src/librustc/middle/borrowck/mod.rs index 3e63707162417..d5c4b27e6cbb8 100644 --- a/src/librustc/middle/borrowck/mod.rs +++ b/src/librustc/middle/borrowck/mod.rs @@ -340,7 +340,7 @@ pub type root_map = HashMap; // if you have an expression `x.f` and x has type ~@T, we could add an // entry {id:x, derefs:0} to refer to `x` itself, `{id:x, derefs:1}` // to refer to the deref of the unique pointer, and so on. -#[deriving_eq] +#[deriving(Eq)] pub struct root_map_key { id: ast::node_id, derefs: uint @@ -355,7 +355,7 @@ pub type mutbl_map = HashMap; pub type write_guard_map = HashMap; // Errors that can occur -#[deriving_eq] +#[deriving(Eq)] pub enum bckerr_code { err_mut_uniq, err_mut_variant, @@ -367,7 +367,7 @@ pub enum bckerr_code { // Combination of an error code and the categorization of the expression // that caused it -#[deriving_eq] +#[deriving(Eq)] pub struct bckerr { cmt: cmt, code: bckerr_code @@ -382,7 +382,7 @@ pub enum MoveError { // shorthand for something that fails with `bckerr` or succeeds with `T` pub type bckres = Result; -#[deriving_eq] +#[deriving(Eq)] pub enum LoanKind { TotalFreeze, // Entire path is frozen (borrowed as &T) PartialFreeze, // Some subpath is frozen (borrowed as &T) @@ -444,7 +444,7 @@ pub impl LoanKind { /// Creates and returns a new root_map impl to_bytes::IterBytes for root_map_key { - pure fn iter_bytes(&self, +lsb0: bool, f: to_bytes::Cb) { + fn iter_bytes(&self, +lsb0: bool, f: to_bytes::Cb) { to_bytes::iter_bytes_2(&self.id, &self.derefs, lsb0, f); } } diff --git a/src/librustc/middle/borrowck/preserve.rs b/src/librustc/middle/borrowck/preserve.rs index 962af48a70c8f..0440f4525ff36 100644 --- a/src/librustc/middle/borrowck/preserve.rs +++ b/src/librustc/middle/borrowck/preserve.rs @@ -79,7 +79,7 @@ struct PreserveCtxt { root_managed_data: bool } -pub impl PreserveCtxt/&self { +pub impl<'self> PreserveCtxt<'self> { fn tcx(&self) -> ty::ctxt { self.bccx.tcx } fn preserve(&self, cmt: cmt) -> bckres { diff --git a/src/librustc/middle/check_match.rs b/src/librustc/middle/check_match.rs index 245872c39c61a..ddc00000c6b4f 100644 --- a/src/librustc/middle/check_match.rs +++ b/src/librustc/middle/check_match.rs @@ -183,7 +183,7 @@ pub type matrix = ~[~[@pat]]; pub enum useful { useful(ty::t, ctor), useful_, not_useful } -#[deriving_eq] +#[deriving(Eq)] pub enum ctor { single, variant(def_id), @@ -528,6 +528,25 @@ pub fn specialize(cx: @MatchCheckCtxt, } pat_enum(_, args) => { match cx.tcx.def_map.get(&pat_id) { + def_const(did) => { + let const_expr = + lookup_const_by_id(cx.tcx, did).get(); + let e_v = eval_const_expr(cx.tcx, const_expr); + let match_ = match ctor_id { + val(ref v) => compare_const_vals(e_v, (*v)) == 0, + range(ref c_lo, ref c_hi) => { + compare_const_vals((*c_lo), e_v) >= 0 && + compare_const_vals((*c_hi), e_v) <= 0 + } + single => true, + _ => fail!(~"type error") + }; + if match_ { + Some(vec::from_slice(r.tail())) + } else { + None + } + } def_variant(_, id) if variant(id) == ctor_id => { let args = match args { Some(args) => args, diff --git a/src/librustc/middle/const_eval.rs b/src/librustc/middle/const_eval.rs index 4888a01c6b953..7e0a36be0a020 100644 --- a/src/librustc/middle/const_eval.rs +++ b/src/librustc/middle/const_eval.rs @@ -10,6 +10,8 @@ use core::prelude::*; +use metadata::csearch; +use middle::astencode; use middle::resolve; use middle::ty; use middle; @@ -19,6 +21,8 @@ use core::vec; use syntax::{ast, ast_map, ast_util, visit}; use syntax::ast::*; +use std::oldmap::HashMap; + // // This pass classifies expressions by their constant-ness. // @@ -187,7 +191,24 @@ pub fn lookup_const_by_id(tcx: ty::ctxt, Some(_) => None } } else { - None + let maps = astencode::Maps { + mutbl_map: HashMap(), + root_map: HashMap(), + last_use_map: HashMap(), + method_map: HashMap(), + vtable_map: HashMap(), + write_guard_map: HashMap(), + moves_map: HashMap(), + capture_map: HashMap() + }; + match csearch::maybe_get_item_ast(tcx, def_id, + |a, b, c, d| astencode::decode_inlined_item(a, b, maps, /*bar*/ copy c, d)) { + csearch::found(ast::ii_item(item)) => match item.node { + item_const(_, const_expr) => Some(const_expr), + _ => None + }, + _ => None + } } } @@ -219,7 +240,7 @@ pub fn process_crate(crate: @ast::crate, // FIXME (#33): this doesn't handle big integer/float literals correctly // (nor does the rest of our literal handling). -#[deriving_eq] +#[deriving(Eq)] pub enum const_val { const_float(f64), const_int(i64), diff --git a/src/librustc/middle/kind.rs b/src/librustc/middle/kind.rs index 4b1b0d0200f6a..0861e57c9b423 100644 --- a/src/librustc/middle/kind.rs +++ b/src/librustc/middle/kind.rs @@ -22,6 +22,7 @@ use core::str; use core::vec; use std::oldmap::HashMap; use syntax::ast::*; +use syntax::attr::attrs_contains_name; use syntax::codemap::{span, spanned}; use syntax::print::pprust::expr_to_str; use syntax::{visit, ast_util}; @@ -55,7 +56,7 @@ use syntax::{visit, ast_util}; // primitives in the stdlib are explicitly annotated to only take sendable // types. -pub const try_adding: &'static str = "Try adding a move"; +pub static try_adding: &'static str = "Try adding a move"; pub type rval_map = HashMap; @@ -63,7 +64,7 @@ pub struct Context { tcx: ty::ctxt, method_map: typeck::method_map, last_use_map: liveness::last_use_map, - current_item: node_id + current_item: node_id, } pub fn check_crate(tcx: ty::ctxt, @@ -74,16 +75,15 @@ pub fn check_crate(tcx: ty::ctxt, tcx: tcx, method_map: method_map, last_use_map: last_use_map, - current_item: -1 + current_item: -1, }; let visit = visit::mk_vt(@visit::Visitor { visit_arm: check_arm, visit_expr: check_expr, visit_fn: check_fn, visit_ty: check_ty, - visit_item: |i, cx, v| { - visit::visit_item(i, Context { current_item: i.id,.. cx }, v); - }, + visit_item: check_item, + visit_block: check_block, .. *visit::default_visitor() }); visit::visit_crate(*crate, ctx, visit); @@ -92,6 +92,93 @@ pub fn check_crate(tcx: ty::ctxt, type check_fn = @fn(Context, @freevar_entry); +fn check_struct_safe_for_destructor(cx: Context, + span: span, + struct_did: def_id) { + let struct_tpt = ty::lookup_item_type(cx.tcx, struct_did); + if struct_tpt.bounds.len() == 0 { + let struct_ty = ty::mk_struct(cx.tcx, struct_did, ty::substs { + self_r: None, + self_ty: None, + tps: ~[] + }); + if !ty::type_is_owned(cx.tcx, struct_ty) { + cx.tcx.sess.span_err(span, + ~"cannot implement a destructor on a struct \ + that is not Owned"); + cx.tcx.sess.span_note(span, + ~"use \"#[unsafe_destructor]\" on the \ + implementation to force the compiler to \ + allow this"); + } + } else { + cx.tcx.sess.span_err(span, + ~"cannot implement a destructor on a struct \ + with type parameters"); + cx.tcx.sess.span_note(span, + ~"use \"#[unsafe_destructor]\" on the \ + implementation to force the compiler to \ + allow this"); + } +} + +fn check_block(block: &blk, cx: Context, visitor: visit::vt) { + visit::visit_block(block, cx, visitor); +} + +fn check_item(item: @item, cx: Context, visitor: visit::vt) { + // If this is a destructor, check kinds. + if !attrs_contains_name(item.attrs, "unsafe_destructor") { + match item.node { + item_impl(_, Some(trait_ref), self_type, _) => { + match cx.tcx.def_map.find(&trait_ref.ref_id) { + None => cx.tcx.sess.bug(~"trait ref not in def map!"), + Some(trait_def) => { + let trait_def_id = ast_util::def_id_of_def(trait_def); + if cx.tcx.lang_items.drop_trait() == trait_def_id { + // Yes, it's a destructor. + match self_type.node { + ty_path(_, path_node_id) => { + let struct_def = cx.tcx.def_map.get( + &path_node_id); + let struct_did = + ast_util::def_id_of_def(struct_def); + check_struct_safe_for_destructor( + cx, + self_type.span, + struct_did); + } + _ => { + cx.tcx.sess.span_bug(self_type.span, + ~"the self type for \ + the Drop trait \ + impl is not a \ + path"); + } + } + } + } + } + } + item_struct(struct_def, _) => { + match struct_def.dtor { + None => {} + Some(ref dtor) => { + let struct_did = def_id { crate: 0, node: item.id }; + check_struct_safe_for_destructor(cx, + dtor.span, + struct_did); + } + } + } + _ => {} + } + } + + let cx = Context { current_item: item.id, ..cx }; + visit::visit_item(item, cx, visitor); +} + // Yields the appropriate function to check the kind of closed over // variables. `id` is the node_id for some expression that creates the // closure. @@ -287,7 +374,7 @@ pub fn check_bounds(cx: Context, ty::bound_durable => { if !kind.is_durable(cx.tcx) { - missing.push("&static"); + missing.push("'static"); } } @@ -378,7 +465,7 @@ pub fn check_durable(tcx: ty::ctxt, ty: ty::t, sp: span) -> bool { match ty::get(ty).sty { ty::ty_param(*) => { tcx.sess.span_err(sp, ~"value may contain borrowed \ - pointers; use `&static` bound"); + pointers; use `'static` bound"); } _ => { tcx.sess.span_err(sp, ~"value may contain borrowed \ @@ -392,7 +479,7 @@ pub fn check_durable(tcx: ty::ctxt, ty: ty::t, sp: span) -> bool { } /// This is rather subtle. When we are casting a value to a -/// instantiated trait like `a as trait/&r`, regionck already ensures +/// instantiated trait like `a as trait<'r>`, regionck already ensures /// that any borrowed pointers that appear in the type of `a` are /// bounded by `&r`. However, it is possible that there are *type /// parameters* in the type of `a`, and those *type parameters* may diff --git a/src/librustc/middle/lang_items.rs b/src/librustc/middle/lang_items.rs index f88be89ad0080..669587205d546 100644 --- a/src/librustc/middle/lang_items.rs +++ b/src/librustc/middle/lang_items.rs @@ -82,7 +82,7 @@ pub struct LanguageItems { } pub impl LanguageItems { - static pub fn new(&self) -> LanguageItems { + pub fn new() -> LanguageItems { LanguageItems { items: [ None, ..35 ] } @@ -96,7 +96,7 @@ pub impl LanguageItems { } } - static pub fn item_name(&self, index: uint) -> &'static str { + pub fn item_name(index: uint) -> &'static str { match index { 0 => "const", 1 => "copy", @@ -255,10 +255,10 @@ pub impl LanguageItems { } } -fn LanguageItemCollector(crate: @crate, - session: Session, - items: &'r mut LanguageItems) - -> LanguageItemCollector/&r { +fn LanguageItemCollector<'r>(crate: @crate, + session: Session, + items: &'r mut LanguageItems) + -> LanguageItemCollector<'r> { let item_refs = HashMap(); item_refs.insert(@~"const", ConstTraitLangItem as uint); @@ -320,7 +320,7 @@ struct LanguageItemCollector { item_refs: HashMap<@~str, uint>, } -pub impl LanguageItemCollector/&self { +pub impl<'self> LanguageItemCollector<'self> { fn match_and_collect_meta_item(&self, item_def_id: def_id, meta_item: @meta_item) { match meta_item.node { diff --git a/src/librustc/middle/lint.rs b/src/librustc/middle/lint.rs index a8fe25b61c79a..2b16ccdd1d220 100644 --- a/src/librustc/middle/lint.rs +++ b/src/librustc/middle/lint.rs @@ -60,7 +60,7 @@ use syntax::{ast, ast_util, visit}; * process. */ -#[deriving_eq] +#[deriving(Eq)] pub enum lint { ctypes, unused_imports, @@ -99,7 +99,7 @@ pub fn level_to_str(lv: level) -> &'static str { } } -#[deriving_eq] +#[deriving(Eq)] pub enum level { allow, warn, deny, forbid } @@ -534,7 +534,7 @@ fn check_item_while_true(cx: ty::ctxt, it: @ast::item) { } fn check_item_type_limits(cx: ty::ctxt, it: @ast::item) { - pure fn is_valid(binop: ast::binop, v: T, + fn is_valid(binop: ast::binop, v: T, min: T, max: T) -> bool { match binop { ast::lt => v <= max, @@ -546,7 +546,7 @@ fn check_item_type_limits(cx: ty::ctxt, it: @ast::item) { } } - pure fn rev_binop(binop: ast::binop) -> ast::binop { + fn rev_binop(binop: ast::binop) -> ast::binop { match binop { ast::lt => ast::gt, ast::le => ast::ge, @@ -556,7 +556,7 @@ fn check_item_type_limits(cx: ty::ctxt, it: @ast::item) { } } - pure fn int_ty_range(int_ty: ast::int_ty) -> (i64, i64) { + fn int_ty_range(int_ty: ast::int_ty) -> (i64, i64) { match int_ty { ast::ty_i => (int::min_value as i64, int::max_value as i64), ast::ty_char => (u32::min_value as i64, u32::max_value as i64), @@ -567,7 +567,7 @@ fn check_item_type_limits(cx: ty::ctxt, it: @ast::item) { } } - pure fn uint_ty_range(uint_ty: ast::uint_ty) -> (u64, u64) { + fn uint_ty_range(uint_ty: ast::uint_ty) -> (u64, u64) { match uint_ty { ast::ty_u => (uint::min_value as u64, uint::max_value as u64), ast::ty_u8 => (u8::min_value as u64, u8::max_value as u64), @@ -622,7 +622,7 @@ fn check_item_type_limits(cx: ty::ctxt, it: @ast::item) { } } - pure fn is_comparison(binop: ast::binop) -> bool { + fn is_comparison(binop: ast::binop) -> bool { match binop { ast::eq | ast::lt | ast::le | ast::ne | ast::ge | ast::gt => true, @@ -888,14 +888,14 @@ fn check_item_non_camel_case_types(cx: ty::ctxt, it: @ast::item) { fn ident_without_trailing_underscores(ident: &'r str) -> &'r str { match str::rfind(ident, |c| c != '_') { - Some(idx) => str::view(ident, 0, idx + 1), + Some(idx) => str::slice(ident, 0, idx + 1), None => ident, // all underscores } } fn ident_without_leading_underscores(ident: &'r str) -> &'r str { match str::find(ident, |c| c != '_') { - Some(idx) => str::view(ident, idx, ident.len()), + Some(idx) => str::slice(ident, idx, ident.len()), None => ident // all underscores } } diff --git a/src/librustc/middle/liveness.rs b/src/librustc/middle/liveness.rs index 7f14b21585889..e3a595a855211 100644 --- a/src/librustc/middle/liveness.rs +++ b/src/librustc/middle/liveness.rs @@ -141,13 +141,13 @@ struct Variable(uint); struct LiveNode(uint); impl cmp::Eq for Variable { - pure fn eq(&self, other: &Variable) -> bool { *(*self) == *(*other) } - pure fn ne(&self, other: &Variable) -> bool { *(*self) != *(*other) } + fn eq(&self, other: &Variable) -> bool { *(*self) == *(*other) } + fn ne(&self, other: &Variable) -> bool { *(*self) != *(*other) } } impl cmp::Eq for LiveNode { - pure fn eq(&self, other: &LiveNode) -> bool { *(*self) == *(*other) } - pure fn ne(&self, other: &LiveNode) -> bool { *(*self) != *(*other) } + fn eq(&self, other: &LiveNode) -> bool { *(*self) == *(*other) } + fn ne(&self, other: &LiveNode) -> bool { *(*self) != *(*other) } } enum LiveNodeKind { @@ -158,7 +158,7 @@ enum LiveNodeKind { } impl cmp::Eq for LiveNodeKind { - pure fn eq(&self, other: &LiveNodeKind) -> bool { + fn eq(&self, other: &LiveNodeKind) -> bool { match (*self) { FreeVarNode(e0a) => { match (*other) { @@ -186,7 +186,7 @@ impl cmp::Eq for LiveNodeKind { } } } - pure fn ne(&self, other: &LiveNodeKind) -> bool { !(*self).eq(other) } + fn ne(&self, other: &LiveNodeKind) -> bool { !(*self).eq(other) } } fn live_node_kind_to_str(lnk: LiveNodeKind, cx: ty::ctxt) -> ~str { @@ -224,11 +224,11 @@ pub fn check_crate(tcx: ty::ctxt, } impl to_str::ToStr for LiveNode { - pure fn to_str(&self) -> ~str { fmt!("ln(%u)", **self) } + fn to_str(&self) -> ~str { fmt!("ln(%u)", **self) } } impl to_str::ToStr for Variable { - pure fn to_str(&self) -> ~str { fmt!("v(%u)", **self) } + fn to_str(&self) -> ~str { fmt!("v(%u)", **self) } } // ______________________________________________________________________ @@ -254,7 +254,7 @@ impl to_str::ToStr for Variable { // assignment. And so forth. pub impl LiveNode { - pure fn is_valid(&self) -> bool { **self != uint::max_value } + fn is_valid(&self) -> bool { **self != uint::max_value } } fn invalid_node() -> LiveNode { LiveNode(uint::max_value) } @@ -653,9 +653,9 @@ struct Specials { no_ret_var: Variable } -const ACC_READ: uint = 1u; -const ACC_WRITE: uint = 2u; -const ACC_USE: uint = 4u; +static ACC_READ: uint = 1u; +static ACC_WRITE: uint = 2u; +static ACC_USE: uint = 4u; type LiveNodeMap = HashMap; diff --git a/src/librustc/middle/mem_categorization.rs b/src/librustc/middle/mem_categorization.rs index fee3695002da1..e767b0ff812f4 100644 --- a/src/librustc/middle/mem_categorization.rs +++ b/src/librustc/middle/mem_categorization.rs @@ -60,7 +60,7 @@ use syntax::ast; use syntax::codemap::span; use syntax::print::pprust; -#[deriving_eq] +#[deriving(Eq)] pub enum categorization { cat_rvalue, // result of eval'ing some misc expr cat_special(special_kind), // @@ -75,7 +75,7 @@ pub enum categorization { } // different kinds of pointers: -#[deriving_eq] +#[deriving(Eq)] pub enum ptr_kind { uniq_ptr, gc_ptr(ast::mutability), @@ -85,7 +85,7 @@ pub enum ptr_kind { // I am coining the term "components" to mean "pieces of a data // structure accessible without a dereference": -#[deriving_eq] +#[deriving(Eq)] pub enum comp_kind { comp_tuple, // elt in a tuple comp_anon_field, // anonymous field (in e.g. @@ -98,7 +98,7 @@ pub enum comp_kind { } // different kinds of expressions we might evaluate -#[deriving_eq] +#[deriving(Eq)] pub enum special_kind { sk_method, sk_static_item, @@ -106,7 +106,7 @@ pub enum special_kind { sk_heap_upvar } -#[deriving_eq] +#[deriving(Eq)] pub enum MutabilityCategory { McImmutable, // Immutable. McReadOnly, // Read-only (`const`) @@ -119,7 +119,7 @@ pub enum MutabilityCategory { // which the value is stored. // // note: cmt stands for "categorized mutable type". -#[deriving_eq] +#[deriving(Eq)] pub struct cmt_ { id: ast::node_id, // id of expr/pat producing this value span: span, // span of same expr/pat @@ -134,7 +134,7 @@ pub type cmt = @cmt_; // a loan path is like a category, but it exists only when the data is // interior to the stack frame. loan paths are used as the key to a // map indicating what is borrowed at any point in time. -#[deriving_eq] +#[deriving(Eq)] pub enum loan_path { lp_local(ast::node_id), lp_arg(ast::node_id), @@ -305,13 +305,13 @@ pub struct mem_categorization_ctxt { } impl ToStr for MutabilityCategory { - pure fn to_str(&self) -> ~str { + fn to_str(&self) -> ~str { fmt!("%?", *self) } } pub impl MutabilityCategory { - static fn from_mutbl(&self, m: ast::mutability) -> MutabilityCategory { + fn from_mutbl(m: ast::mutability) -> MutabilityCategory { match m { m_imm => McImmutable, m_const => McReadOnly, @@ -916,6 +916,11 @@ pub impl mem_categorization_ctxt { self.cat_pattern(cmt_field, *subpat, op); } } + Some(ast::def_const(*)) => { + for subpats.each |subpat| { + self.cat_pattern(cmt, *subpat, op); + } + } _ => { self.tcx.sess.span_bug( pat.span, diff --git a/src/librustc/middle/pat_util.rs b/src/librustc/middle/pat_util.rs index 4522977a4ab12..a25fddcad88c8 100644 --- a/src/librustc/middle/pat_util.rs +++ b/src/librustc/middle/pat_util.rs @@ -43,7 +43,7 @@ pub fn pat_is_variant_or_struct(dm: resolve::DefMap, pat: @pat) -> bool { pub fn pat_is_const(dm: resolve::DefMap, pat: &pat) -> bool { match pat.node { - pat_ident(_, _, None) => { + pat_ident(_, _, None) | pat_enum(*) => { match dm.find(&pat.id) { Some(def_const(*)) => true, _ => false diff --git a/src/librustc/middle/privacy.rs b/src/librustc/middle/privacy.rs index 5a4fe4018ceaf..c3a65a4f256f4 100644 --- a/src/librustc/middle/privacy.rs +++ b/src/librustc/middle/privacy.rs @@ -265,8 +265,7 @@ pub fn check_crate(tcx: ty::ctxt, } } else { let visibility = - csearch::get_method_visibility(tcx.sess.cstore, - method_id); + csearch::get_item_visibility(tcx.sess.cstore, method_id); if visibility != public { tcx.sess.span_err(span, fmt!("method `%s` is private", @@ -298,8 +297,16 @@ pub fn check_crate(tcx: ty::ctxt, .idents .last()))); } - } else { - // XXX: Check privacy in external crates. + } else if csearch::get_item_visibility(tcx.sess.cstore, + def_id) != public { + tcx.sess.span_err(span, + fmt!("function `%s` is private", + *tcx.sess + .parse_sess + .interner + .get(copy *path + .idents + .last()))); } } _ => {} diff --git a/src/librustc/middle/region.rs b/src/librustc/middle/region.rs index 6dcf1ba812863..10838a7a8dc2c 100644 --- a/src/librustc/middle/region.rs +++ b/src/librustc/middle/region.rs @@ -389,7 +389,7 @@ pub fn resolve_crate(sess: Session, pub type region_paramd_items = HashMap; -#[deriving_eq] +#[deriving(Eq)] pub struct region_dep { ambient_variance: region_variance, id: ast::node_id diff --git a/src/librustc/middle/resolve.rs b/src/librustc/middle/resolve.rs index 6c2168548f147..00883b28b0493 100644 --- a/src/librustc/middle/resolve.rs +++ b/src/librustc/middle/resolve.rs @@ -77,6 +77,7 @@ use syntax::opt_vec::OptVec; use core::option::{Some, get, is_some, is_none}; use core::str::{connect, split_str}; +use core::hashmap::linear::LinearMap; use std::oldmap::HashMap; // Definition mapping @@ -121,7 +122,7 @@ pub struct Export2 { reexport: bool, // Whether this is a reexport. } -#[deriving_eq] +#[deriving(Eq)] pub enum PatternBindingMode { RefutableMode, LocalIrrefutableMode, @@ -150,7 +151,7 @@ pub enum NamespaceResult { } pub impl NamespaceResult { - pure fn is_unknown(&self) -> bool { + fn is_unknown(&self) -> bool { match *self { UnknownResult => true, _ => false @@ -165,7 +166,7 @@ pub enum NameDefinition { } -#[deriving_eq] +#[deriving(Eq)] pub enum Mutability { Mutable, Immutable @@ -178,7 +179,7 @@ pub enum SelfBinding { pub type ResolveVisitor = vt<()>; -#[deriving_eq] +#[deriving(Eq)] pub enum ImportDirectiveNS { TypeNSOnly, AnyNS @@ -270,7 +271,7 @@ pub enum MethodSort { // FIXME #4947: The X-ray flag is kind of questionable in the first // place. It might be better to introduce an expr_xray_path instead. -#[deriving_eq] +#[deriving(Eq)] pub enum XrayFlag { NoXray, //< Private items cannot be accessed. Xray //< Private items can be accessed. @@ -291,13 +292,13 @@ pub enum ModulePrefixResult { PrefixFound(@mut Module, uint) } -#[deriving_eq] +#[deriving(Eq)] pub enum AllowCapturingSelfFlag { AllowCapturingSelf, //< The "self" definition can be captured. DontAllowCapturingSelf, //< The "self" definition cannot be captured. } -#[deriving_eq] +#[deriving(Eq)] enum NameSearchType { SearchItemsAndPublicImports, //< Search items and public imports. SearchItemsAndAllImports, //< Search items and all imports. @@ -311,7 +312,7 @@ pub enum BareIdentifierPatternResolution { // Specifies how duplicates should be handled when adding a child item if // another item exists with the same name in some namespace. -#[deriving_eq] +#[deriving(Eq)] pub enum DuplicateCheckingMode { ForbidDuplicateModules, ForbidDuplicateTypes, @@ -456,7 +457,7 @@ pub struct Module { def_id: Option, kind: ModuleKind, - children: @HashMap, + children: @mut LinearMap, imports: @mut ~[@ImportDirective], // The anonymous children of this node. Anonymous children are pseudo- @@ -477,7 +478,7 @@ pub struct Module { anonymous_children: @HashMap, // The status of resolving each import in this module. - import_resolutions: @HashMap, + import_resolutions: @mut LinearMap, // The number of unresolved globs that this module exports. glob_count: uint, @@ -494,10 +495,10 @@ pub fn Module(parent_link: ParentLink, parent_link: parent_link, def_id: def_id, kind: kind, - children: @HashMap(), + children: @mut LinearMap::new(), imports: @mut ~[], anonymous_children: @HashMap(), - import_resolutions: @HashMap(), + import_resolutions: @mut LinearMap::new(), glob_count: 0, resolved_import_count: 0 } @@ -1024,7 +1025,7 @@ pub impl Resolver { *self.session.str_of(name))); } } - return (child, new_parent); + return (*child, new_parent); } } } @@ -1614,7 +1615,7 @@ pub impl Resolver { let name_bindings = parent_module.children.get( &ident); resolution.type_target = - Some(Target(parent_module, name_bindings)); + Some(Target(parent_module, *name_bindings)); } } @@ -2168,13 +2169,13 @@ pub impl Resolver { // Continue. } Some(child_name_bindings) => { - if (*child_name_bindings).defined_in_namespace(ValueNS) { + if child_name_bindings.defined_in_namespace(ValueNS) { value_result = BoundResult(containing_module, - child_name_bindings); + *child_name_bindings); } - if (*child_name_bindings).defined_in_namespace(TypeNS) { + if child_name_bindings.defined_in_namespace(TypeNS) { type_result = BoundResult(containing_module, - child_name_bindings); + *child_name_bindings); } } } @@ -2244,11 +2245,11 @@ pub impl Resolver { // The name is an import which has been fully // resolved. We can, therefore, just follow it. if value_result.is_unknown() { - value_result = get_binding(import_resolution, + value_result = get_binding(*import_resolution, ValueNS); } if type_result.is_unknown() { - type_result = get_binding(import_resolution, + type_result = get_binding(*import_resolution, TypeNS); } } @@ -2355,9 +2356,9 @@ pub impl Resolver { // Continue. } Some(child_name_bindings) => { - if (*child_name_bindings).defined_in_namespace(TypeNS) { + if child_name_bindings.defined_in_namespace(TypeNS) { module_result = BoundResult(containing_module, - child_name_bindings); + *child_name_bindings); } } } @@ -2486,7 +2487,7 @@ pub impl Resolver { // Add all resolved imports from the containing module. for containing_module.import_resolutions.each - |&ident, &target_import_resolution| { + |&(ident, target_import_resolution)| { debug!("(resolving glob import) writing module resolution \ %? into `%s`", @@ -2494,7 +2495,7 @@ pub impl Resolver { self.module_to_str(module_)); // Here we merge two import resolutions. - match module_.import_resolutions.find(&ident) { + match module_.import_resolutions.find(ident) { None if target_import_resolution.privacy == Public => { // Simple: just copy the old import resolution. let new_import_resolution = @@ -2507,7 +2508,7 @@ pub impl Resolver { copy target_import_resolution.type_target; module_.import_resolutions.insert - (ident, new_import_resolution); + (*ident, new_import_resolution); } None => { /* continue ... */ } Some(dest_import_resolution) => { @@ -2537,39 +2538,39 @@ pub impl Resolver { } // Add all children from the containing module. - for containing_module.children.each |&ident, &name_bindings| { + for containing_module.children.each |&(ident, name_bindings)| { let mut dest_import_resolution; - match module_.import_resolutions.find(&ident) { + match module_.import_resolutions.find(ident) { None => { // Create a new import resolution from this child. dest_import_resolution = @mut ImportResolution(privacy, span, state); module_.import_resolutions.insert - (ident, dest_import_resolution); + (*ident, dest_import_resolution); } Some(existing_import_resolution) => { - dest_import_resolution = existing_import_resolution; + dest_import_resolution = *existing_import_resolution; } } debug!("(resolving glob import) writing resolution `%s` in `%s` \ to `%s`, privacy=%?", - *self.session.str_of(ident), + *self.session.str_of(*ident), self.module_to_str(containing_module), self.module_to_str(module_), copy dest_import_resolution.privacy); // Merge the child item into the import resolution. - if (*name_bindings).defined_in_public_namespace(ValueNS) { + if name_bindings.defined_in_public_namespace(ValueNS) { debug!("(resolving glob import) ... for value target"); dest_import_resolution.value_target = - Some(Target(containing_module, name_bindings)); + Some(Target(containing_module, *name_bindings)); } - if (*name_bindings).defined_in_public_namespace(TypeNS) { + if name_bindings.defined_in_public_namespace(TypeNS) { debug!("(resolving glob import) ... for type target"); dest_import_resolution.type_target = - Some(Target(containing_module, name_bindings)); + Some(Target(containing_module, *name_bindings)); } } @@ -2763,8 +2764,8 @@ pub impl Resolver { match module_.children.find(&name) { Some(name_bindings) - if (*name_bindings).defined_in_namespace(namespace) => { - return Success(Target(module_, name_bindings)); + if name_bindings.defined_in_namespace(namespace) => { + return Success(Target(module_, *name_bindings)); } Some(_) | None => { /* Not found; continue. */ } } @@ -3008,10 +3009,9 @@ pub impl Resolver { // First, check the direct children of the module. match module_.children.find(&name) { Some(name_bindings) - if (*name_bindings).defined_in_namespace(namespace) => { - + if name_bindings.defined_in_namespace(namespace) => { debug!("(resolving name in module) found node as child"); - return Success(Target(module_, name_bindings)); + return Success(Target(module_, *name_bindings)); } Some(_) | None => { // Continue. @@ -3193,7 +3193,7 @@ pub impl Resolver { fn add_exports_for_module(@mut self, exports2: &mut ~[Export2], module_: @mut Module) { - for module_.children.each |ident, namebindings| { + for module_.children.each |&(ident, namebindings)| { debug!("(computing exports) maybe export '%s'", *self.session.str_of(*ident)); self.add_exports_of_namebindings(&mut *exports2, @@ -3208,7 +3208,7 @@ pub impl Resolver { false); } - for module_.import_resolutions.each |ident, importresolution| { + for module_.import_resolutions.each |&(ident, importresolution)| { if importresolution.privacy != Public { debug!("(computing exports) not reexporting private `%s`", *self.session.str_of(*ident)); @@ -4333,23 +4333,24 @@ pub impl Resolver { } pat_enum(path, _) => { - // This must be an enum variant or struct. + // This must be an enum variant, struct or const. match self.resolve_path(path, ValueNS, false, visitor) { Some(def @ def_variant(*)) | - Some(def @ def_struct(*)) => { + Some(def @ def_struct(*)) | + Some(def @ def_const(*)) => { self.record_def(pattern.id, def); } Some(_) => { self.session.span_err( path.span, - fmt!("not an enum variant or struct: %s", + fmt!("not an enum variant, struct or const: %s", *self.session.str_of( *path.idents.last()))); } None => { self.session.span_err(path.span, - ~"unresolved enum variant \ - or struct"); + ~"unresolved enum variant, \ + struct or const"); } } @@ -4740,8 +4741,8 @@ pub impl Resolver { let mut j = this.value_ribs.len(); while j != 0 { j -= 1; - for this.value_ribs[j].bindings.each_entry |e| { - vec::push(&mut maybes, copy *this.session.str_of(e.key)); + for this.value_ribs[j].bindings.each_key |&k| { + vec::push(&mut maybes, copy *this.session.str_of(k)); vec::push(&mut values, uint::max_value); } } @@ -5311,9 +5312,9 @@ pub impl Resolver { } debug!("Import resolutions:"); - for module_.import_resolutions.each |&name, &import_resolution| { + for module_.import_resolutions.each |&(name, import_resolution)| { let mut value_repr; - match (*import_resolution).target_for_namespace(ValueNS) { + match import_resolution.target_for_namespace(ValueNS) { None => { value_repr = ~""; } Some(_) => { value_repr = ~" value:?"; @@ -5322,7 +5323,7 @@ pub impl Resolver { } let mut type_repr; - match (*import_resolution).target_for_namespace(TypeNS) { + match import_resolution.target_for_namespace(TypeNS) { None => { type_repr = ~""; } Some(_) => { type_repr = ~" type:?"; @@ -5330,7 +5331,7 @@ pub impl Resolver { } } - debug!("* %s:%s%s", *self.session.str_of(name), + debug!("* %s:%s%s", *self.session.str_of(*name), value_repr, type_repr); } } diff --git a/src/librustc/middle/trans/_match.rs b/src/librustc/middle/trans/_match.rs index 45fe40ca1f70f..7529b2132fd9e 100644 --- a/src/librustc/middle/trans/_match.rs +++ b/src/librustc/middle/trans/_match.rs @@ -331,9 +331,9 @@ pub struct ArmData { bindings_map: BindingsMap } -pub struct Match { +pub struct Match<'self> { pats: ~[@ast::pat], - data: @ArmData/&self + data: @ArmData<'self> } pub fn match_to_str(bcx: block, m: &Match) -> ~str { @@ -359,9 +359,11 @@ pub fn has_nested_bindings(m: &[@Match], col: uint) -> bool { return false; } -pub fn expand_nested_bindings(bcx: block, m: &[@Match/&r], - col: uint, val: ValueRef) - -> ~[@Match/&r] { +pub fn expand_nested_bindings<'r>(bcx: block, + m: &[@Match<'r>], + col: uint, + val: ValueRef) + -> ~[@Match<'r>] { debug!("expand_nested_bindings(bcx=%s, m=%s, col=%u, val=%?)", bcx.to_str(), matches_to_str(bcx, m), @@ -402,9 +404,13 @@ pub fn assert_is_binding_or_wild(bcx: block, p: @ast::pat) { } } -pub fn enter_match(bcx: block, dm: DefMap, m: &[@Match/&r], - col: uint, val: ValueRef, e: enter_pat) - -> ~[@Match/&r] { +pub fn enter_match<'r>(bcx: block, + dm: DefMap, + m: &[@Match<'r>], + col: uint, + val: ValueRef, + e: enter_pat) + -> ~[@Match<'r>] { debug!("enter_match(bcx=%s, m=%s, col=%u, val=%?)", bcx.to_str(), matches_to_str(bcx, m), @@ -445,9 +451,12 @@ pub fn enter_match(bcx: block, dm: DefMap, m: &[@Match/&r], return result; } -pub fn enter_default(bcx: block, dm: DefMap, m: &[@Match/&r], - col: uint, val: ValueRef) - -> ~[@Match/&r] { +pub fn enter_default<'r>(bcx: block, + dm: DefMap, + m: &[@Match<'r>], + col: uint, + val: ValueRef) + -> ~[@Match<'r>] { debug!("enter_default(bcx=%s, m=%s, col=%u, val=%?)", bcx.to_str(), matches_to_str(bcx, m), @@ -488,9 +497,13 @@ pub fn enter_default(bcx: block, dm: DefMap, m: &[@Match/&r], // so all patterns must either be records (resp. tuples) or // wildcards -pub fn enter_opt(bcx: block, m: &[@Match/&r], opt: &Opt, col: uint, - variant_size: uint, val: ValueRef) - -> ~[@Match/&r] { +pub fn enter_opt<'r>(bcx: block, + m: &[@Match<'r>], + opt: &Opt, + col: uint, + variant_size: uint, + val: ValueRef) + -> ~[@Match<'r>] { debug!("enter_opt(bcx=%s, m=%s, col=%u, val=%?)", bcx.to_str(), matches_to_str(bcx, m), @@ -502,6 +515,16 @@ pub fn enter_opt(bcx: block, m: &[@Match/&r], opt: &Opt, col: uint, let dummy = @ast::pat {id: 0, node: ast::pat_wild, span: dummy_sp()}; do enter_match(bcx, tcx.def_map, m, col, val) |p| { match p.node { + ast::pat_enum(*) | + ast::pat_ident(_, _, None) if pat_is_const(tcx.def_map, p) => { + let const_def = tcx.def_map.get(&p.id); + let const_def_id = ast_util::def_id_of_def(const_def); + if opt_eq(tcx, &lit(ConstLit(const_def_id)), opt) { + Some(~[]) + } else { + None + } + } ast::pat_enum(_, ref subpats) => { if opt_eq(tcx, &variant_opt(bcx, p.id), opt) { match *subpats { @@ -520,15 +543,6 @@ pub fn enter_opt(bcx: block, m: &[@Match/&r], opt: &Opt, col: uint, None } } - ast::pat_ident(_, _, None) if pat_is_const(tcx.def_map, p) => { - let const_def = tcx.def_map.get(&p.id); - let const_def_id = ast_util::def_id_of_def(const_def); - if opt_eq(tcx, &lit(ConstLit(const_def_id)), opt) { - Some(~[]) - } else { - None - } - } ast::pat_lit(l) => { if opt_eq(tcx, &lit(ExprLit(l)), opt) {Some(~[])} else {None} } @@ -598,11 +612,11 @@ pub fn enter_opt(bcx: block, m: &[@Match/&r], opt: &Opt, col: uint, pub fn enter_rec_or_struct(bcx: block, dm: DefMap, - m: &[@Match/&r], + m: &[@Match<'r>], col: uint, fields: &[ast::ident], val: ValueRef) - -> ~[@Match/&r] { + -> ~[@Match<'r>] { debug!("enter_rec_or_struct(bcx=%s, m=%s, col=%u, val=%?)", bcx.to_str(), matches_to_str(bcx, m), @@ -631,9 +645,13 @@ pub fn enter_rec_or_struct(bcx: block, } } -pub fn enter_tup(bcx: block, dm: DefMap, m: &[@Match/&r], - col: uint, val: ValueRef, n_elts: uint) - -> ~[@Match/&r] { +pub fn enter_tup<'r>(bcx: block, + dm: DefMap, + m: &[@Match<'r>], + col: uint, + val: ValueRef, + n_elts: uint) + -> ~[@Match<'r>] { debug!("enter_tup(bcx=%s, m=%s, col=%u, val=%?)", bcx.to_str(), matches_to_str(bcx, m), @@ -655,13 +673,13 @@ pub fn enter_tup(bcx: block, dm: DefMap, m: &[@Match/&r], } } -pub fn enter_tuple_struct(bcx: block, - dm: DefMap, - m: &[@Match/&r], - col: uint, - val: ValueRef, - n_elts: uint) - -> ~[@Match/&r] { +pub fn enter_tuple_struct<'r>(bcx: block, + dm: DefMap, + m: &[@Match<'r>], + col: uint, + val: ValueRef, + n_elts: uint) + -> ~[@Match<'r>] { debug!("enter_tuple_struct(bcx=%s, m=%s, col=%u, val=%?)", bcx.to_str(), matches_to_str(bcx, m), @@ -681,12 +699,12 @@ pub fn enter_tuple_struct(bcx: block, } } -pub fn enter_box(bcx: block, - dm: DefMap, - m: &[@Match/&r], - col: uint, - val: ValueRef) - -> ~[@Match/&r] { +pub fn enter_box<'r>(bcx: block, + dm: DefMap, + m: &[@Match<'r>], + col: uint, + val: ValueRef) + -> ~[@Match<'r>] { debug!("enter_box(bcx=%s, m=%s, col=%u, val=%?)", bcx.to_str(), matches_to_str(bcx, m), @@ -708,12 +726,12 @@ pub fn enter_box(bcx: block, } } -pub fn enter_uniq(bcx: block, - dm: DefMap, - m: &[@Match/&r], - col: uint, - val: ValueRef) - -> ~[@Match/&r] { +pub fn enter_uniq<'r>(bcx: block, + dm: DefMap, + m: &[@Match<'r>], + col: uint, + val: ValueRef) + -> ~[@Match<'r>] { debug!("enter_uniq(bcx=%s, m=%s, col=%u, val=%?)", bcx.to_str(), matches_to_str(bcx, m), @@ -735,12 +753,12 @@ pub fn enter_uniq(bcx: block, } } -pub fn enter_region(bcx: block, - dm: DefMap, - m: &[@Match/&r], - col: uint, - val: ValueRef) - -> ~[@Match/&r] { +pub fn enter_region<'r>(bcx: block, + dm: DefMap, + m: &[@Match<'r>], + col: uint, + val: ValueRef) + -> ~[@Match<'r>] { debug!("enter_region(bcx=%s, m=%s, col=%u, val=%?)", bcx.to_str(), matches_to_str(bcx, m), @@ -806,6 +824,10 @@ pub fn get_options(bcx: block, m: &[@Match], col: uint) -> ~[Opt] { add_to_set(ccx.tcx, &mut found, variant_opt(bcx, cur.id)); } + Some(ast::def_const(const_did)) => { + add_to_set(ccx.tcx, &mut found, + lit(ConstLit(const_did))); + } _ => {} } } @@ -1032,7 +1054,7 @@ pub fn pick_col(m: &[@Match]) -> uint { return best_col; } -#[deriving_eq] +#[deriving(Eq)] pub enum branch_kind { no_branch, single, switch, compare, compare_vec_len, } // Compiles a comparison between two things. @@ -1782,6 +1804,9 @@ pub fn bind_irrefutable_pat(bcx: block, } } } + Some(ast::def_const(*)) => { + bcx = bind_irrefutable_pat(bcx, pat, val, make_copy, binding_mode); + } _ => { // Nothing to do here. } diff --git a/src/librustc/middle/trans/base.rs b/src/librustc/middle/trans/base.rs index c36d0446ef0a7..62fff5837666e 100644 --- a/src/librustc/middle/trans/base.rs +++ b/src/librustc/middle/trans/base.rs @@ -88,11 +88,14 @@ pub struct icx_popper { ccx: @CrateContext, } +#[unsafe_destructor] impl Drop for icx_popper { fn finalize(&self) { - if self.ccx.sess.count_llvm_insns() { - self.ccx.stats.llvm_insn_ctxt.pop(); - } + unsafe { + if self.ccx.sess.count_llvm_insns() { + self.ccx.stats.llvm_insn_ctxt.pop(); + } + } } } @@ -804,9 +807,9 @@ pub fn invoke(bcx: block, llfn: ValueRef, +llargs: ~[ValueRef]) -> block { if bcx.unreachable { return bcx; } match bcx.node_info { - None => error!("invoke at ???"), + None => debug!("invoke at ???"), Some(node_info) => { - error!("invoke at %s", + debug!("invoke at %s", bcx.sess().codemap.span_to_str(node_info.span)); } } @@ -1264,7 +1267,7 @@ pub fn trans_block_cleanups_(bcx: block, bcx.ccx().sess.opts.debugging_opts & session::no_landing_pads != 0; if bcx.unreachable && !no_lpads { return bcx; } let mut bcx = bcx; - for vec::rev_each(cleanups) |cu| { + for cleanups.each_reverse |cu| { match *cu { clean(cfn, cleanup_type) | clean_temp(_, cfn, cleanup_type) => { // Some types don't need to be cleaned up during @@ -1512,7 +1515,7 @@ pub fn alloc_ty(bcx: block, t: ty::t) -> ValueRef { let _icx = bcx.insn_ctxt("alloc_ty"); let ccx = bcx.ccx(); let llty = type_of::type_of(ccx, t); - if ty::type_has_params(t) { error!("%s", ty_to_str(ccx.tcx, t)); } + if ty::type_has_params(t) { debug!("%s", ty_to_str(ccx.tcx, t)); } fail_unless!(!ty::type_has_params(t)); let val = alloca(bcx, llty); return val; diff --git a/src/librustc/middle/trans/build.rs b/src/librustc/middle/trans/build.rs index 0933cf6c8e535..5e5cbc9f97191 100644 --- a/src/librustc/middle/trans/build.rs +++ b/src/librustc/middle/trans/build.rs @@ -178,7 +178,7 @@ pub fn IndirectBr(cx: block, Addr: ValueRef, NumDests: uint) { // lot more efficient) than doing str::as_c_str("", ...) every time. pub fn noname() -> *libc::c_char { unsafe { - const cnull: uint = 0u; + static cnull: uint = 0u; return cast::reinterpret_cast(&ptr::addr_of(&cnull)); } } diff --git a/src/librustc/middle/trans/cabi_x86_64.rs b/src/librustc/middle/trans/cabi_x86_64.rs index f7226812b967a..4d0ad2c19f115 100644 --- a/src/librustc/middle/trans/cabi_x86_64.rs +++ b/src/librustc/middle/trans/cabi_x86_64.rs @@ -41,10 +41,10 @@ enum x86_64_reg_class { } impl cmp::Eq for x86_64_reg_class { - pure fn eq(&self, other: &x86_64_reg_class) -> bool { + fn eq(&self, other: &x86_64_reg_class) -> bool { ((*self) as uint) == ((*other) as uint) } - pure fn ne(&self, other: &x86_64_reg_class) -> bool { !(*self).eq(other) } + fn ne(&self, other: &x86_64_reg_class) -> bool { !(*self).eq(other) } } fn is_sse(++c: x86_64_reg_class) -> bool { diff --git a/src/librustc/middle/trans/callee.rs b/src/librustc/middle/trans/callee.rs index 14336a203ced4..607d4cff8d6a4 100644 --- a/src/librustc/middle/trans/callee.rs +++ b/src/librustc/middle/trans/callee.rs @@ -492,12 +492,14 @@ pub fn trans_call_inner( } }; - let args_res = trans_args(bcx, llenv, args, fn_expr_ty, - dest, ret_flag, autoref_arg); - bcx = args_res.bcx; - let mut llargs = /*bad*/copy args_res.args; + let llretslot = trans_ret_slot(bcx, fn_expr_ty, dest); + + let mut llargs = ~[]; + llargs.push(llretslot); + llargs.push(llenv); + bcx = trans_args(bcx, args, fn_expr_ty, + ret_flag, autoref_arg, &mut llargs); - let llretslot = args_res.retslot; // Now that the arguments have finished evaluating, we need to revoke // the cleanup for the self argument, if it exists @@ -555,30 +557,12 @@ pub enum CallArgs { ArgVals(&'self [ValueRef]) } -pub struct Args { - bcx: block, - args: ~[ValueRef], - retslot: ValueRef -} - -pub fn trans_args(cx: block, - llenv: ValueRef, - +args: CallArgs, - fn_ty: ty::t, - dest: expr::Dest, - ret_flag: Option, - +autoref_arg: AutorefArg) -> Args { - let _icx = cx.insn_ctxt("trans_args"); - let mut temp_cleanups = ~[]; - let arg_tys = ty::ty_fn_args(fn_ty); - let mut llargs: ~[ValueRef] = ~[]; - - let mut bcx = cx; - +pub fn trans_ret_slot(+bcx: block, + +fn_ty: ty::t, + +dest: expr::Dest) -> ValueRef +{ let retty = ty::ty_fn_ret(fn_ty); - - // Arg 0: Output pointer. - let llretslot = match dest { + match dest { expr::SaveIn(dst) => dst, expr::Ignore => { if ty::type_is_nil(retty) { @@ -589,13 +573,21 @@ pub fn trans_args(cx: block, alloc_ty(bcx, retty) } } - }; - llargs.push(llretslot); + } +} - // Arg 1: Env (closure-bindings / self value) - llargs.push(llenv); +pub fn trans_args(+cx: block, + +args: CallArgs, + +fn_ty: ty::t, + +ret_flag: Option, + +autoref_arg: AutorefArg, + +llargs: &mut ~[ValueRef]) -> block +{ + let _icx = cx.insn_ctxt("trans_args"); + let mut temp_cleanups = ~[]; + let arg_tys = ty::ty_fn_args(fn_ty); - // ... then explicit args. + let mut bcx = cx; // First we figure out the caller's view of the types of the arguments. // This will be needed if this is a generic call, because the callee has @@ -624,7 +616,7 @@ pub fn trans_args(cx: block, revoke_clean(bcx, *c) } - Args { bcx: bcx, args: llargs, retslot: llretslot } + return bcx; } pub enum AutorefArg { diff --git a/src/librustc/middle/trans/common.rs b/src/librustc/middle/trans/common.rs index 8c95ee4fd9635..0b7d6f5c39bfe 100644 --- a/src/librustc/middle/trans/common.rs +++ b/src/librustc/middle/trans/common.rs @@ -76,8 +76,8 @@ pub type addrspace = c_uint; // 0 is ignored by the GC, and is used for all non-GC'd pointers. // 1 is for opaque GC'd boxes. // >= 2 are for specific types (e.g. resources). -pub const default_addrspace: addrspace = 0; -pub const gc_box_addrspace: addrspace = 1; +pub static default_addrspace: addrspace = 0; +pub static gc_box_addrspace: addrspace = 1; pub type addrspace_gen = @fn() -> addrspace; pub fn new_addrspace_gen() -> addrspace_gen { @@ -335,14 +335,14 @@ pub fn warn_not_to_commit(ccx: @CrateContext, msg: &str) { } // Heap selectors. Indicate which heap something should go on. -#[deriving_eq] +#[deriving(Eq)] pub enum heap { heap_managed, heap_managed_unique, heap_exchange, } -#[deriving_eq] +#[deriving(Eq)] pub enum cleantype { normal_exit_only, normal_exit_and_unwind @@ -615,7 +615,7 @@ pub fn mk_block(llbb: BasicBlockRef, parent: Option, +kind: block_kind, } // First two args are retptr, env -pub const first_real_arg: uint = 2u; +pub static first_real_arg: uint = 2u; pub struct Result { bcx: block, @@ -678,9 +678,9 @@ pub fn block_parent(cx: block) -> block { // Accessors pub impl block_ { - pure fn ccx(@mut self) -> @CrateContext { *self.fcx.ccx } - pure fn tcx(@mut self) -> ty::ctxt { self.fcx.ccx.tcx } - pure fn sess(@mut self) -> Session { self.fcx.ccx.sess } + fn ccx(@mut self) -> @CrateContext { *self.fcx.ccx } + fn tcx(@mut self) -> ty::ctxt { self.fcx.ccx.tcx } + fn sess(@mut self) -> Session { self.fcx.ccx.sess } fn node_id_to_str(@mut self, id: ast::node_id) -> ~str { ast_map::node_id_to_str(self.tcx().items, id, self.sess().intr()) @@ -1270,7 +1270,7 @@ pub fn is_undef(val: ValueRef) -> bool { } // Used to identify cached monomorphized functions and vtables -#[deriving_eq] +#[deriving(Eq)] pub enum mono_param_id { mono_precise(ty::t, Option<~[mono_id]>), mono_any, @@ -1280,7 +1280,7 @@ pub enum mono_param_id { datum::DatumMode), } -#[deriving_eq] +#[deriving(Eq)] pub struct mono_id_ { def: ast::def_id, params: ~[mono_param_id], @@ -1290,7 +1290,7 @@ pub struct mono_id_ { pub type mono_id = @mono_id_; impl to_bytes::IterBytes for mono_param_id { - pure fn iter_bytes(&self, +lsb0: bool, f: to_bytes::Cb) { + fn iter_bytes(&self, +lsb0: bool, f: to_bytes::Cb) { match *self { mono_precise(t, ref mids) => to_bytes::iter_bytes_3(&0u8, &ty::type_id(t), mids, lsb0, f), @@ -1304,7 +1304,7 @@ impl to_bytes::IterBytes for mono_param_id { } impl to_bytes::IterBytes for mono_id_ { - pure fn iter_bytes(&self, +lsb0: bool, f: to_bytes::Cb) { + fn iter_bytes(&self, +lsb0: bool, f: to_bytes::Cb) { to_bytes::iter_bytes_2(&self.def, &self.params, lsb0, f); } } @@ -1430,7 +1430,7 @@ pub fn find_vtable(tcx: ty::ctxt, ps: ¶m_substs, // Vtables are stored in a flat array, finding the right one is // somewhat awkward - let first_n_bounds = ps.bounds.view(0, n_param); + let first_n_bounds = ps.bounds.slice(0, n_param); let vtables_to_skip = ty::count_traits_and_supertraits(tcx, first_n_bounds); let vtable_off = vtables_to_skip + n_bound; diff --git a/src/librustc/middle/trans/consts.rs b/src/librustc/middle/trans/consts.rs index b630a9b44e84a..ea34df54462b7 100644 --- a/src/librustc/middle/trans/consts.rs +++ b/src/librustc/middle/trans/consts.rs @@ -28,6 +28,7 @@ use util::ppaux::{expr_repr, ty_to_str}; use core::libc::c_uint; use syntax::{ast, ast_util, codemap, ast_map}; +use util::ppaux::ty_to_str; pub fn const_lit(cx: @CrateContext, e: @ast::expr, lit: ast::lit) -> ValueRef { @@ -45,7 +46,8 @@ pub fn const_lit(cx: @CrateContext, e: @ast::expr, lit: ast::lit) C_integral(T_uint_ty(cx, t), i as u64, False) } _ => cx.sess.span_bug(lit.span, - ~"integer literal doesn't have a type") + fmt!("integer literal has type %s (expected int or uint)", + ty_to_str(cx.tcx, lit_int_ty))) } } ast::lit_float(fs, t) => C_floating(/*bad*/copy *fs, T_float_ty(cx, t)), @@ -177,7 +179,7 @@ pub fn const_expr(cx: @CrateContext, e: @ast::expr) -> ValueRef { llconst = C_struct(~[llconst, C_null(T_opaque_box_ptr(cx))]) } Some(@ty::AutoAddEnv(ref r, ref s)) => { - cx.sess.span_bug(e.span, fmt!("unexpected const function: \ + cx.sess.span_bug(e.span, fmt!("unexpected static function: \ region %? sigil %?", *r, *s)) } Some(@ty::AutoDerefRef(ref adj)) => { diff --git a/src/librustc/middle/trans/datum.rs b/src/librustc/middle/trans/datum.rs index 9b3ec5ef842e6..600f637f72b59 100644 --- a/src/librustc/middle/trans/datum.rs +++ b/src/librustc/middle/trans/datum.rs @@ -110,7 +110,7 @@ use core::uint; use syntax::ast; use syntax::parse::token::special_idents; -#[deriving_eq] +#[deriving(Eq)] pub enum CopyAction { INIT, DROP_EXISTING @@ -158,20 +158,20 @@ pub impl DatumMode { } impl cmp::Eq for DatumMode { - pure fn eq(&self, other: &DatumMode) -> bool { + fn eq(&self, other: &DatumMode) -> bool { (*self) as uint == (*other as uint) } - pure fn ne(&self, other: &DatumMode) -> bool { !(*self).eq(other) } + fn ne(&self, other: &DatumMode) -> bool { !(*self).eq(other) } } impl to_bytes::IterBytes for DatumMode { - pure fn iter_bytes(&self, +lsb0: bool, f: to_bytes::Cb) { + fn iter_bytes(&self, +lsb0: bool, f: to_bytes::Cb) { (*self as uint).iter_bytes(lsb0, f) } } /// See `Datum cleanup styles` section at the head of this module. -#[deriving_eq] +#[deriving(Eq)] pub enum DatumCleanup { RevokeClean, ZeroMem diff --git a/src/librustc/middle/trans/debuginfo.rs b/src/librustc/middle/trans/debuginfo.rs index f74f83e4573f5..505c08fc8b8c1 100644 --- a/src/librustc/middle/trans/debuginfo.rs +++ b/src/librustc/middle/trans/debuginfo.rs @@ -29,32 +29,32 @@ use syntax::codemap::{span, CharPos}; use syntax::parse::token::ident_interner; use syntax::{ast, codemap, ast_util, ast_map}; -const LLVMDebugVersion: int = (9 << 16); - -const DW_LANG_RUST: int = 0x9000; -const DW_VIRTUALITY_none: int = 0; - -const CompileUnitTag: int = 17; -const FileDescriptorTag: int = 41; -const SubprogramTag: int = 46; -const SubroutineTag: int = 21; -const BasicTypeDescriptorTag: int = 36; -const AutoVariableTag: int = 256; -const ArgVariableTag: int = 257; -const ReturnVariableTag: int = 258; -const LexicalBlockTag: int = 11; -const PointerTypeTag: int = 15; -const StructureTypeTag: int = 19; -const MemberTag: int = 13; -const ArrayTypeTag: int = 1; -const SubrangeTag: int = 33; - -const DW_ATE_boolean: int = 0x02; -const DW_ATE_float: int = 0x04; -const DW_ATE_signed: int = 0x05; -const DW_ATE_signed_char: int = 0x06; -const DW_ATE_unsigned: int = 0x07; -const DW_ATE_unsigned_char: int = 0x08; +static LLVMDebugVersion: int = (9 << 16); + +static DW_LANG_RUST: int = 0x9000; +static DW_VIRTUALITY_none: int = 0; + +static CompileUnitTag: int = 17; +static FileDescriptorTag: int = 41; +static SubprogramTag: int = 46; +static SubroutineTag: int = 21; +static BasicTypeDescriptorTag: int = 36; +static AutoVariableTag: int = 256; +static ArgVariableTag: int = 257; +static ReturnVariableTag: int = 258; +static LexicalBlockTag: int = 11; +static PointerTypeTag: int = 15; +static StructureTypeTag: int = 19; +static MemberTag: int = 13; +static ArrayTypeTag: int = 1; +static SubrangeTag: int = 33; + +static DW_ATE_boolean: int = 0x02; +static DW_ATE_float: int = 0x04; +static DW_ATE_signed: int = 0x05; +static DW_ATE_signed_char: int = 0x06; +static DW_ATE_unsigned: int = 0x07; +static DW_ATE_unsigned_char: int = 0x08; fn llstr(s: &str) -> ValueRef { do str::as_c_str(s) |sbuf| { @@ -251,10 +251,10 @@ fn get_cache(cx: @CrateContext) -> metadata_cache { fn get_file_path_and_dir(work_dir: &str, full_path: &str) -> (~str, ~str) { (if str::starts_with(full_path, work_dir) { str::slice(full_path, str::len(work_dir) + 1u, - str::len(full_path)) + str::len(full_path)).to_owned() } else { - str::from_slice(full_path) - }, str::from_slice(work_dir)) + full_path.to_owned() + }, work_dir.to_owned()) } fn create_file(cx: @CrateContext, +full_path: ~str) diff --git a/src/librustc/middle/trans/expr.rs b/src/librustc/middle/trans/expr.rs index fb63f5384fb7a..7cfa1ff49292a 100644 --- a/src/librustc/middle/trans/expr.rs +++ b/src/librustc/middle/trans/expr.rs @@ -175,7 +175,7 @@ pub impl Dest { } impl cmp::Eq for Dest { - pure fn eq(&self, other: &Dest) -> bool { + fn eq(&self, other: &Dest) -> bool { match ((*self), (*other)) { (SaveIn(e0a), SaveIn(e0b)) => e0a == e0b, (Ignore, Ignore) => true, @@ -183,7 +183,7 @@ impl cmp::Eq for Dest { (Ignore, _) => false, } } - pure fn ne(&self, other: &Dest) -> bool { !(*self).eq(other) } + fn ne(&self, other: &Dest) -> bool { !(*self).eq(other) } } fn drop_and_cancel_clean(bcx: block, dat: Datum) -> block { @@ -1085,15 +1085,6 @@ fn trans_lvalue_unadjusted(bcx: block, expr: @ast::expr) -> DatumBlock { ast::def_const(did) => { let const_ty = expr_ty(bcx, ref_expr); - #[cfg(stage0)] - fn get_did(_ccx: @CrateContext, did: ast::def_id) - -> ast::def_id { - did - } - - #[cfg(stage1)] - #[cfg(stage2)] - #[cfg(stage3)] fn get_did(ccx: @CrateContext, did: ast::def_id) -> ast::def_id { if did.crate != ast::local_crate { @@ -1103,24 +1094,6 @@ fn trans_lvalue_unadjusted(bcx: block, expr: @ast::expr) -> DatumBlock { } } - #[cfg(stage0)] - fn get_val(bcx: block, did: ast::def_id, const_ty: ty::t) - -> ValueRef { - let ccx = bcx.ccx(); - if did.crate == ast::local_crate { - // The LLVM global has the type of its initializer, - // which may not be equal to the enum's type for - // non-C-like enums. - PointerCast(bcx, base::get_item_val(ccx, did.node), - T_ptr(type_of(bcx.ccx(), const_ty))) - } else { - base::trans_external_path(ccx, did, const_ty) - } - } - - #[cfg(stage1)] - #[cfg(stage2)] - #[cfg(stage3)] fn get_val(bcx: block, did: ast::def_id, const_ty: ty::t) -> ValueRef { // The LLVM global has the type of its initializer, @@ -1722,7 +1695,7 @@ pub enum cast_kind { } impl cmp::Eq for cast_kind { - pure fn eq(&self, other: &cast_kind) -> bool { + fn eq(&self, other: &cast_kind) -> bool { match ((*self), (*other)) { (cast_pointer, cast_pointer) => true, (cast_integral, cast_integral) => true, @@ -1736,7 +1709,7 @@ impl cmp::Eq for cast_kind { (cast_other, _) => false, } } - pure fn ne(&self, other: &cast_kind) -> bool { !(*self).eq(other) } + fn ne(&self, other: &cast_kind) -> bool { !(*self).eq(other) } } pub fn cast_type_kind(t: ty::t) -> cast_kind { @@ -1849,6 +1822,7 @@ fn trans_assign_op(bcx: block, return result_datum.copy_to_datum(bcx, DROP_EXISTING, dst_datum); } +// NOTE: Mode neccessary here? fn shorten(+x: ~str) -> ~str { - if x.len() > 60 { x.substr(0, 60) } else { x } + if x.len() > 60 { x.substr(0, 60).to_owned() } else { x } } diff --git a/src/librustc/middle/trans/glue.rs b/src/librustc/middle/trans/glue.rs index 2352ada8cedb3..bf5a699ed8237 100644 --- a/src/librustc/middle/trans/glue.rs +++ b/src/librustc/middle/trans/glue.rs @@ -218,8 +218,8 @@ pub fn simplified_glue_type(tcx: ty::ctxt, field: uint, t: ty::t) -> ty::t { return t; } -pub pure fn cast_glue(ccx: @CrateContext, ti: @mut tydesc_info, v: ValueRef) - -> ValueRef { +pub fn cast_glue(ccx: @CrateContext, ti: @mut tydesc_info, v: ValueRef) + -> ValueRef { unsafe { let llfnty = type_of_glue_fn(ccx, ti.ty); llvm::LLVMConstPointerCast(v, T_ptr(llfnty)) diff --git a/src/librustc/middle/trans/meth.rs b/src/librustc/middle/trans/meth.rs index 205acedb9e1c2..ce6f6c8efa702 100644 --- a/src/librustc/middle/trans/meth.rs +++ b/src/librustc/middle/trans/meth.rs @@ -282,7 +282,7 @@ pub fn trans_static_method_callee(bcx: block, // When we translate a static fn defined in a trait like: // // trait Trait { - // static fn foo(...) {...} + // fn foo(...) {...} // } // // this winds up being translated as something like: diff --git a/src/librustc/middle/trans/tvec.rs b/src/librustc/middle/trans/tvec.rs index 586b29c19c90c..90f6bf8757865 100644 --- a/src/librustc/middle/trans/tvec.rs +++ b/src/librustc/middle/trans/tvec.rs @@ -27,6 +27,7 @@ use middle::ty; use util::common::indenter; use util::ppaux::ty_to_str; +use core::option::None; use core::uint; use core::vec; use syntax::ast; @@ -413,30 +414,57 @@ pub fn write_content(bcx: block, return bcx; } - let tmpdatum = unpack_datum!(bcx, { + // Some cleanup would be required in the case in which failure happens + // during a copy. But given that copy constructors are not overridable, + // this can only happen as a result of OOM. So we just skip out on the + // cleanup since things would *probably* be broken at that point anyways. + + let elem = unpack_datum!(bcx, { expr::trans_to_datum(bcx, element) }); - let mut temp_cleanups = ~[]; + let next_bcx = sub_block(bcx, ~"expr_repeat: while next"); + let loop_bcx = loop_scope_block(bcx, next_bcx, None, ~"expr_repeat", None); + let cond_bcx = scope_block(loop_bcx, None, ~"expr_repeat: loop cond"); + let set_bcx = scope_block(loop_bcx, None, ~"expr_repeat: body: set"); + let inc_bcx = scope_block(loop_bcx, None, ~"expr_repeat: body: inc"); + Br(bcx, loop_bcx.llbb); - for uint::range(0, count) |i| { - let lleltptr = GEPi(bcx, lldest, [i]); - if i < count - 1 { - // Copy all but the last one in. - bcx = tmpdatum.copy_to(bcx, INIT, lleltptr); - } else { - // Move the last one in. - bcx = tmpdatum.move_to(bcx, INIT, lleltptr); - } - add_clean_temp_mem(bcx, lleltptr, vt.unit_ty); - temp_cleanups.push(lleltptr); + let loop_counter = { + // i = 0 + let i = alloca(loop_bcx, bcx.ccx().int_type); + Store(loop_bcx, C_uint(bcx.ccx(), 0), i); + + Br(loop_bcx, cond_bcx.llbb); + i + }; + + { // i < count + let lhs = Load(cond_bcx, loop_counter); + let rhs = C_uint(bcx.ccx(), count); + let cond_val = ICmp(cond_bcx, lib::llvm::IntULT, lhs, rhs); + + CondBr(cond_bcx, cond_val, set_bcx.llbb, next_bcx.llbb); } - for vec::each(temp_cleanups) |cleanup| { - revoke_clean(bcx, *cleanup); + { // v[i] = elem + let i = Load(set_bcx, loop_counter); + let lleltptr = InBoundsGEP(set_bcx, lldest, [i]); + let set_bcx = elem.copy_to(set_bcx, INIT, lleltptr); + + Br(set_bcx, inc_bcx.llbb); } - return bcx; + { // i += 1 + let i = Load(inc_bcx, loop_counter); + let plusone = Add(inc_bcx, i, C_uint(bcx.ccx(), 1)); + Store(inc_bcx, plusone, loop_counter); + + Br(inc_bcx, cond_bcx.llbb); + } + + return next_bcx; + } } } diff --git a/src/librustc/middle/trans/type_use.rs b/src/librustc/middle/trans/type_use.rs index 77e10b2fbda64..45cf790ccee20 100644 --- a/src/librustc/middle/trans/type_use.rs +++ b/src/librustc/middle/trans/type_use.rs @@ -47,9 +47,9 @@ use syntax::ast_util; use syntax::visit; pub type type_uses = uint; // Bitmask -pub const use_repr: uint = 1u; /* Dependency on size/alignment/mode and - take/drop glue */ -pub const use_tydesc: uint = 2u; /* Takes the tydesc, or compares */ +pub static use_repr: uint = 1u; /* Dependency on size/alignment/mode and + take/drop glue */ +pub static use_tydesc: uint = 2u; /* Takes the tydesc, or compares */ pub struct Context { ccx: @CrateContext, diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs index e50fd7b10cc4d..44245e0b4e1f8 100644 --- a/src/librustc/middle/ty.rs +++ b/src/librustc/middle/ty.rs @@ -54,13 +54,13 @@ use syntax; // Note: after typeck, you should use resolved_mode() to convert this mode // into an rmode, which will take into account the results of mode inference. -#[deriving_eq] +#[deriving(Eq)] pub struct arg { mode: ast::mode, ty: t } -#[deriving_eq] +#[deriving(Eq)] pub struct field { ident: ast::ident, mt: mt @@ -84,7 +84,7 @@ pub struct mt { #[auto_encode] #[auto_decode] -#[deriving_eq] +#[deriving(Eq)] pub enum vstore { vstore_fixed(uint), vstore_uniq, @@ -94,7 +94,7 @@ pub enum vstore { #[auto_encode] #[auto_decode] -#[deriving_eq] +#[deriving(Eq)] pub enum TraitStore { BareTraitStore, // a plain trait without a sigil BoxTraitStore, // @Trait @@ -111,7 +111,7 @@ pub struct field_ty { // Contains information needed to resolve types and (in the future) look up // the types of AST nodes. -#[deriving_eq] +#[deriving(Eq)] pub struct creader_cache_key { cnum: int, pos: uint, @@ -121,7 +121,7 @@ pub struct creader_cache_key { type creader_cache = HashMap; impl to_bytes::IterBytes for creader_cache_key { - pure fn iter_bytes(&self, +lsb0: bool, f: to_bytes::Cb) { + fn iter_bytes(&self, +lsb0: bool, f: to_bytes::Cb) { to_bytes::iter_bytes_3(&self.cnum, &self.pos, &self.len, lsb0, f); } } @@ -131,22 +131,22 @@ struct intern_key { o_def_id: Option } -// NB: Do not replace this with #[deriving_eq]. The automatically-derived +// NB: Do not replace this with #[deriving(Eq)]. The automatically-derived // implementation will not recurse through sty and you will get stack // exhaustion. impl cmp::Eq for intern_key { - pure fn eq(&self, other: &intern_key) -> bool { + fn eq(&self, other: &intern_key) -> bool { unsafe { *self.sty == *other.sty && self.o_def_id == other.o_def_id } } - pure fn ne(&self, other: &intern_key) -> bool { + fn ne(&self, other: &intern_key) -> bool { !self.eq(other) } } impl to_bytes::IterBytes for intern_key { - pure fn iter_bytes(&self, +lsb0: bool, f: to_bytes::Cb) { + fn iter_bytes(&self, +lsb0: bool, f: to_bytes::Cb) { unsafe { to_bytes::iter_bytes_2(&*self.sty, &self.o_def_id, lsb0, f); } @@ -165,7 +165,7 @@ pub type opt_region_variance = Option; pub enum region_variance { rv_covariant, rv_invariant, rv_contravariant } impl cmp::Eq for region_variance { - pure fn eq(&self, other: ®ion_variance) -> bool { + fn eq(&self, other: ®ion_variance) -> bool { match ((*self), (*other)) { (rv_covariant, rv_covariant) => true, (rv_invariant, rv_invariant) => true, @@ -175,7 +175,7 @@ impl cmp::Eq for region_variance { (rv_contravariant, _) => false } } - pure fn ne(&self, other: ®ion_variance) -> bool { !(*self).eq(other) } + fn ne(&self, other: ®ion_variance) -> bool { !(*self).eq(other) } } #[auto_encode] @@ -310,6 +310,7 @@ enum tbox_flag { needs_infer = 4, has_regions = 8, has_ty_err = 16, + has_ty_bot = 32, // a meta-flag: subst may be required if the type has parameters, a self // type, or references bound regions @@ -333,7 +334,7 @@ struct t_box_ { enum t_opaque {} pub type t = *t_opaque; -pub pure fn get(t: t) -> t_box { +pub fn get(t: t) -> t_box { unsafe { let t2 = cast::reinterpret_cast::(&t); let t3 = t2; @@ -342,33 +343,30 @@ pub pure fn get(t: t) -> t_box { } } -pub pure fn tbox_has_flag(tb: t_box, flag: tbox_flag) -> bool { +pub fn tbox_has_flag(tb: t_box, flag: tbox_flag) -> bool { (tb.flags & (flag as uint)) != 0u } -pub pure fn type_has_params(t: t) -> bool { +pub fn type_has_params(t: t) -> bool { tbox_has_flag(get(t), has_params) } -pub pure fn type_has_self(t: t) -> bool { tbox_has_flag(get(t), has_self) } -pub pure fn type_needs_infer(t: t) -> bool { +pub fn type_has_self(t: t) -> bool { tbox_has_flag(get(t), has_self) } +pub fn type_needs_infer(t: t) -> bool { tbox_has_flag(get(t), needs_infer) } -pub pure fn type_has_regions(t: t) -> bool { +pub fn type_has_regions(t: t) -> bool { tbox_has_flag(get(t), has_regions) } -pub pure fn type_contains_err(t: t) -> bool { - tbox_has_flag(get(t), has_ty_err) -} -pub pure fn type_def_id(t: t) -> Option { get(t).o_def_id } -pub pure fn type_id(t: t) -> uint { get(t).id } +pub fn type_def_id(t: t) -> Option { get(t).o_def_id } +pub fn type_id(t: t) -> uint { get(t).id } -#[deriving_eq] +#[deriving(Eq)] pub struct BareFnTy { purity: ast::purity, abi: Abi, sig: FnSig } -#[deriving_eq] +#[deriving(Eq)] pub struct ClosureTy { purity: ast::purity, sigil: ast::Sigil, @@ -383,33 +381,33 @@ pub struct ClosureTy { * * - `inputs` is the list of arguments and their modes. * - `output` is the return type. */ -#[deriving_eq] +#[deriving(Eq)] pub struct FnSig { inputs: ~[arg], output: t } impl to_bytes::IterBytes for BareFnTy { - pure fn iter_bytes(&self, +lsb0: bool, f: to_bytes::Cb) { + fn iter_bytes(&self, +lsb0: bool, f: to_bytes::Cb) { to_bytes::iter_bytes_3(&self.purity, &self.abi, &self.sig, lsb0, f) } } impl to_bytes::IterBytes for ClosureTy { - pure fn iter_bytes(&self, +lsb0: bool, f: to_bytes::Cb) { + fn iter_bytes(&self, +lsb0: bool, f: to_bytes::Cb) { to_bytes::iter_bytes_5(&self.purity, &self.sigil, &self.onceness, &self.region, &self.sig, lsb0, f) } } -#[deriving_eq] +#[deriving(Eq)] pub struct param_ty { idx: uint, def_id: def_id } impl to_bytes::IterBytes for param_ty { - pure fn iter_bytes(&self, +lsb0: bool, f: to_bytes::Cb) { + fn iter_bytes(&self, +lsb0: bool, f: to_bytes::Cb) { to_bytes::iter_bytes_2(&self.idx, &self.def_id, lsb0, f) } } @@ -491,7 +489,7 @@ type opt_region = Option; * - `self_ty` is the type to which `self` should be remapped, if any. The * `self` type is rather funny in that it can only appear on traits and is * always substituted away to the implementing type for a trait. */ -#[deriving_eq] +#[deriving(Eq)] pub struct substs { self_r: opt_region, self_ty: Option, @@ -500,7 +498,7 @@ pub struct substs { // NB: If you change this, you'll probably want to change the corresponding // AST structure in libsyntax/ast.rs as well. -#[deriving_eq] +#[deriving(Eq)] pub enum sty { ty_nil, ty_bot, @@ -537,7 +535,7 @@ pub enum sty { ty_unboxed_vec(mt), } -#[deriving_eq] +#[deriving(Eq)] pub enum IntVarValue { IntType(ast::int_ty), UintType(ast::uint_ty), @@ -594,23 +592,23 @@ pub enum param_bound { bound_trait(t), } -#[deriving_eq] +#[deriving(Eq)] pub struct TyVid(uint); -#[deriving_eq] +#[deriving(Eq)] pub struct IntVid(uint); -#[deriving_eq] +#[deriving(Eq)] pub struct FloatVid(uint); -#[deriving_eq] +#[deriving(Eq)] #[auto_encode] #[auto_decode] pub struct RegionVid { id: uint } -#[deriving_eq] +#[deriving(Eq)] pub enum InferTy { TyVar(TyVid), IntVar(IntVid), @@ -618,7 +616,7 @@ pub enum InferTy { } impl to_bytes::IterBytes for InferTy { - pure fn iter_bytes(&self, +lsb0: bool, f: to_bytes::Cb) { + fn iter_bytes(&self, +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), @@ -635,7 +633,7 @@ pub enum InferRegion { } impl to_bytes::IterBytes for InferRegion { - pure fn iter_bytes(&self, +lsb0: bool, f: to_bytes::Cb) { + fn iter_bytes(&self, +lsb0: bool, f: to_bytes::Cb) { match *self { ReVar(ref rv) => to_bytes::iter_bytes_2(&0u8, rv, lsb0, f), ReSkolemized(ref v, _) => to_bytes::iter_bytes_2(&1u8, v, lsb0, f) @@ -644,7 +642,7 @@ impl to_bytes::IterBytes for InferRegion { } impl cmp::Eq for InferRegion { - pure fn eq(&self, other: &InferRegion) -> bool { + fn eq(&self, other: &InferRegion) -> bool { match ((*self), *other) { (ReVar(rva), ReVar(rvb)) => { rva == rvb @@ -655,13 +653,13 @@ impl cmp::Eq for InferRegion { _ => false } } - pure fn ne(&self, other: &InferRegion) -> bool { + fn ne(&self, other: &InferRegion) -> bool { !((*self) == (*other)) } } impl to_bytes::IterBytes for param_bound { - pure fn iter_bytes(&self, +lsb0: bool, f: to_bytes::Cb) { + fn iter_bytes(&self, +lsb0: bool, f: to_bytes::Cb) { match *self { bound_copy => 0u8.iter_bytes(lsb0, f), bound_durable => 1u8.iter_bytes(lsb0, f), @@ -674,50 +672,50 @@ impl to_bytes::IterBytes for param_bound { } pub trait Vid { - pure fn to_uint(&self) -> uint; + fn to_uint(&self) -> uint; } impl Vid for TyVid { - pure fn to_uint(&self) -> uint { **self } + fn to_uint(&self) -> uint { **self } } impl ToStr for TyVid { - pure fn to_str(&self) -> ~str { fmt!("", self.to_uint()) } + fn to_str(&self) -> ~str { fmt!("", self.to_uint()) } } impl Vid for IntVid { - pure fn to_uint(&self) -> uint { **self } + fn to_uint(&self) -> uint { **self } } impl ToStr for IntVid { - pure fn to_str(&self) -> ~str { fmt!("", self.to_uint()) } + fn to_str(&self) -> ~str { fmt!("", self.to_uint()) } } impl Vid for FloatVid { - pure fn to_uint(&self) -> uint { **self } + fn to_uint(&self) -> uint { **self } } impl ToStr for FloatVid { - pure fn to_str(&self) -> ~str { fmt!("", self.to_uint()) } + fn to_str(&self) -> ~str { fmt!("", self.to_uint()) } } impl Vid for RegionVid { - pure fn to_uint(&self) -> uint { self.id } + fn to_uint(&self) -> uint { self.id } } impl ToStr for RegionVid { - pure fn to_str(&self) -> ~str { fmt!("%?", self.id) } + fn to_str(&self) -> ~str { fmt!("%?", self.id) } } impl ToStr for FnSig { - pure fn to_str(&self) -> ~str { + fn to_str(&self) -> ~str { // grr, without tcx not much we can do. return ~"(...)"; } } impl ToStr for InferTy { - pure fn to_str(&self) -> ~str { + fn to_str(&self) -> ~str { match *self { TyVar(ref v) => v.to_str(), IntVar(ref v) => v.to_str(), @@ -727,7 +725,7 @@ impl ToStr for InferTy { } impl ToStr for IntVarValue { - pure fn to_str(&self) -> ~str { + fn to_str(&self) -> ~str { match *self { IntType(ref v) => v.to_str(), UintType(ref v) => v.to_str(), @@ -736,25 +734,25 @@ impl ToStr for IntVarValue { } impl to_bytes::IterBytes for TyVid { - pure fn iter_bytes(&self, +lsb0: bool, f: to_bytes::Cb) { + fn iter_bytes(&self, +lsb0: bool, f: to_bytes::Cb) { self.to_uint().iter_bytes(lsb0, f) } } impl to_bytes::IterBytes for IntVid { - pure fn iter_bytes(&self, +lsb0: bool, f: to_bytes::Cb) { + fn iter_bytes(&self, +lsb0: bool, f: to_bytes::Cb) { self.to_uint().iter_bytes(lsb0, f) } } impl to_bytes::IterBytes for FloatVid { - pure fn iter_bytes(&self, +lsb0: bool, f: to_bytes::Cb) { + fn iter_bytes(&self, +lsb0: bool, f: to_bytes::Cb) { self.to_uint().iter_bytes(lsb0, f) } } impl to_bytes::IterBytes for RegionVid { - pure fn iter_bytes(&self, +lsb0: bool, f: to_bytes::Cb) { + fn iter_bytes(&self, +lsb0: bool, f: to_bytes::Cb) { self.to_uint().iter_bytes(lsb0, f) } } @@ -892,9 +890,17 @@ fn mk_t_with_id(cx: ctxt, +st: sty, o_def_id: Option) -> t { flags |= rflags(r); flags |= get(mt.ty).flags; } - &ty_nil | &ty_bot | &ty_bool | &ty_int(_) | &ty_float(_) | &ty_uint(_) | + &ty_nil | &ty_bool | &ty_int(_) | &ty_float(_) | &ty_uint(_) | &ty_estr(_) | &ty_type | &ty_opaque_closure_ptr(_) | &ty_opaque_box => (), + // You might think that we could just return ty_err for + // any type containing ty_err as a component, and get + // rid of the has_ty_err flag -- likewise for ty_bot (with + // the exception of function types that return bot). + // But doing so caused sporadic memory corruption, and + // neither I (tjc) nor nmatsakis could figure out why, + // so we're doing it this way. + &ty_bot => flags |= has_ty_bot as uint, &ty_err => flags |= has_ty_err as uint, &ty_param(_) => flags |= has_params as uint, &ty_infer(_) => flags |= needs_infer as uint, @@ -914,12 +920,16 @@ fn mk_t_with_id(cx: ctxt, +st: sty, o_def_id: Option) -> t { &ty_tup(ref ts) => for ts.each |tt| { flags |= get(*tt).flags; }, &ty_bare_fn(ref f) => { for f.sig.inputs.each |a| { flags |= get(a.ty).flags; } - flags |= get(f.sig.output).flags; + flags |= get(f.sig.output).flags; + // T -> _|_ is *not* _|_ ! + flags &= !(has_ty_bot as uint); } &ty_closure(ref f) => { flags |= rflags(f.region); for f.sig.inputs.each |a| { flags |= get(a.ty).flags; } flags |= get(f.sig.output).flags; + // T -> _|_ is *not* _|_ ! + flags &= !(has_ty_bot as uint); } } @@ -1102,7 +1112,7 @@ pub fn mk_with_id(cx: ctxt, base: t, def_id: ast::def_id) -> t { } // Converts s to its machine type equivalent -pub pure fn mach_sty(cfg: @session::config, t: t) -> sty { +pub fn mach_sty(cfg: @session::config, t: t) -> sty { match get(t).sty { ty_int(ast::ty_i) => ty_int(cfg.int_type), ty_uint(ast::ty_u) => ty_uint(cfg.uint_type), @@ -1394,7 +1404,7 @@ pub fn substs_to_str(cx: ctxt, substs: &substs) -> ~str { pub fn param_bound_to_str(cx: ctxt, pb: ¶m_bound) -> ~str { match *pb { bound_copy => ~"copy", - bound_durable => ~"&static", + bound_durable => ~"'static", bound_owned => ~"owned", bound_const => ~"const", bound_trait(t) => ::util::ppaux::ty_to_str(cx, t) @@ -1465,7 +1475,13 @@ pub fn subst_substs(cx: ctxt, sup: &substs, sub: &substs) -> substs { pub fn type_is_nil(ty: t) -> bool { get(ty).sty == ty_nil } -pub fn type_is_bot(ty: t) -> bool { get(ty).sty == ty_bot } +pub fn type_is_bot(ty: t) -> bool { + (get(ty).flags & (has_ty_bot as uint)) != 0 +} + +pub fn type_is_error(ty: t) -> bool { + (get(ty).flags & (has_ty_err as uint)) != 0 +} pub fn type_is_ty_var(ty: t) -> bool { match get(ty).sty { @@ -1516,14 +1532,14 @@ pub fn get_element_type(ty: t, i: uint) -> t { } } -pub pure fn type_is_box(ty: t) -> bool { +pub fn type_is_box(ty: t) -> bool { match get(ty).sty { ty_box(_) => return true, _ => return false } } -pub pure fn type_is_boxed(ty: t) -> bool { +pub fn type_is_boxed(ty: t) -> bool { match get(ty).sty { ty_box(_) | ty_opaque_box | ty_evec(_, vstore_box) | ty_estr(vstore_box) => true, @@ -1531,35 +1547,35 @@ pub pure fn type_is_boxed(ty: t) -> bool { } } -pub pure fn type_is_region_ptr(ty: t) -> bool { +pub fn type_is_region_ptr(ty: t) -> bool { match get(ty).sty { ty_rptr(_, _) => true, _ => false } } -pub pure fn type_is_slice(ty: t) -> bool { +pub fn type_is_slice(ty: t) -> bool { match get(ty).sty { ty_evec(_, vstore_slice(_)) | ty_estr(vstore_slice(_)) => true, _ => return false } } -pub pure fn type_is_unique_box(ty: t) -> bool { +pub fn type_is_unique_box(ty: t) -> bool { match get(ty).sty { ty_uniq(_) => return true, _ => return false } } -pub pure fn type_is_unsafe_ptr(ty: t) -> bool { +pub fn type_is_unsafe_ptr(ty: t) -> bool { match get(ty).sty { ty_ptr(_) => return true, _ => return false } } -pub pure fn type_is_vec(ty: t) -> bool { +pub fn type_is_vec(ty: t) -> bool { return match get(ty).sty { ty_evec(_, _) | ty_unboxed_vec(_) => true, ty_estr(_) => true, @@ -1567,7 +1583,7 @@ pub pure fn type_is_vec(ty: t) -> bool { }; } -pub pure fn type_is_unique(ty: t) -> bool { +pub fn type_is_unique(ty: t) -> bool { match get(ty).sty { ty_uniq(_) | ty_evec(_, vstore_uniq) | @@ -1582,7 +1598,7 @@ pub pure fn type_is_unique(ty: t) -> bool { (A ty_ptr is scalar because it represents a non-managed pointer, so its contents are abstract to rustc.) */ -pub pure fn type_is_scalar(ty: t) -> bool { +pub fn type_is_scalar(ty: t) -> bool { match get(ty).sty { ty_nil | ty_bool | ty_int(_) | ty_float(_) | ty_uint(_) | ty_infer(IntVar(_)) | ty_infer(FloatVar(_)) | ty_type | @@ -1704,7 +1720,7 @@ pub impl TypeContents { !self.intersects(TypeContents::noncopyable(cx)) } - static fn noncopyable(_cx: ctxt) -> TypeContents { + fn noncopyable(_cx: ctxt) -> TypeContents { TC_DTOR + TC_BORROWED_MUT + TC_ONCE_CLOSURE + TC_OWNED_CLOSURE + TC_EMPTY_ENUM } @@ -1713,7 +1729,7 @@ pub impl TypeContents { !self.intersects(TypeContents::nondurable(cx)) } - static fn nondurable(_cx: ctxt) -> TypeContents { + fn nondurable(_cx: ctxt) -> TypeContents { TC_BORROWED_POINTER } @@ -1721,7 +1737,7 @@ pub impl TypeContents { !self.intersects(TypeContents::nonowned(cx)) } - static fn nonowned(_cx: ctxt) -> TypeContents { + fn nonowned(_cx: ctxt) -> TypeContents { TC_MANAGED + TC_BORROWED_POINTER } @@ -1733,7 +1749,7 @@ pub impl TypeContents { !self.intersects(TypeContents::nonconst(cx)) } - static fn nonconst(_cx: ctxt) -> TypeContents { + fn nonconst(_cx: ctxt) -> TypeContents { TC_MUTABLE } @@ -1741,7 +1757,7 @@ pub impl TypeContents { self.intersects(TypeContents::nonimplicitly_copyable(cx)) } - static fn nonimplicitly_copyable(cx: ctxt) -> TypeContents { + fn nonimplicitly_copyable(cx: ctxt) -> TypeContents { let base = TypeContents::noncopyable(cx) + TC_OWNED_POINTER; if cx.vecs_implicitly_copyable {base} else {base + TC_OWNED_VEC} } @@ -1750,7 +1766,7 @@ pub impl TypeContents { !self.intersects(TypeContents::nondefault_mode(cx)) } - static fn nondefault_mode(cx: ctxt) -> TypeContents { + fn nondefault_mode(cx: ctxt) -> TypeContents { let tc = TypeContents::nonimplicitly_copyable(cx); tc + TC_BIG + TC_OWNED_VEC // disregard cx.vecs_implicitly_copyable } @@ -1760,68 +1776,68 @@ pub impl TypeContents { self.intersects(tc) } - static fn owned(&self, _cx: ctxt) -> TypeContents { + fn owned(_cx: ctxt) -> TypeContents { //! Any kind of owned contents. TC_OWNED_CLOSURE + TC_OWNED_POINTER + TC_OWNED_VEC } } impl ops::Add for TypeContents { - pure fn add(&self, other: &TypeContents) -> TypeContents { + fn add(&self, other: &TypeContents) -> TypeContents { TypeContents {bits: self.bits | other.bits} } } impl ops::Sub for TypeContents { - pure fn sub(&self, other: &TypeContents) -> TypeContents { + fn sub(&self, other: &TypeContents) -> TypeContents { TypeContents {bits: self.bits & !other.bits} } } impl ToStr for TypeContents { - pure fn to_str(&self) -> ~str { + fn to_str(&self) -> ~str { fmt!("TypeContents(%s)", u32::to_str_radix(self.bits, 2)) } } /// Constant for a type containing nothing of interest. -const TC_NONE: TypeContents = TypeContents{bits:0b0000_00000000}; +static TC_NONE: TypeContents = TypeContents{bits:0b0000_00000000}; /// Contains a borrowed value with a lifetime other than static -const TC_BORROWED_POINTER: TypeContents = TypeContents{bits:0b0000_00000001}; +static TC_BORROWED_POINTER: TypeContents = TypeContents{bits:0b0000_00000001}; /// Contains an owned pointer (~T) but not slice of some kind -const TC_OWNED_POINTER: TypeContents = TypeContents{bits:0b000000000010}; +static TC_OWNED_POINTER: TypeContents = TypeContents{bits:0b000000000010}; /// Contains an owned vector ~[] or owned string ~str -const TC_OWNED_VEC: TypeContents = TypeContents{bits:0b000000000100}; +static TC_OWNED_VEC: TypeContents = TypeContents{bits:0b000000000100}; /// Contains a ~fn() or a ~Trait, which is non-copyable. -const TC_OWNED_CLOSURE: TypeContents = TypeContents{bits:0b000000001000}; +static TC_OWNED_CLOSURE: TypeContents = TypeContents{bits:0b000000001000}; /// Type with a destructor -const TC_DTOR: TypeContents = TypeContents{bits:0b000000010000}; +static TC_DTOR: TypeContents = TypeContents{bits:0b000000010000}; /// Contains a managed value -const TC_MANAGED: TypeContents = TypeContents{bits:0b000000100000}; +static TC_MANAGED: TypeContents = TypeContents{bits:0b000000100000}; /// &mut with any region -const TC_BORROWED_MUT: TypeContents = TypeContents{bits:0b000001000000}; +static TC_BORROWED_MUT: TypeContents = TypeContents{bits:0b000001000000}; /// Mutable content, whether owned or by ref -const TC_MUTABLE: TypeContents = TypeContents{bits:0b000010000000}; +static TC_MUTABLE: TypeContents = TypeContents{bits:0b000010000000}; /// Mutable content, whether owned or by ref -const TC_ONCE_CLOSURE: TypeContents = TypeContents{bits:0b000100000000}; +static TC_ONCE_CLOSURE: TypeContents = TypeContents{bits:0b000100000000}; /// Something we estimate to be "big" -const TC_BIG: TypeContents = TypeContents{bits:0b001000000000}; +static TC_BIG: TypeContents = TypeContents{bits:0b001000000000}; /// An enum with no variants. -const TC_EMPTY_ENUM: TypeContents = TypeContents{bits:0b010000000000}; +static TC_EMPTY_ENUM: TypeContents = TypeContents{bits:0b010000000000}; /// All possible contents. -const TC_ALL: TypeContents = TypeContents{bits:0b011111111111}; +static TC_ALL: TypeContents = TypeContents{bits:0b011111111111}; pub fn type_is_copyable(cx: ctxt, t: ty::t) -> bool { type_contents(cx, t).is_copy(cx) @@ -2518,7 +2534,7 @@ pub fn index_sty(cx: ctxt, sty: &sty) -> Option { } impl to_bytes::IterBytes for bound_region { - pure fn iter_bytes(&self, +lsb0: bool, f: to_bytes::Cb) { + fn iter_bytes(&self, +lsb0: bool, f: to_bytes::Cb) { match *self { ty::br_self => 0u8.iter_bytes(lsb0, f), @@ -2538,7 +2554,7 @@ impl to_bytes::IterBytes for bound_region { } impl to_bytes::IterBytes for Region { - pure fn iter_bytes(&self, +lsb0: bool, f: to_bytes::Cb) { + fn iter_bytes(&self, +lsb0: bool, f: to_bytes::Cb) { match *self { re_bound(ref br) => to_bytes::iter_bytes_2(&0u8, br, lsb0, f), @@ -2558,7 +2574,7 @@ impl to_bytes::IterBytes for Region { } impl to_bytes::IterBytes for vstore { - pure fn iter_bytes(&self, +lsb0: bool, f: to_bytes::Cb) { + fn iter_bytes(&self, +lsb0: bool, f: to_bytes::Cb) { match *self { vstore_fixed(ref u) => to_bytes::iter_bytes_2(&0u8, u, lsb0, f), @@ -2573,7 +2589,7 @@ impl to_bytes::IterBytes for vstore { } impl to_bytes::IterBytes for TraitStore { - pure fn iter_bytes(&self, +lsb0: bool, f: to_bytes::Cb) { + fn iter_bytes(&self, +lsb0: bool, f: to_bytes::Cb) { match *self { BareTraitStore => 0u8.iter_bytes(lsb0, f), UniqTraitStore => 1u8.iter_bytes(lsb0, f), @@ -2584,7 +2600,7 @@ impl to_bytes::IterBytes for TraitStore { } impl to_bytes::IterBytes for substs { - pure fn iter_bytes(&self, +lsb0: bool, f: to_bytes::Cb) { + fn iter_bytes(&self, +lsb0: bool, f: to_bytes::Cb) { to_bytes::iter_bytes_3(&self.self_r, &self.self_ty, &self.tps, lsb0, f) @@ -2592,28 +2608,28 @@ impl to_bytes::IterBytes for substs { } impl to_bytes::IterBytes for mt { - pure fn iter_bytes(&self, +lsb0: bool, f: to_bytes::Cb) { + fn iter_bytes(&self, +lsb0: bool, f: to_bytes::Cb) { to_bytes::iter_bytes_2(&self.ty, &self.mutbl, lsb0, f) } } impl to_bytes::IterBytes for field { - pure fn iter_bytes(&self, +lsb0: bool, f: to_bytes::Cb) { + fn iter_bytes(&self, +lsb0: bool, f: to_bytes::Cb) { to_bytes::iter_bytes_2(&self.ident, &self.mt, lsb0, f) } } impl to_bytes::IterBytes for arg { - pure fn iter_bytes(&self, +lsb0: bool, f: to_bytes::Cb) { + fn iter_bytes(&self, +lsb0: bool, f: to_bytes::Cb) { to_bytes::iter_bytes_2(&self.mode, &self.ty, lsb0, f) } } impl to_bytes::IterBytes for FnSig { - pure fn iter_bytes(&self, +lsb0: bool, f: to_bytes::Cb) { + fn iter_bytes(&self, +lsb0: bool, f: to_bytes::Cb) { to_bytes::iter_bytes_2(&self.inputs, &self.output, lsb0, f); @@ -2621,7 +2637,7 @@ impl to_bytes::IterBytes for FnSig { } impl to_bytes::IterBytes for sty { - pure fn iter_bytes(&self, +lsb0: bool, f: to_bytes::Cb) { + fn iter_bytes(&self, +lsb0: bool, f: to_bytes::Cb) { match *self { ty_nil => 0u8.iter_bytes(lsb0, f), ty_bool => 1u8.iter_bytes(lsb0, f), @@ -2752,7 +2768,7 @@ pub fn ty_fn_purity(fty: t) -> ast::purity { } } -pub pure fn ty_fn_ret(fty: t) -> t { +pub fn ty_fn_ret(fty: t) -> t { match get(fty).sty { ty_bare_fn(ref f) => f.sig.output, ty_closure(ref f) => f.sig.output, @@ -2770,7 +2786,7 @@ pub fn is_fn_ty(fty: t) -> bool { } } -pub pure fn ty_vstore(ty: t) -> vstore { +pub fn ty_vstore(ty: t) -> vstore { match get(ty).sty { ty_evec(_, vstore) => vstore, ty_estr(vstore) => vstore, @@ -2778,13 +2794,18 @@ pub pure fn ty_vstore(ty: t) -> vstore { } } -pub fn ty_region(ty: t) -> Region { +pub fn ty_region(tcx: ctxt, + span: span, + ty: t) -> Region { match get(ty).sty { - ty_rptr(r, _) => r, - ty_evec(_, vstore_slice(r)) => r, - ty_estr(vstore_slice(r)) => r, - ref s => fail!(fmt!("ty_region() invoked on in appropriate ty: %?", - (*s))) + ty_rptr(r, _) => r, + ty_evec(_, vstore_slice(r)) => r, + ty_estr(vstore_slice(r)) => r, + ref s => { + tcx.sess.span_bug( + span, + fmt!("ty_region() invoked on in appropriate ty: %?", s)); + } } } @@ -3700,13 +3721,13 @@ pub enum DtorKind { } pub impl DtorKind { - pure fn is_not_present(&const self) -> bool { + fn is_not_present(&const self) -> bool { match *self { NoDtor => true, _ => false } } - pure fn is_present(&const self) -> bool { + fn is_present(&const self) -> bool { !self.is_not_present() } } @@ -3984,7 +4005,7 @@ pub fn lookup_struct_field(cx: ctxt, } } -pure fn is_public(f: field_ty) -> bool { +fn is_public(f: field_ty) -> bool { // XXX: This is wrong. match f.vis { public | inherited => true, @@ -4060,21 +4081,21 @@ fn struct_item_fields(cx:ctxt, } pub fn is_binopable(_cx: ctxt, ty: t, op: ast::binop) -> bool { - const tycat_other: int = 0; - const tycat_bool: int = 1; - const tycat_int: int = 2; - const tycat_float: int = 3; - const tycat_struct: int = 4; - const tycat_bot: int = 5; - - const opcat_add: int = 0; - const opcat_sub: int = 1; - const opcat_mult: int = 2; - const opcat_shift: int = 3; - const opcat_rel: int = 4; - const opcat_eq: int = 5; - const opcat_bit: int = 6; - const opcat_logic: int = 7; + static tycat_other: int = 0; + static tycat_bool: int = 1; + static tycat_int: int = 2; + static tycat_float: int = 3; + static tycat_struct: int = 4; + static tycat_bot: int = 5; + + static opcat_add: int = 0; + static opcat_sub: int = 1; + static opcat_mult: int = 2; + static opcat_shift: int = 3; + static opcat_rel: int = 4; + static opcat_eq: int = 5; + static opcat_bit: int = 6; + static opcat_logic: int = 7; fn opcat(op: ast::binop) -> int { match op { @@ -4110,8 +4131,8 @@ pub fn is_binopable(_cx: ctxt, ty: t, op: ast::binop) -> bool { } } - const t: bool = true; - const f: bool = false; + static t: bool = true; + static f: bool = false; let tbl = ~[ /*. add, shift, bit @@ -4244,7 +4265,7 @@ pub fn eval_repeat_count(tcx: ctxt, count_expr: @ast::expr) -> uint { } // Determine what purity to check a nested function under -pub pure fn determine_inherited_purity(parent_purity: ast::purity, +pub fn determine_inherited_purity(parent_purity: ast::purity, child_purity: ast::purity, child_sigil: ast::Sigil) -> ast::purity { @@ -4348,14 +4369,14 @@ pub fn get_impl_id(tcx: ctxt, trait_id: def_id, self_ty: t) -> def_id { } impl cmp::Eq for mt { - pure fn eq(&self, other: &mt) -> bool { + fn eq(&self, other: &mt) -> bool { (*self).ty == (*other).ty && (*self).mutbl == (*other).mutbl } - pure fn ne(&self, other: &mt) -> bool { !(*self).eq(other) } + fn ne(&self, other: &mt) -> bool { !(*self).eq(other) } } impl cmp::Eq for Region { - pure fn eq(&self, other: &Region) -> bool { + fn eq(&self, other: &Region) -> bool { match (*self) { re_bound(e0a) => { match (*other) { @@ -4389,11 +4410,11 @@ impl cmp::Eq for Region { } } } - pure fn ne(&self, other: &Region) -> bool { !(*self).eq(other) } + fn ne(&self, other: &Region) -> bool { !(*self).eq(other) } } impl cmp::Eq for bound_region { - pure fn eq(&self, other: &bound_region) -> bool { + fn eq(&self, other: &bound_region) -> bool { match (*self) { br_self => { match (*other) { @@ -4427,11 +4448,11 @@ impl cmp::Eq for bound_region { } } } - pure fn ne(&self, other: &bound_region) -> bool { !(*self).eq(other) } + fn ne(&self, other: &bound_region) -> bool { !(*self).eq(other) } } impl cmp::Eq for param_bound { - pure fn eq(&self, other: ¶m_bound) -> bool { + fn eq(&self, other: ¶m_bound) -> bool { match (*self) { bound_copy => { match (*other) { @@ -4465,7 +4486,7 @@ impl cmp::Eq for param_bound { } } } - pure fn ne(&self, other: ¶m_bound) -> bool { !self.eq(other) } + fn ne(&self, other: ¶m_bound) -> bool { !self.eq(other) } } // Local Variables: diff --git a/src/librustc/middle/typeck/astconv.rs b/src/librustc/middle/typeck/astconv.rs index e259fdaf400e4..c288151308fe4 100644 --- a/src/librustc/middle/typeck/astconv.rs +++ b/src/librustc/middle/typeck/astconv.rs @@ -202,8 +202,8 @@ pub fn ast_path_to_ty( ty_param_substs_and_ty { substs: substs, ty: ty } } -pub const NO_REGIONS: uint = 1; -pub const NO_TPS: uint = 2; +pub static NO_REGIONS: uint = 1; +pub static NO_TPS: uint = 2; // Parses the programmer's textual representation of a type into our // internal notion of a type. `getter` is a function that returns the type diff --git a/src/librustc/middle/typeck/check/_match.rs b/src/librustc/middle/typeck/check/_match.rs index 5e106668fc97e..4ffcd440bcf4a 100644 --- a/src/librustc/middle/typeck/check/_match.rs +++ b/src/librustc/middle/typeck/check/_match.rs @@ -28,12 +28,11 @@ use syntax::print::pprust; pub fn check_match(fcx: @mut FnCtxt, expr: @ast::expr, discrim: @ast::expr, - arms: &[ast::arm]) -> bool { + arms: &[ast::arm]) { let tcx = fcx.ccx.tcx; - let mut bot; let pattern_ty = fcx.infcx().next_ty_var(); - bot = check_expr_has_type(fcx, discrim, pattern_ty); + check_expr_has_type(fcx, discrim, pattern_ty); // Typecheck the patterns first, so that we get types for all the // bindings. @@ -51,19 +50,46 @@ pub fn check_match(fcx: @mut FnCtxt, // Now typecheck the blocks. let mut result_ty = fcx.infcx().next_ty_var(); let mut arm_non_bot = false; + let mut saw_err = false; for arms.each |arm| { + let mut guard_err = false; + let mut guard_bot = false; match arm.guard { - Some(e) => { check_expr_has_type(fcx, e, ty::mk_bool(tcx)); }, + Some(e) => { + check_expr_has_type(fcx, e, ty::mk_bool(tcx)); + let e_ty = fcx.expr_ty(e); + if ty::type_is_error(e_ty) { + guard_err = true; + } + else if ty::type_is_bot(e_ty) { + guard_bot = true; + } + }, None => () } - if !check_block(fcx, &arm.body) { arm_non_bot = true; } + check_block(fcx, &arm.body); let bty = fcx.node_ty(arm.body.node.id); + saw_err = saw_err || ty::type_is_error(bty); + if guard_err { + fcx.write_error(arm.body.node.id); + saw_err = true; + } + else if guard_bot { + fcx.write_bot(arm.body.node.id); + } + else if !ty::type_is_bot(bty) { + arm_non_bot = true; // If the match *may* evaluate to a non-_|_ + // expr, the whole thing is non-_|_ + } demand::suptype(fcx, arm.body.span, result_ty, bty); } - bot |= !arm_non_bot; - if !arm_non_bot { result_ty = ty::mk_bot(tcx); } + if saw_err { + result_ty = ty::mk_err(tcx); + } + else if !arm_non_bot { + result_ty = ty::mk_bot(tcx); + } fcx.write_ty(expr.id, result_ty); - return bot; } pub struct pat_ctxt { @@ -366,6 +392,7 @@ pub fn check_pat(pcx: pat_ctxt, pat: @ast::pat, expected: ty::t) { } fcx.write_ty(pat.id, b_ty); } + ast::pat_enum(*) | ast::pat_ident(*) if pat_is_const(tcx.def_map, pat) => { let const_did = ast_util::def_id_of_def(tcx.def_map.get(&pat.id)); let const_tpt = ty::lookup_item_type(tcx, const_did); diff --git a/src/librustc/middle/typeck/check/method.rs b/src/librustc/middle/typeck/check/method.rs index cb626dc85e0ae..c550e5c71e491 100644 --- a/src/librustc/middle/typeck/check/method.rs +++ b/src/librustc/middle/typeck/check/method.rs @@ -105,13 +105,13 @@ use syntax::ast::{m_const, m_mutbl, m_imm}; use syntax::ast; use syntax::ast_map; -#[deriving_eq] +#[deriving(Eq)] pub enum CheckTraitsFlag { CheckTraitsOnly, CheckTraitsAndInherentMethods, } -#[deriving_eq] +#[deriving(Eq)] pub enum AutoderefReceiverFlag { AutoderefReceiver, DontAutoderefReceiver, @@ -192,8 +192,12 @@ pub enum TransformTypeFlag { TransformTypeForObject, } -pub impl LookupContext/&self { +pub impl<'self> LookupContext<'self> { fn do_lookup(&self, self_ty: ty::t) -> Option { + let mut self_ty = structurally_resolved_type(self.fcx, + self.self_expr.span, + self_ty); + debug!("do_lookup(self_ty=%s, expr=%s, self_expr=%s)", self.ty_to_str(self_ty), expr_repr(self.tcx(), self.expr), diff --git a/src/librustc/middle/typeck/check/mod.rs b/src/librustc/middle/typeck/check/mod.rs index 472e042d12841..12c88ae7198db 100644 --- a/src/librustc/middle/typeck/check/mod.rs +++ b/src/librustc/middle/typeck/check/mod.rs @@ -339,7 +339,7 @@ pub fn check_fn(ccx: @mut CrateCtxt, }; gather_locals(fcx, decl, body, arg_tys, self_info); - check_block(fcx, body); + check_block_with_expected(fcx, body, Some(ret_ty)); // We unify the tail expr's type with the // function result type, if there is a tail expr. @@ -741,6 +741,9 @@ pub impl FnCtxt { fn write_bot(&self, node_id: ast::node_id) { self.write_ty(node_id, ty::mk_bot(self.tcx())); } + fn write_error(@mut self, node_id: ast::node_id) { + self.write_ty(node_id, ty::mk_err(self.tcx())); + } fn to_ty(&self, ast_t: @ast::Ty) -> ty::t { ast_ty_to_ty(self, self, ast_t) @@ -889,6 +892,10 @@ pub impl FnCtxt { e: ty::t, a: ty::t, err: &ty::type_err) { + // Derived error + if ty::type_is_error(e) || ty::type_is_error(a) { + return; + } match self.fn_kind { ForLoop(_) if !ty::type_is_bool(e) && !ty::type_is_nil(a) => self.tcx().sess.span_err(sp, fmt!("A for-loop body must \ @@ -1003,7 +1010,7 @@ pub fn valid_range_bounds(ccx: @mut CrateCtxt, pub fn check_expr_has_type( fcx: @mut FnCtxt, expr: @ast::expr, - expected: ty::t) -> bool { + expected: ty::t) { do check_expr_with_unifier(fcx, expr, Some(expected)) { demand::suptype(fcx, expr.span, expected, fcx.expr_ty(expr)); } @@ -1011,7 +1018,7 @@ pub fn check_expr_has_type( pub fn check_expr_coercable_to_type( fcx: @mut FnCtxt, expr: @ast::expr, - expected: ty::t) -> bool { + expected: ty::t) { do check_expr_with_unifier(fcx, expr, Some(expected)) { demand::coerce(fcx, expr.span, expected, expr) } @@ -1019,17 +1026,17 @@ pub fn check_expr_coercable_to_type( pub fn check_expr_with_hint( fcx: @mut FnCtxt, expr: @ast::expr, - expected: ty::t) -> bool { + expected: ty::t) { check_expr_with_unifier(fcx, expr, Some(expected), || ()) } pub fn check_expr_with_opt_hint( fcx: @mut FnCtxt, expr: @ast::expr, - expected: Option) -> bool { + expected: Option) { check_expr_with_unifier(fcx, expr, expected, || ()) } -pub fn check_expr(fcx: @mut FnCtxt, expr: @ast::expr) -> bool { +pub fn check_expr(fcx: @mut FnCtxt, expr: @ast::expr) { check_expr_with_unifier(fcx, expr, None, || ()) } @@ -1120,10 +1127,20 @@ pub fn break_here() { debug!("break here!"); } +/// Invariant: +/// If an expression has any sub-expressions that result in a type error, +/// inspecting that expression's type with `ty::type_is_error` will return +/// true. Likewise, if an expression is known to diverge, inspecting its +/// type with `ty::type_is_bot` will return true (n.b.: since Rust is +/// strict, _|_ can appear in the type of an expression that does not, +/// itself, diverge: for example, fn() -> _|_.) +/// Note that inspecting a type's structure *directly* may expose the fact +/// that there are actually multiple representations for both `ty_err` and +/// `ty_bot`, so avoid that when err and bot need to be handled differently. pub fn check_expr_with_unifier(fcx: @mut FnCtxt, expr: @ast::expr, expected: Option, - unifier: &fn()) -> bool { + unifier: &fn()) { debug!(">> typechecking %s", fcx.expr_to_str(expr)); // A generic function to factor out common logic from call and @@ -1136,10 +1153,9 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt, callee_expr: @ast::expr, args: &[@ast::expr], sugar: ast::CallSugar, - deref_args: DerefArgs) -> (ty::t, bool) + deref_args: DerefArgs) -> ty::t { let tcx = fcx.ccx.tcx; - let mut bot = false; // Replace all region parameters in the arguments and return // type with fresh region variables. @@ -1164,8 +1180,6 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt, let supplied_arg_count = args.len(); - bot |= ty::type_is_bot(sig.output); - // Grab the argument types, supplying fresh type variables // if the wrong number of arguments were supplied let expected_arg_count = sig.inputs.len(); @@ -1246,6 +1260,7 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt, DoDerefArgs => { match ty::get(formal_ty).sty { ty::ty_rptr(_, mt) => formal_ty = mt.ty, + ty::ty_err => (), _ => { fcx.ccx.tcx.sess.span_bug(arg.span, ~"no ref"); @@ -1255,28 +1270,26 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt, DontDerefArgs => {} } - // mismatch error happens in here - bot |= check_expr_coercable_to_type( + check_expr_coercable_to_type( fcx, *arg, formal_ty); } } } - (ret_ty, bot) + ret_ty } // A generic function for checking assignment expressions fn check_assignment(fcx: @mut FnCtxt, lhs: @ast::expr, rhs: @ast::expr, - id: ast::node_id) - -> bool { - let mut bot = check_expr(fcx, lhs); + id: ast::node_id) { + check_expr(fcx, lhs); let lhs_type = fcx.expr_ty(lhs); - bot |= check_expr_has_type(fcx, rhs, lhs_type); + check_expr_has_type(fcx, rhs, lhs_type); fcx.write_ty(id, ty::mk_nil(fcx.ccx.tcx)); - return bot; + // The callee checks for bot / err, we don't need to } // A generic function for doing all of the checking for call or @@ -1287,20 +1300,16 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt, fn_ty: ty::t, expr: @ast::expr, args: &[@ast::expr], - bot: bool, - sugar: ast::CallSugar) -> bool + sugar: ast::CallSugar) { - let mut bot = bot; // Call the generic checker. - let (ret_ty, b) = check_call_inner(fcx, sp, call_expr_id, + let ret_ty = check_call_inner(fcx, sp, call_expr_id, fn_ty, expr, args, sugar, DontDerefArgs); - bot |= b; - // Pull the return type out of the type of the function. fcx.write_ty(call_expr_id, ret_ty); - return bot; + // Callee checks for bot and err, no need for that } // A generic function for doing all of the checking for call expressions @@ -1309,13 +1318,12 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt, call_expr_id: ast::node_id, f: @ast::expr, args: &[@ast::expr], - sugar: ast::CallSugar) - -> bool { + sugar: ast::CallSugar) { // Index expressions need to be handled separately, to inform them // that they appear in call position. - let mut bot = match f.node { - ast::expr_field(base, field, ref tys) => { - check_field(fcx, f, true, base, field, *tys) + match f.node { + ast::expr_field(ref base, ref field, ref tys) => { + check_field(fcx, f, true, *base, *field, *tys) } _ => check_expr(fcx, f) }; @@ -1326,7 +1334,6 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt, fcx.expr_ty(f), f, args, - bot, sugar) } @@ -1337,9 +1344,9 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt, method_name: ast::ident, args: &[@ast::expr], tps: &[@ast::Ty], - sugar: ast::CallSugar) - -> bool { - let bot = check_expr(fcx, rcvr); + sugar: ast::CallSugar) { + check_expr(fcx, rcvr); + // no need to check for bot/err -- callee does that let expr_t = structurally_resolved_type(fcx, expr.span, fcx.expr_ty(rcvr)); @@ -1371,8 +1378,8 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt, None); // Add error type for the result - fcx.write_ty(expr.id, ty::mk_err(fcx.ccx.tcx)); - fcx.write_ty(expr.callee_id, ty::mk_err(fcx.ccx.tcx)); + fcx.write_error(expr.id); + fcx.write_error(expr.callee_id); } } @@ -1382,50 +1389,33 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt, fcx.node_ty(expr.callee_id), expr, args, - bot, sugar) } - // A generic function for checking for or for-each loops - fn check_for(fcx: @mut FnCtxt, - local: @ast::local, - element_ty: ty::t, - body: &ast::blk, - node_id: ast::node_id) - -> bool { - let local_ty = fcx.local_ty(local.span, local.node.id); - demand::suptype(fcx, local.span, local_ty, element_ty); - let bot = check_decl_local(fcx, local); - check_block_no_value(fcx, body); - fcx.write_nil(node_id); - return bot; - } - // A generic function for checking the then and else in an if // or if-check fn check_then_else(fcx: @mut FnCtxt, thn: &ast::blk, elsopt: Option<@ast::expr>, id: ast::node_id, - _sp: span) - -> bool { - let (if_t, if_bot) = + _sp: span) { + let if_t = match elsopt { Some(els) => { let if_t = fcx.infcx().next_ty_var(); - let thn_bot = check_block(fcx, thn); + check_block(fcx, thn); let thn_t = fcx.node_ty(thn.node.id); demand::suptype(fcx, thn.span, if_t, thn_t); - let els_bot = check_expr_has_type(fcx, els, if_t); - (if_t, thn_bot & els_bot) + check_expr_has_type(fcx, els, if_t); + if_t } None => { check_block_no_value(fcx, thn); - (ty::mk_nil(fcx.ccx.tcx), false) + ty::mk_nil(fcx.ccx.tcx) } }; + fcx.write_ty(id, if_t); - return if_bot; } fn lookup_op_method(fcx: @mut FnCtxt, @@ -1435,32 +1425,34 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt, opname: ast::ident, +args: ~[@ast::expr], +deref_args: DerefArgs, - +autoderef_receiver: AutoderefReceiverFlag) - -> Option<(ty::t, bool)> { - match method::lookup(fcx, - op_ex, - self_ex, - op_ex.callee_id, - opname, - self_t, - ~[], - deref_args, - CheckTraitsOnly, - autoderef_receiver) { - Some(ref origin) => { - let method_ty = fcx.node_ty(op_ex.callee_id); - let method_map = fcx.ccx.method_map; - method_map.insert(op_ex.id, *origin); - Some(check_call_inner(fcx, - op_ex.span, - op_ex.id, - method_ty, - op_ex, - args, - ast::NoSugar, - deref_args)) - } - _ => None + +autoderef_receiver: AutoderefReceiverFlag, + unbound_method: &fn(), + _expected_result: Option + ) + -> ty::t { + match method::lookup(fcx, op_ex, self_ex, + op_ex.callee_id, opname, self_t, ~[], + deref_args, CheckTraitsOnly, autoderef_receiver) { + Some(ref origin) => { + let method_ty = fcx.node_ty(op_ex.callee_id); + let method_map = fcx.ccx.method_map; + method_map.insert(op_ex.id, *origin); + check_call_inner(fcx, op_ex.span, + op_ex.id, method_ty, + op_ex, args, + ast::NoSugar, deref_args) + } + _ => { + let tcx = fcx.tcx(); + unbound_method(); + // Check the args anyway + // so we get all the error messages + let expected_ty = ty::mk_err(tcx); + check_call_inner(fcx, op_ex.span, op_ex.id, + expected_ty, op_ex, args, + ast::NoSugar, deref_args); + ty::mk_err(tcx) + } } } @@ -1469,27 +1461,30 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt, expr: @ast::expr, op: ast::binop, lhs: @ast::expr, - rhs: @ast::expr) - -> bool { + rhs: @ast::expr, + // Used only in the error case + expected_result: Option + ) { let tcx = fcx.ccx.tcx; - let lhs_bot = check_expr(fcx, lhs); - let lhs_t = fcx.expr_ty(lhs); - let lhs_t = structurally_resolved_type(fcx, lhs.span, lhs_t); + check_expr(fcx, lhs); + // Callee does bot / err checking + let lhs_t = structurally_resolved_type(fcx, lhs.span, + fcx.expr_ty(lhs)); if ty::type_is_integral(lhs_t) && ast_util::is_shift_binop(op) { // Shift is a special case: rhs can be any integral type - let rhs_bot = check_expr(fcx, rhs); + check_expr(fcx, rhs); let rhs_t = fcx.expr_ty(rhs); require_integral(fcx, rhs.span, rhs_t); fcx.write_ty(expr.id, lhs_t); - return lhs_bot | rhs_bot; + return; } if ty::is_binopable(tcx, lhs_t, op) { let tvar = fcx.infcx().next_ty_var(); demand::suptype(fcx, expr.span, tvar, lhs_t); - let rhs_bot = check_expr_has_type(fcx, rhs, tvar); + check_expr_has_type(fcx, rhs, tvar); let result_t = match op { ast::eq | ast::ne | ast::lt | ast::le | ast::ge | @@ -1502,23 +1497,28 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt, }; fcx.write_ty(expr.id, result_t); - return { - if !ast_util::lazy_binop(op) { lhs_bot | rhs_bot } - else { lhs_bot } - }; + return; } - // A hack, but this prevents multiple errors for the same code - // (since check_user_binop calls structurally_resolve_type) - let (result, rhs_bot) = - match ty::deref(fcx.tcx(), lhs_t, false).map( - |tt| structurally_resolved_type(fcx, - expr.span, tt.ty)) { - Some(t) if ty::get(t).sty == ty::ty_err => (t, false), - _ => check_user_binop(fcx, expr, lhs, lhs_t, op, rhs) - }; - fcx.write_ty(expr.id, result); - return lhs_bot | rhs_bot; + if op == ast::or || op == ast::and { + // This is an error; one of the operands must have the wrong + // type + fcx.write_error(expr.id); + fcx.write_error(rhs.id); + fcx.type_error_message(expr.span, |actual| { + fmt!("binary operation %s cannot be applied \ + to type `%s`", + ast_util::binop_to_str(op), actual)}, + lhs_t, None) + + } + + let result_t = check_user_binop(fcx, expr, lhs, lhs_t, op, rhs, + expected_result); + fcx.write_ty(expr.id, result_t); + if ty::type_is_error(result_t) { + fcx.write_ty(rhs.id, result_t); + } } fn check_user_binop(fcx: @mut FnCtxt, @@ -1526,32 +1526,26 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt, lhs_expr: @ast::expr, lhs_resolved_t: ty::t, op: ast::binop, - rhs: @ast::expr) - -> (ty::t, bool) { + rhs: @ast::expr, + expected_result: Option) -> ty::t { let tcx = fcx.ccx.tcx; match ast_util::binop_to_method_name(op) { - Some(ref name) => { - match lookup_op_method(fcx, - ex, - lhs_expr, - lhs_resolved_t, - fcx.tcx().sess.ident_of(copy *name), - ~[rhs], - DoDerefArgs, - DontAutoderefReceiver) { - Some(pair) => return pair, - _ => () + Some(ref name) => { + let if_op_unbound = || { + fcx.type_error_message(ex.span, |actual| { + fmt!("binary operation %s cannot be applied \ + to type `%s`", + ast_util::binop_to_str(op), actual)}, + lhs_resolved_t, None) + }; + return lookup_op_method(fcx, ex, lhs_expr, lhs_resolved_t, + fcx.tcx().sess.ident_of(copy *name), + ~[rhs], DoDerefArgs, DontAutoderefReceiver, if_op_unbound, + expected_result); } - } - _ => () - } + None => () + }; check_expr(fcx, rhs); - fcx.type_error_message(ex.span, - |actual| { - fmt!("binary operation %s cannot be applied to type `%s`", - ast_util::binop_to_str(op), actual) - }, - lhs_resolved_t, None); // If the or operator is used it might be that the user forgot to // supply the do keyword. Let's be more helpful in that situation. @@ -1566,7 +1560,7 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt, } } - (lhs_resolved_t, false) + ty::mk_err(tcx) } fn check_user_unop(fcx: @mut FnCtxt, @@ -1574,25 +1568,19 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt, +mname: ~str, ex: @ast::expr, rhs_expr: @ast::expr, - rhs_t: ty::t) + rhs_t: ty::t, + expected_t: Option) -> ty::t { - match lookup_op_method(fcx, - ex, - rhs_expr, - rhs_t, - fcx.tcx().sess.ident_of(mname), - ~[], - DontDerefArgs, - DontAutoderefReceiver) { - Some((ret_ty, _)) => ret_ty, - _ => { - fcx.type_error_message(ex.span, |actual| { - fmt!("cannot apply unary operator `%s` to type `%s`", - op_str, actual) - }, rhs_t, None); - rhs_t - } - } + lookup_op_method( + fcx, ex, rhs_expr, rhs_t, + fcx.tcx().sess.ident_of(mname), ~[], + DontDerefArgs, DontAutoderefReceiver, + || { + fcx.type_error_message(ex.span, |actual| { + fmt!("cannot apply unary operator `%s` to type `%s`", + op_str, actual) + }, rhs_t, None); + }, expected_t) } // Resolves `expected` by a single level if it is a variable and passes it @@ -1632,6 +1620,7 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt, // block syntax lambdas; that is, lambdas without explicit // sigils. let expected_sty = unpack_expected(fcx, expected, |x| Some(copy *x)); + let mut error_happened = false; let (expected_tys, expected_purity, expected_sigil, @@ -1646,6 +1635,7 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt, (Some(sig), cenv.purity, cenv.sigil, cenv.onceness) } _ => { + // Not an error! Means we're inferring the closure type (None, ast::impure_fn, ast::BorrowedSigil, ast::Many) } } @@ -1664,7 +1654,22 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt, sigil, purity, expected_onceness, None, decl, expected_tys, expr.span); - let fty = ty::mk_closure(tcx, copy fn_ty); + let mut fty_sig; + let fty = if error_happened { + fty_sig = FnSig { + inputs: fn_ty.sig.inputs.map(|an_arg| { + arg { mode: an_arg.mode, + ty: ty::mk_err(tcx) + }}), + output: ty::mk_err(tcx) + }; + ty::mk_err(tcx) + } + else { + let fn_ty_copy = copy fn_ty; + fty_sig = copy fn_ty.sig; + ty::mk_closure(tcx, fn_ty_copy) + }; debug!("check_expr_fn_with_unifier %s fty=%s", fcx.expr_to_str(expr), @@ -1674,11 +1679,10 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt, let inherited_purity = ty::determine_inherited_purity(copy fcx.purity, purity, - fn_ty.sigil); + sigil); - check_fn(fcx.ccx, None, inherited_purity, - &fn_ty.sig, decl, body, fn_kind, - fcx.in_scope_regions, fcx.inh); + check_fn(fcx.ccx, None, inherited_purity, &fty_sig, + decl, body, fn_kind, fcx.in_scope_regions, fcx.inh); } @@ -1688,10 +1692,9 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt, is_callee: bool, base: @ast::expr, field: ast::ident, - tys: &[@ast::Ty]) - -> bool { + tys: &[@ast::Ty]) { let tcx = fcx.ccx.tcx; - let bot = check_expr(fcx, base); + let mut bot = check_expr(fcx, base); let expr_t = structurally_resolved_type(fcx, expr.span, fcx.expr_ty(base)); let (base_t, derefs) = do_autoderef(fcx, expr.span, expr_t); @@ -1743,7 +1746,7 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt, ~"attempted to take value of method \ (try writing an anonymous function)"); // Add error type for the result - fcx.write_ty(expr.id, ty::mk_err(tcx)); + fcx.write_error(expr.id); } } None => { @@ -1755,25 +1758,21 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt, }, expr_t, None); // Add error type for the result - fcx.write_ty(expr.id, ty::mk_err(tcx)); + fcx.write_error(expr.id); } } - return bot; } fn check_struct_or_variant_fields(fcx: @mut FnCtxt, span: span, class_id: ast::def_id, - substitutions: &ty::substs, + node_id: ast::node_id, + +substitutions: ty::substs, field_types: &[ty::field_ty], ast_fields: &[ast::field], - check_completeness: bool) - -> bool { + check_completeness: bool) { let tcx = fcx.ccx.tcx; - let mut bot = false; - - debug!("%? %?", ast_fields.len(), field_types.len()); let class_field_map = HashMap(); let mut fields_found = 0; @@ -1782,38 +1781,49 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt, class_field_map.insert(field.ident, (field.id, false)); } + let mut error_happened = false; + // Typecheck each field. for ast_fields.each |field| { + let mut expected_field_type = ty::mk_err(tcx); + match class_field_map.find(&field.node.ident) { None => { tcx.sess.span_err( field.span, fmt!("structure has no field named `%s`", *tcx.sess.str_of(field.node.ident))); + error_happened = true; } Some((_, true)) => { tcx.sess.span_err( field.span, fmt!("field `%s` specified more than once", *tcx.sess.str_of(field.node.ident))); + error_happened = true; } Some((field_id, false)) => { - let expected_field_type = + expected_field_type = ty::lookup_field_type( - tcx, class_id, field_id, substitutions); - bot |= - check_expr_coercable_to_type( - fcx, - field.node.expr, - expected_field_type); + tcx, class_id, field_id, &substitutions); class_field_map.insert( field.node.ident, (field_id, true)); fields_found += 1; } } + // Make sure to give a type to the field even if there's + // an error, so we can continue typechecking + check_expr_coercable_to_type( + fcx, + field.node.expr, + expected_field_type); + } + + if error_happened { + fcx.write_error(node_id); } - if check_completeness { + if check_completeness && !error_happened { // Make sure the programmer specified all the fields. fail_unless!(fields_found <= field_types.len()); if fields_found < field_types.len() { @@ -1835,10 +1845,13 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt, ~"s" }, str::connect(missing_fields, ~", "))); - } + } } - return bot; + if !error_happened { + fcx.write_ty(node_id, ty::mk_struct(fcx.ccx.tcx, + class_id, substitutions)); + } } fn check_struct_constructor(fcx: @mut FnCtxt, @@ -1846,9 +1859,7 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt, span: codemap::span, class_id: ast::def_id, fields: &[ast::field], - base_expr: Option<@ast::expr>) - -> bool { - let mut bot = false; + base_expr: Option<@ast::expr>) { let tcx = fcx.ccx.tcx; // Look up the number of type parameters and the raw type, and @@ -1900,29 +1911,35 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt, tps: type_parameters }; - let struct_type = ty::subst(tcx, &substitutions, raw_type); + let mut struct_type = ty::subst(tcx, &substitutions, raw_type); // Look up and check the fields. let class_fields = ty::lookup_struct_fields(tcx, class_id); - bot = check_struct_or_variant_fields(fcx, - span, - class_id, - &substitutions, - class_fields, - fields, - base_expr.is_none()) || bot; + check_struct_or_variant_fields(fcx, + span, + class_id, + id, + substitutions, + class_fields, + fields, + base_expr.is_none()); + if ty::type_is_error(fcx.node_ty(id)) { + struct_type = ty::mk_err(tcx); + } // Check the base expression if necessary. match base_expr { None => {} Some(base_expr) => { - bot = check_expr_has_type(fcx, base_expr, struct_type) || bot + check_expr_has_type(fcx, base_expr, struct_type); + if ty::type_is_bot(fcx.node_ty(base_expr.id)) { + struct_type = ty::mk_bot(tcx); + } } } // Write in the resulting type. fcx.write_ty(id, struct_type); - return bot; } fn check_struct_enum_variant(fcx: @mut FnCtxt, @@ -1930,9 +1947,7 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt, span: codemap::span, enum_id: ast::def_id, variant_id: ast::def_id, - fields: &[ast::field]) - -> bool { - let mut bot = false; + fields: &[ast::field]) { let tcx = fcx.ccx.tcx; // Look up the number of type parameters and the raw type, and @@ -1988,17 +2003,15 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt, // Look up and check the enum variant fields. let variant_fields = ty::lookup_struct_fields(tcx, variant_id); - bot = check_struct_or_variant_fields(fcx, - span, - variant_id, - &substitutions, - variant_fields, - fields, - true) || bot; - - // Write in the resulting type. + check_struct_or_variant_fields(fcx, + span, + variant_id, + id, + substitutions, + variant_fields, + fields, + true); fcx.write_ty(id, enum_type); - return bot; } fn check_loop_body(fcx: @mut FnCtxt, @@ -2046,15 +2059,8 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt, fty.sig.output, None); err_happened = true; - - // Kind of a hack: create a function type with - // the result replaced with ty_err, to - // suppress derived errors. - let t = ty::replace_closure_return_type( - tcx, ty::mk_closure(tcx, copy *fty), - ty::mk_err(tcx)); - fcx.write_ty(expr.id, ty::mk_err(tcx)); - t + fcx.write_error(expr.id); + ty::mk_err(tcx) } } } @@ -2070,7 +2076,7 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt, }, expected_t, None); let err_ty = ty::mk_err(tcx); - fcx.write_ty(expr.id, err_ty); + fcx.write_error(expr.id); err_happened = true; err_ty } @@ -2110,7 +2116,8 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt, let block_ty = structurally_resolved_type( fcx, expr.span, fcx.node_ty(loop_body.id)); if err_happened { - fcx.write_ty(expr.id, ty::mk_err(fcx.tcx())); + fcx.write_error(expr.id); + fcx.write_error(loop_body.id); } else { let loop_body_ty = ty::replace_closure_return_type( @@ -2121,17 +2128,18 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt, let tcx = fcx.ccx.tcx; let id = expr.id; - let mut bot = false; match expr.node { ast::expr_vstore(ev, vst) => { let typ = match ev.node { ast::expr_lit(@codemap::spanned { node: ast::lit_str(s), _ }) => { - let tt = ast_expr_vstore_to_vstore(fcx, ev, str::len(*s), vst); + let tt = ast_expr_vstore_to_vstore(fcx, ev, s.len(), vst); ty::mk_estr(tcx, tt) } ast::expr_vec(ref args, mutbl) => { let tt = ast_expr_vstore_to_vstore(fcx, ev, args.len(), vst); let mutability; + let mut any_error = false; + let mut any_bot = false; match vst { ast::expr_vstore_mut_box | ast::expr_vstore_mut_slice => { mutability = ast::m_mutbl @@ -2139,16 +2147,42 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt, _ => mutability = mutbl } let t: ty::t = fcx.infcx().next_ty_var(); - for args.each |e| { bot |= check_expr_has_type(fcx, *e, t); } - ty::mk_evec(tcx, ty::mt {ty: t, mutbl: mutability}, tt) + for args.each |e| { + check_expr_has_type(fcx, *e, t); + let arg_t = fcx.expr_ty(*e); + if ty::type_is_error(arg_t) { + any_error = true; + } + else if ty::type_is_bot(arg_t) { + any_bot = true; + } + } + if any_error { + ty::mk_err(tcx) + } + else if any_bot { + ty::mk_bot(tcx) + } + else { + ty::mk_evec(tcx, ty::mt {ty: t, mutbl: mutability}, tt) + } } ast::expr_repeat(element, count_expr, mutbl) => { let count = ty::eval_repeat_count(tcx, count_expr); check_expr_with_hint(fcx, count_expr, ty::mk_uint(tcx)); let tt = ast_expr_vstore_to_vstore(fcx, ev, count, vst); let t: ty::t = fcx.infcx().next_ty_var(); - bot |= check_expr_has_type(fcx, element, t); - ty::mk_evec(tcx, ty::mt {ty: t, mutbl: mutbl}, tt) + check_expr_has_type(fcx, element, t); + let arg_t = fcx.expr_ty(element); + if ty::type_is_error(arg_t) { + ty::mk_err(tcx) + } + else if ty::type_is_bot(arg_t) { + ty::mk_bot(tcx) + } + else { + ty::mk_evec(tcx, ty::mt {ty: t, mutbl: mutbl}, tt) + } } _ => tcx.sess.span_bug(expr.span, ~"vstore modifier on non-sequence") @@ -2162,10 +2196,20 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt, fcx.write_ty(id, typ); } ast::expr_binary(op, lhs, rhs) => { - bot |= check_binop(fcx, expr, op, lhs, rhs); + check_binop(fcx, expr, op, lhs, rhs, expected); + let lhs_ty = fcx.expr_ty(lhs); + let rhs_ty = fcx.expr_ty(rhs); + if ty::type_is_error(lhs_ty) || + ty::type_is_error(rhs_ty) { + fcx.write_error(id); + } + else if ty::type_is_bot(lhs_ty) || + (ty::type_is_bot(rhs_ty) && !ast_util::lazy_binop(op)) { + fcx.write_bot(id); + } } ast::expr_assign_op(op, lhs, rhs) => { - bot |= check_binop(fcx, expr, op, lhs, rhs); + check_binop(fcx, expr, op, lhs, rhs, expected); let lhs_t = fcx.expr_ty(lhs); let result_t = fcx.expr_ty(expr); demand::suptype(fcx, expr.span, result_t, lhs_t); @@ -2173,7 +2217,10 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt, // Overwrite result of check_binop...this preserves existing behavior // but seems quite dubious with regard to user-defined methods // and so forth. - Niko - fcx.write_nil(expr.id); + if !ty::type_is_error(result_t) + && !ty::type_is_bot(result_t) { + fcx.write_nil(expr.id); + } } ast::expr_unary(unop, oprnd) => { let exp_inner = do unpack_expected(fcx, expected) |sty| { @@ -2186,75 +2233,82 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt, ast::deref => None } }; - bot = check_expr_with_opt_hint(fcx, oprnd, exp_inner); + check_expr_with_opt_hint(fcx, oprnd, exp_inner); let mut oprnd_t = fcx.expr_ty(oprnd); - match unop { - ast::box(mutbl) => { - oprnd_t = ty::mk_box(tcx, ty::mt {ty: oprnd_t, mutbl: mutbl}); - } - ast::uniq(mutbl) => { - oprnd_t = ty::mk_uniq(tcx, ty::mt {ty: oprnd_t, mutbl: mutbl}); - } - ast::deref => { - let sty = structure_of(fcx, expr.span, oprnd_t); - - match sty { - // deref'ing an unsafe pointer requires that we be in an unsafe - // context - ty::ty_ptr(*) => { - fcx.require_unsafe( - expr.span, - ~"dereference of unsafe pointer"); - } - _ => { /*ok*/ } - } - - let operand_ty = ty::deref_sty(tcx, &sty, true); - - match operand_ty { - Some(mt) => { - oprnd_t = mt.ty - } - None => { - match sty { - ty::ty_enum(*) => { - tcx.sess.span_err( - expr.span, - ~"can only dereference enums \ - with a single variant which has a \ - single argument"); - } - ty::ty_struct(*) => { - tcx.sess.span_err( - expr.span, - ~"can only dereference structs with one anonymous \ - field"); - } - _ => { - fcx.type_error_message(expr.span, |actual| { - fmt!("type %s cannot be dereferenced", actual) - }, oprnd_t, None); - } + if !ty::type_is_error(oprnd_t) && + !ty::type_is_bot(oprnd_t) { + match unop { + ast::box(mutbl) => { + oprnd_t = ty::mk_box(tcx, + ty::mt {ty: oprnd_t, mutbl: mutbl}); + } + ast::uniq(mutbl) => { + oprnd_t = ty::mk_uniq(tcx, + ty::mt {ty: oprnd_t, mutbl: mutbl}); + } + ast::deref => { + let sty = structure_of(fcx, expr.span, oprnd_t); + match sty { + // deref'ing an unsafe pointer requires that we be in + // an unsafe context + ty::ty_ptr(*) => { + fcx.require_unsafe( + expr.span, + ~"dereference of unsafe pointer"); + } + _ => { /*ok*/ } + } + let operand_ty = ty::deref_sty(tcx, &sty, true); + match operand_ty { + Some(mt) => { + oprnd_t = mt.ty + } + None => { + match sty { + ty::ty_enum(*) => { + tcx.sess.span_err( + expr.span, + ~"can only dereference enums \ + with a single variant which has a \ + single argument"); + } + ty::ty_struct(*) => { + tcx.sess.span_err( + expr.span, + ~"can only dereference structs with \ + one anonymous field"); + } + _ => { + fcx.type_error_message(expr.span, + |actual| { + fmt!("type %s cannot be \ + dereferenced", actual) + }, oprnd_t, None); + } + } + } + } + } + ast::not => { + oprnd_t = structurally_resolved_type(fcx, oprnd.span, + oprnd_t); + if !(ty::type_is_integral(oprnd_t) || + ty::get(oprnd_t).sty == ty::ty_bool) { + oprnd_t = check_user_unop(fcx, + ~"!", ~"not", expr, oprnd, oprnd_t, + expected); + } + } + ast::neg => { + oprnd_t = structurally_resolved_type(fcx, oprnd.span, + oprnd_t); + if !(ty::type_is_integral(oprnd_t) || + ty::type_is_fp(oprnd_t)) { + oprnd_t = check_user_unop(fcx, + ~"-", ~"neg", expr, oprnd, oprnd_t, expected); + } } - } - } - } - ast::not => { - oprnd_t = structurally_resolved_type(fcx, oprnd.span, oprnd_t); - if !(ty::type_is_integral(oprnd_t) || - ty::get(oprnd_t).sty == ty::ty_bool) { - oprnd_t = check_user_unop(fcx, ~"!", ~"not", expr, - oprnd, oprnd_t); - } - } - ast::neg => { - oprnd_t = structurally_resolved_type(fcx, oprnd.span, oprnd_t); - if !(ty::type_is_integral(oprnd_t) || - ty::type_is_fp(oprnd_t)) { - oprnd_t = check_user_unop(fcx, ~"-", ~"neg", expr, - oprnd, oprnd_t); } - } } fcx.write_ty(id, oprnd_t); } @@ -2263,7 +2317,7 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt, fcx, expected, |sty| match *sty { ty::ty_rptr(_, ref mt) => Some(mt.ty), _ => None }); - bot = check_expr_with_opt_hint(fcx, oprnd, hint); + check_expr_with_opt_hint(fcx, oprnd, hint); // Note: at this point, we cannot say what the best lifetime // is to use for resulting pointer. We want to use the @@ -2282,7 +2336,14 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt, let region = fcx.infcx().next_region_var(expr.span, expr.id); let tm = ty::mt { ty: fcx.expr_ty(oprnd), mutbl: mutbl }; - let oprnd_t = ty::mk_rptr(tcx, region, tm); + let oprnd_t = if ty::type_is_error(tm.ty) { + ty::mk_err(tcx) + } else if ty::type_is_bot(tm.ty) { + ty::mk_bot(tcx) + } + else { + ty::mk_rptr(tcx, region, tm) + }; fcx.write_ty(id, oprnd_t); } ast::expr_path(pth) => { @@ -2304,10 +2365,9 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt, fcx.write_nil(id); } ast::expr_mac(_) => tcx.sess.bug(~"unexpanded macro"), - ast::expr_break(_) => { fcx.write_bot(id); bot = true; } - ast::expr_again(_) => { fcx.write_bot(id); bot = true; } + ast::expr_break(_) => { fcx.write_bot(id); } + ast::expr_again(_) => { fcx.write_bot(id); } ast::expr_ret(expr_opt) => { - bot = true; let ret_ty = match fcx.indirect_ret_ty { Some(t) => t, None => fcx.ret_ty }; @@ -2328,43 +2388,124 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt, fcx.write_bot(id); } ast::expr_log(_, lv, e) => { - bot = check_expr_has_type(fcx, lv, + check_expr_has_type(fcx, lv, ty::mk_mach_uint(tcx, ast::ty_u32)); // Note: this does not always execute, so do not propagate bot: check_expr(fcx, e); - fcx.write_nil(id); + if ty::type_is_error(fcx.expr_ty(e)) { + fcx.write_error(id); + } + else { + fcx.write_nil(id); + } } ast::expr_copy(a) => { - bot = check_expr_with_opt_hint(fcx, a, expected); + check_expr_with_opt_hint(fcx, a, expected); fcx.write_ty(id, fcx.expr_ty(a)); } ast::expr_paren(a) => { - bot = check_expr_with_opt_hint(fcx, a, expected); + check_expr_with_opt_hint(fcx, a, expected); fcx.write_ty(id, fcx.expr_ty(a)); } ast::expr_assign(lhs, rhs) => { - bot = check_assignment(fcx, lhs, rhs, id); + check_assignment(fcx, lhs, rhs, id); + let lhs_ty = fcx.expr_ty(lhs); + let rhs_ty = fcx.expr_ty(rhs); + if ty::type_is_error(lhs_ty) || ty::type_is_error(rhs_ty) { + fcx.write_error(id); + } + else if ty::type_is_bot(lhs_ty) || ty::type_is_bot(rhs_ty) { + fcx.write_bot(id); + } + else { + fcx.write_nil(id); + } } ast::expr_swap(lhs, rhs) => { - bot = check_assignment(fcx, lhs, rhs, id); + check_assignment(fcx, lhs, rhs, id); + let lhs_ty = fcx.expr_ty(lhs); + let rhs_ty = fcx.expr_ty(rhs); + if ty::type_is_error(lhs_ty) || ty::type_is_error(rhs_ty) { + fcx.write_error(id); + } + else if ty::type_is_bot(lhs_ty) || ty::type_is_bot(rhs_ty) { + fcx.write_bot(id); + } + else { + fcx.write_nil(id); + } } ast::expr_if(cond, ref thn, elsopt) => { - bot = check_expr_has_type(fcx, cond, ty::mk_bool(tcx)); - bot |= check_then_else(fcx, thn, elsopt, id, expr.span); + check_expr_has_type(fcx, cond, ty::mk_bool(tcx)); + check_then_else(fcx, thn, elsopt, id, expr.span); + let cond_ty = fcx.expr_ty(cond); + let then_ty = fcx.node_ty(thn.node.id); + let else_is_bot = elsopt.map_default(false, |els| { + ty::type_is_bot(fcx.expr_ty(*els))}); + if ty::type_is_error(cond_ty) || ty::type_is_error(then_ty) { + fcx.write_error(id); + } + else if elsopt.map_default(false, |els| { + ty::type_is_error(fcx.expr_ty(*els)) }) { + fcx.write_error(id); + } + else if ty::type_is_bot(cond_ty) || + (ty::type_is_bot(then_ty) && else_is_bot) { + fcx.write_bot(id); + } + // Other cases were handled by check_then_else } ast::expr_while(cond, ref body) => { - bot = check_expr_has_type(fcx, cond, ty::mk_bool(tcx)); + check_expr_has_type(fcx, cond, ty::mk_bool(tcx)); check_block_no_value(fcx, body); - fcx.write_ty(id, ty::mk_nil(tcx)); + let cond_ty = fcx.expr_ty(cond); + let body_ty = fcx.node_ty(body.node.id); + if ty::type_is_error(cond_ty) || ty::type_is_error(body_ty) { + fcx.write_error(id); + } + else if ty::type_is_bot(cond_ty) { + fcx.write_bot(id); + } + else { + fcx.write_nil(id); + } } ast::expr_loop(ref body, _) => { - check_block_no_value(fcx, body); - fcx.write_ty(id, ty::mk_nil(tcx)); - bot = !may_break(tcx, expr.id, body); + check_block_no_value(fcx, (body)); + if !may_break(tcx, expr.id, body) { + fcx.write_bot(id); + } + else { + fcx.write_nil(id); + } } ast::expr_match(discrim, ref arms) => { - bot = _match::check_match(fcx, expr, discrim, *arms); + _match::check_match(fcx, expr, discrim, *arms); + let discrim_ty = fcx.expr_ty(discrim); + let arm_tys = arms.map(|a| fcx.node_ty(a.body.node.id)); + if ty::type_is_error(discrim_ty) || + arm_tys.any(|t| ty::type_is_error(*t)) { + fcx.write_error(id); + } + // keep in mind that `all` returns true in the empty vec case, + // which is what we want + else if ty::type_is_bot(discrim_ty) || + arm_tys.all(|t| ty::type_is_bot(*t)) { + fcx.write_bot(id); + } + else { + // Find the first non-_|_ arm. + // We know there's at least one because we already checked + // for n=0 as well as all arms being _|_ in the previous + // `if`. + for arm_tys.each() |arm_ty| { + if !ty::type_is_bot(*arm_ty) { + fcx.write_ty(id, *arm_ty); + break; + } + } + } } ast::expr_fn_block(ref decl, ref body) => { check_expr_fn(fcx, expr, None, @@ -2407,105 +2548,144 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt, fcx.write_ty(expr.id, fcx.node_ty(b.id)); } ast::expr_block(ref b) => { - // If this is an unchecked block, turn off purity-checking - bot = check_block_with_expected(fcx, b, expected); - let typ = - match b.node.expr { - Some(expr) => fcx.expr_ty(expr), - None => ty::mk_nil(tcx) - }; - fcx.write_ty(id, typ); + check_block_with_expected(fcx, b, expected); + fcx.write_ty(id, fcx.node_ty(b.node.id)); } ast::expr_call(f, ref args, sugar) => { - bot = check_call(fcx, expr.span, expr.id, f, *args, sugar); + check_call(fcx, expr.span, expr.id, f, *args, sugar); + let f_ty = fcx.expr_ty(f); + let (args_bot, args_err) = args.foldl((false, false), + |&(rest_bot, rest_err), a| { + // is this not working? + let a_ty = fcx.expr_ty(*a); + (rest_bot || ty::type_is_bot(a_ty), + rest_err || ty::type_is_error(a_ty))}); + if ty::type_is_error(f_ty) || args_err { + fcx.write_error(id); + } + else if ty::type_is_bot(f_ty) || args_bot { + fcx.write_bot(id); + } } ast::expr_method_call(rcvr, ident, ref tps, ref args, sugar) => { - bot = check_method_call(fcx, expr, rcvr, ident, *args, *tps, sugar); + check_method_call(fcx, expr, rcvr, ident, *args, *tps, sugar); + let f_ty = fcx.expr_ty(rcvr); + let arg_tys = args.map(|a| fcx.expr_ty(*a)); + let (args_bot, args_err) = arg_tys.foldl((false, false), + |&(rest_bot, rest_err), a| { + (rest_bot || ty::type_is_bot(*a), + rest_err || ty::type_is_error(*a))}); + if ty::type_is_error(f_ty) || args_err { + fcx.write_error(id); + } + else if ty::type_is_bot(f_ty) || args_bot { + fcx.write_bot(id); + } } ast::expr_cast(e, t) => { - bot = check_expr(fcx, e); + check_expr(fcx, e); let t_1 = fcx.to_ty(t); let t_e = fcx.expr_ty(e); debug!("t_1=%s", fcx.infcx().ty_to_str(t_1)); debug!("t_e=%s", fcx.infcx().ty_to_str(t_e)); - match ty::get(t_1).sty { - // This will be looked up later on - ty::ty_trait(*) => (), + if ty::type_is_error(t_e) { + fcx.write_error(id); + } + else if ty::type_is_bot(t_e) { + fcx.write_bot(id); + } + else { + match ty::get(t_1).sty { + // This will be looked up later on + ty::ty_trait(*) => (), - _ => { - if ty::type_is_nil(t_e) { - fcx.type_error_message(expr.span, |actual| { - fmt!("cast from nil: `%s` as `%s`", actual, - fcx.infcx().ty_to_str(t_1)) - }, t_e, None); - } else if ty::type_is_nil(t_1) { - fcx.type_error_message(expr.span, |actual| { - fmt!("cast to nil: `%s` as `%s`", actual, - fcx.infcx().ty_to_str(t_1)) - }, t_e, None); - } - - let t_1_is_scalar = type_is_scalar(fcx, expr.span, t_1); - if type_is_c_like_enum(fcx,expr.span,t_e) && t_1_is_scalar { - /* this case is allowed */ - } else if type_is_region_ptr(fcx, expr.span, t_e) && - type_is_unsafe_ptr(fcx, expr.span, t_1) { - - fn is_vec(t: ty::t) -> bool { - match ty::get(t).sty { - ty::ty_evec(_,_) => true, - _ => false - } - } - fn types_compatible(fcx: @mut FnCtxt, sp: span, t1: ty::t, - t2: ty::t) -> bool { - if !is_vec(t1) { - false - } else { - let el = ty::sequence_element_type(fcx.tcx(), t1); - infer::mk_eqty(fcx.infcx(), false, sp, el, t2).is_ok() + _ => { + if ty::type_is_nil(t_e) { + fcx.type_error_message(expr.span, |actual| { + fmt!("cast from nil: `%s` as `%s`", actual, + fcx.infcx().ty_to_str(t_1)) + }, t_e, None); + } else if ty::type_is_nil(t_1) { + fcx.type_error_message(expr.span, |actual| { + fmt!("cast to nil: `%s` as `%s`", actual, + fcx.infcx().ty_to_str(t_1)) + }, t_e, None); } - } - // Due to the limitations of LLVM global constants, - // region pointers end up pointing at copies of - // vector elements instead of the original values. - // To allow unsafe pointers to work correctly, we - // need to special-case obtaining an unsafe pointer - // from a region pointer to a vector. - - /* this cast is only allowed from &[T] to *T or - &T to *T. */ - let te = structurally_resolved_type(fcx, e.span, t_e); - match (&ty::get(te).sty, &ty::get(t_1).sty) { - (&ty::ty_rptr(_, mt1), &ty::ty_ptr(mt2)) - if types_compatible(fcx, e.span, mt1.ty, mt2.ty) => { - /* this case is allowed */ - } - _ => { - demand::coerce(fcx, e.span, t_1, e); - } + let t_1_is_scalar = type_is_scalar(fcx, expr.span, t_1); + if type_is_c_like_enum(fcx,expr.span,t_e) + && t_1_is_scalar { + /* this case is allowed */ + } else if type_is_region_ptr(fcx, expr.span, t_e) && + type_is_unsafe_ptr(fcx, expr.span, t_1) { + + fn is_vec(t: ty::t) -> bool { + match ty::get(t).sty { + ty::ty_evec(_,_) => true, + _ => false + } + } + fn types_compatible(fcx: @mut FnCtxt, sp: span, + t1: ty::t, t2: ty::t) -> bool { + if !is_vec(t1) { + false + } else { + let el = ty::sequence_element_type(fcx.tcx(), + t1); + infer::mk_eqty(fcx.infcx(), false, + sp, el, t2).is_ok() + } + } + + // Due to the limitations of LLVM global constants, + // region pointers end up pointing at copies of + // vector elements instead of the original values. + // To allow unsafe pointers to work correctly, we + // need to special-case obtaining an unsafe pointer + // from a region pointer to a vector. + + /* this cast is only allowed from &[T] to *T or + &T to *T. */ + let te = structurally_resolved_type(fcx, e.span, t_e); + match (&ty::get(te).sty, &ty::get(t_1).sty) { + (&ty::ty_rptr(_, mt1), &ty::ty_ptr(mt2)) + if types_compatible(fcx, e.span, + mt1.ty, mt2.ty) => { + /* this case is allowed */ + } + _ => { + demand::coerce(fcx, e.span, t_1, e); + } + } + } else if !(type_is_scalar(fcx,expr.span,t_e) + && t_1_is_scalar) { + /* + If more type combinations should be supported than are + supported here, then file an enhancement issue and + record the issue number in this comment. + */ + fcx.type_error_message(expr.span, |actual| { + fmt!("non-scalar cast: `%s` as `%s`", actual, + fcx.infcx().ty_to_str(t_1)) + }, t_e, None); + } } - } else if !(type_is_scalar(fcx,expr.span,t_e) && t_1_is_scalar) { - /* - If more type combinations should be supported than are - supported here, then file an enhancement issue and record the - issue number in this comment. - */ - fcx.type_error_message(expr.span, |actual| { - fmt!("non-scalar cast: `%s` as `%s`", actual, - fcx.infcx().ty_to_str(t_1)) - }, t_e, None); } - } + fcx.write_ty(id, t_1); } - fcx.write_ty(id, t_1); } ast::expr_vec(ref args, mutbl) => { let t: ty::t = fcx.infcx().next_ty_var(); - for args.each |e| { bot |= check_expr_has_type(fcx, *e, t); } + let mut arg_is_bot = false; + let mut arg_is_err = false; + for args.each |e| { + check_expr_has_type(fcx, *e, t); + let arg_t = fcx.expr_ty(*e); + arg_is_bot |= ty::type_is_bot(arg_t); + arg_is_err |= ty::type_is_error(arg_t); + } let typ = ty::mk_evec(tcx, ty::mt {ty: t, mutbl: mutbl}, ty::vstore_fixed(args.len())); fcx.write_ty(id, typ); @@ -2514,21 +2694,43 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt, let count = ty::eval_repeat_count(tcx, count_expr); check_expr_with_hint(fcx, count_expr, ty::mk_uint(tcx)); let t: ty::t = fcx.infcx().next_ty_var(); - bot |= check_expr_has_type(fcx, element, t); - let t = ty::mk_evec(tcx, ty::mt {ty: t, mutbl: mutbl}, - ty::vstore_fixed(count)); - fcx.write_ty(id, t); + check_expr_has_type(fcx, element, t); + let element_ty = fcx.expr_ty(element); + if ty::type_is_error(element_ty) { + fcx.write_error(id); + } + else if ty::type_is_bot(element_ty) { + fcx.write_bot(id); + } + else { + let t = ty::mk_evec(tcx, ty::mt {ty: t, mutbl: mutbl}, + ty::vstore_fixed(count)); + fcx.write_ty(id, t); + } } ast::expr_tup(ref elts) => { let flds = unpack_expected(fcx, expected, |sty| { match *sty { ty::ty_tup(ref flds) => Some(copy *flds), _ => None } }); + let mut bot_field = false; + let mut err_field = false; let elt_ts = do elts.mapi |i, e| { check_expr_with_opt_hint(fcx, *e, flds.map(|fs| fs[i])); - fcx.expr_ty(*e) + let t = fcx.expr_ty(*e); + err_field = err_field || ty::type_is_error(t); + bot_field = bot_field || ty::type_is_bot(t); + t }; - let typ = ty::mk_tup(tcx, elt_ts); - fcx.write_ty(id, typ); + if bot_field { + fcx.write_bot(id); + } + else if err_field { + fcx.write_error(id); + } + else { + let typ = ty::mk_tup(tcx, elt_ts); + fcx.write_ty(id, typ); + } } ast::expr_struct(path, ref fields, base_expr) => { // Resolve the path. @@ -2548,48 +2750,57 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt, } } ast::expr_field(base, field, ref tys) => { - bot = check_field(fcx, expr, false, base, field, *tys); + check_field(fcx, expr, false, base, field, * tys); + let base_t = fcx.expr_ty(base); + if ty::type_is_error(base_t) { + fcx.write_error(id); + } + else if ty::type_is_bot(base_t) { + fcx.write_bot(id); + } + // Otherwise, type already got written } ast::expr_index(base, idx) => { - bot |= check_expr(fcx, base); + check_expr(fcx, base); + check_expr(fcx, idx); let raw_base_t = fcx.expr_ty(base); - let (base_t, derefs) = do_autoderef(fcx, expr.span, raw_base_t); - bot |= check_expr(fcx, idx); let idx_t = fcx.expr_ty(idx); - let base_sty = structure_of(fcx, expr.span, base_t); - match ty::index_sty(tcx, &base_sty) { - Some(mt) => { - require_integral(fcx, idx.span, idx_t); - fcx.write_ty(id, mt.ty); - fcx.write_autoderef_adjustment(base.id, derefs); - } - None => { - let resolved = structurally_resolved_type(fcx, expr.span, - raw_base_t); - match lookup_op_method(fcx, - expr, - base, - resolved, - tcx.sess.ident_of(~"index"), - ~[idx], - DontDerefArgs, - AutoderefReceiver) { - Some((ret_ty, _)) => fcx.write_ty(id, ret_ty), - _ => { - fcx.type_error_message(expr.span, |actual| - fmt!("cannot index a value of type `%s`", - actual), base_t, None); - fcx.write_ty(id, ty::mk_err(tcx)); - return true; - } + if ty::type_is_error(raw_base_t) + || ty::type_is_bot(raw_base_t) { + fcx.write_ty(id, raw_base_t); + } + else if ty::type_is_error(idx_t) + || ty::type_is_bot(idx_t) { + fcx.write_ty(id, idx_t); + } + else { + let (base_t, derefs) = do_autoderef(fcx, expr.span, raw_base_t); + let base_sty = structure_of(fcx, expr.span, base_t); + match ty::index_sty(tcx, &base_sty) { + Some(mt) => { + require_integral(fcx, idx.span, idx_t); + fcx.write_ty(id, mt.ty); + fcx.write_autoderef_adjustment(base.id, derefs); + } + None => { + let resolved = structurally_resolved_type(fcx, + expr.span, raw_base_t); + let ret_ty = lookup_op_method(fcx, expr, base, resolved, + tcx.sess.ident_of(~"index"), + ~[idx], DontDerefArgs, AutoderefReceiver, + || { + fcx.type_error_message(expr.span, |actual| + fmt!("cannot index a value \ + of type `%s`", actual), base_t, None); + }, expected); + fcx.write_ty(id, ret_ty); } } } - } + } } - if bot { fcx.write_bot(expr.id); } - debug!("type of expr %s is...", + debug!("type of expr(%d) %s is...", expr.id, syntax::print::pprust::expr_to_str(expr, tcx.sess.intr())); debug!("... %s, expected is %s", ppaux::ty_to_str(tcx, fcx.expr_ty(expr)), @@ -2599,9 +2810,6 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt, }); unifier(); - - debug!("<< bot=%b", bot); - return bot; } pub fn require_integral(fcx: @mut FnCtxt, sp: span, t: ty::t) { @@ -2616,13 +2824,12 @@ pub fn require_integral(fcx: @mut FnCtxt, sp: span, t: ty::t) { pub fn check_decl_initializer(fcx: @mut FnCtxt, nid: ast::node_id, init: @ast::expr) - -> bool { + { let local_ty = fcx.local_ty(init.span, nid); - return check_expr_coercable_to_type(fcx, init, local_ty); + check_expr_coercable_to_type(fcx, init, local_ty) } -pub fn check_decl_local(fcx: @mut FnCtxt, local: @ast::local) -> bool { - let mut bot = false; +pub fn check_decl_local(fcx: @mut FnCtxt, local: @ast::local) { let tcx = fcx.ccx.tcx; let t = fcx.local_ty(local.span, local.node.id); @@ -2630,7 +2837,11 @@ pub fn check_decl_local(fcx: @mut FnCtxt, local: @ast::local) -> bool { match local.node.init { Some(init) => { - bot = check_decl_initializer(fcx, local.node.id, init); + check_decl_initializer(fcx, local.node.id, init); + let init_ty = fcx.expr_ty(init); + if ty::type_is_error(init_ty) || ty::type_is_bot(init_ty) { + fcx.write_ty(local.node.id, init_ty); + } } _ => {} } @@ -2644,64 +2855,92 @@ pub fn check_decl_local(fcx: @mut FnCtxt, local: @ast::local) -> bool { block_region: region, }; _match::check_pat(pcx, local.node.pat, t); - return bot; + let pat_ty = fcx.node_ty(local.node.pat.id); + if ty::type_is_error(pat_ty) || ty::type_is_bot(pat_ty) { + fcx.write_ty(local.node.id, pat_ty); + } } -pub fn check_stmt(fcx: @mut FnCtxt, stmt: @ast::stmt) -> bool { +pub fn check_stmt(fcx: @mut FnCtxt, stmt: @ast::stmt) { let mut node_id; - let mut bot = false; + let mut saw_bot = false; + let mut saw_err = false; match stmt.node { ast::stmt_decl(decl, id) => { node_id = id; match decl.node { ast::decl_local(ref ls) => for ls.each |l| { - bot |= check_decl_local(fcx, *l); + check_decl_local(fcx, *l); + let l_t = fcx.node_ty(l.node.id); + saw_bot = saw_bot || ty::type_is_bot(l_t); + saw_err = saw_err || ty::type_is_error(l_t); }, ast::decl_item(_) => {/* ignore for now */ } } } ast::stmt_expr(expr, id) => { node_id = id; - bot = check_expr_has_type(fcx, expr, ty::mk_nil(fcx.ccx.tcx)); + // Check with expected type of () + check_expr_has_type(fcx, expr, ty::mk_nil(fcx.ccx.tcx)); + let expr_ty = fcx.expr_ty(expr); + saw_bot = saw_bot || ty::type_is_bot(expr_ty); + saw_err = saw_err || ty::type_is_error(expr_ty); } ast::stmt_semi(expr, id) => { node_id = id; - bot = check_expr(fcx, expr); + check_expr(fcx, expr); + let expr_ty = fcx.expr_ty(expr); + saw_bot |= ty::type_is_bot(expr_ty); + saw_err |= ty::type_is_error(expr_ty); } ast::stmt_mac(*) => fcx.ccx.tcx.sess.bug(~"unexpanded macro") } - fcx.write_nil(node_id); - return bot; + if saw_bot { + fcx.write_bot(node_id); + } + else if saw_err { + fcx.write_error(node_id); + } + else { + fcx.write_nil(node_id) + } } -pub fn check_block_no_value(fcx: @mut FnCtxt, blk: &ast::blk) -> bool { - let bot = check_block(fcx, blk); - if !bot { - let blkty = fcx.node_ty(blk.node.id); +pub fn check_block_no_value(fcx: @mut FnCtxt, blk: &ast::blk) { + check_block_with_expected(fcx, blk, Some(ty::mk_nil(fcx.ccx.tcx))); + let blkty = fcx.node_ty(blk.node.id); + if ty::type_is_error(blkty) { + fcx.write_error(blk.node.id); + } + else if ty::type_is_bot(blkty) { + fcx.write_bot(blk.node.id); + } + else { let nilty = ty::mk_nil(fcx.ccx.tcx); demand::suptype(fcx, blk.span, nilty, blkty); } - return bot; } -pub fn check_block(fcx0: @mut FnCtxt, blk: &ast::blk) -> bool { +pub fn check_block(fcx0: @mut FnCtxt, blk: &ast::blk) { check_block_with_expected(fcx0, blk, None) } pub fn check_block_with_expected(fcx0: @mut FnCtxt, blk: &ast::blk, - expected: Option) - -> bool { + expected: Option) { let fcx = match blk.node.rules { ast::unsafe_blk => @mut FnCtxt {purity: ast::unsafe_fn,.. copy *fcx0}, ast::default_blk => fcx0 }; do fcx.with_region_lb(blk.node.id) { - let mut bot = false; let mut warned = false; + let mut last_was_bot = false; + let mut any_bot = false; + let mut any_err = false; for blk.node.stmts.each |s| { - if bot && !warned && - match s.node { + check_stmt(fcx, *s); + let s_ty = fcx.node_ty(ast_util::stmt_id(**s)); + if last_was_bot && !warned && match s.node { ast::stmt_decl(@codemap::spanned { node: ast::decl_local(_), _}, _) | ast::stmt_expr(_, _) | ast::stmt_semi(_, _) => { @@ -2712,23 +2951,37 @@ pub fn check_block_with_expected(fcx0: @mut FnCtxt, fcx.ccx.tcx.sess.span_warn(s.span, ~"unreachable statement"); warned = true; } - bot |= check_stmt(fcx, *s); + if ty::type_is_bot(s_ty) { + last_was_bot = true; + } + any_bot = any_bot || ty::type_is_bot(s_ty); + any_err = any_err || ty::type_is_error(s_ty); } match blk.node.expr { - None => fcx.write_nil(blk.node.id), + None => if any_err { + fcx.write_error(blk.node.id); + } + else if any_bot { + fcx.write_bot(blk.node.id); + } + else { + fcx.write_nil(blk.node.id); + }, Some(e) => { - if bot && !warned { + if any_bot && !warned { fcx.ccx.tcx.sess.span_warn(e.span, ~"unreachable expression"); } - bot |= check_expr_with_opt_hint(fcx, e, expected); - let ety = fcx.expr_ty(e); - fcx.write_ty(blk.node.id, ety); + check_expr_with_opt_hint(fcx, e, expected); + let ety = fcx.expr_ty(e); + fcx.write_ty(blk.node.id, ety); + if any_err { + fcx.write_error(blk.node.id); + } + else if any_bot { + fcx.write_bot(blk.node.id); + } } - } - if bot { - fcx.write_bot(blk.node.id); - } - bot + }; } } @@ -3030,12 +3283,13 @@ pub fn instantiate_path(fcx: @mut FnCtxt, pub fn structurally_resolved_type(fcx: @mut FnCtxt, sp: span, tp: ty::t) -> ty::t { match infer::resolve_type(fcx.infcx(), tp, force_tvar) { - Ok(t_s) if !ty::type_is_ty_var(t_s) => return t_s, + Ok(t_s) if !ty::type_is_ty_var(t_s) => t_s, _ => { fcx.type_error_message(sp, |_actual| { ~"the type of this value must be known in this context" }, tp, None); - return ty::mk_err(fcx.tcx()); + demand::suptype(fcx, sp, ty::mk_err(fcx.tcx()), tp); + tp } } } diff --git a/src/librustc/middle/typeck/check/regionck.rs b/src/librustc/middle/typeck/check/regionck.rs index e0441d2e5447f..3a02c19dbaf83 100644 --- a/src/librustc/middle/typeck/check/regionck.rs +++ b/src/librustc/middle/typeck/check/regionck.rs @@ -32,7 +32,6 @@ use core::prelude::*; use middle::freevars::get_freevars; use middle::pat_util::{pat_bindings, pat_is_binding}; use middle::ty::{encl_region, re_scope}; -use middle::ty::{vstore_box, vstore_fixed, vstore_slice}; use middle::ty; use middle::typeck::check::FnCtxt; use middle::typeck::check::lookup_def; @@ -150,7 +149,7 @@ pub fn visit_local(l: @ast::local, &&rcx: @mut Rcx, v: rvt) { // Note: we do this here rather than in visit_pat because we do // not wish to constrain the regions in *patterns* in quite the // same way. `visit_node()` guarantees that the region encloses - // the node in question, which ultimately constraints the regions + // the node in question, which ultimately constrains the regions // in patterns to enclose the match expression as a whole. But we // want them to enclose the *arm*. However, regions in patterns // must either derive from the discriminant or a ref pattern: in @@ -616,9 +615,10 @@ pub mod guarantor { // expressions, both of which always yield a region variable, so // mk_subr should never fail. let rptr_ty = rcx.resolve_node_type(id); - if !ty::type_contains_err(rptr_ty) { - debug!("rptr_ty=%s", ty_to_str(rcx.fcx.ccx.tcx, rptr_ty)); - let r = ty::ty_region(rptr_ty); + if !ty::type_is_error(rptr_ty) { + let tcx = rcx.fcx.ccx.tcx; + debug!("rptr_ty=%s", ty_to_str(tcx, rptr_ty)); + let r = ty::ty_region(tcx, span, rptr_ty); infallibly_mk_subr(rcx, true, span, r, bound); } } @@ -890,8 +890,8 @@ pub mod guarantor { } ast::pat_region(p) => { let rptr_ty = rcx.resolve_node_type(pat.id); - if !ty::type_contains_err(rptr_ty) { - let r = ty::ty_region(rptr_ty); + if !ty::type_is_error(rptr_ty) { + let r = ty::ty_region(rcx.fcx.tcx(), pat.span, rptr_ty); link_ref_bindings_in_pat(rcx, p, Some(r)); } } @@ -899,7 +899,7 @@ pub mod guarantor { ast::pat_range(*) => {} ast::pat_vec(ref before, ref slice, ref after) => { let vec_ty = rcx.resolve_node_type(pat.id); - if !ty::type_contains_err(vec_ty) { + if !ty::type_is_error(vec_ty) { let vstore = ty::ty_vstore(vec_ty); let guarantor1 = match vstore { ty::vstore_fixed(_) | ty::vstore_uniq => guarantor, diff --git a/src/librustc/middle/typeck/check/regionmanip.rs b/src/librustc/middle/typeck/check/regionmanip.rs index c78a91b95e4bb..abbefd1f7e6f9 100644 --- a/src/librustc/middle/typeck/check/regionmanip.rs +++ b/src/librustc/middle/typeck/check/regionmanip.rs @@ -20,8 +20,6 @@ use util::ppaux::region_to_str; use util::ppaux; use std::list::Cons; -use syntax::ast; -use syntax::codemap; // Helper functions related to manipulating region types. diff --git a/src/librustc/middle/typeck/check/vtable.rs b/src/librustc/middle/typeck/check/vtable.rs index 6e86bbca0d1c3..2a705a8feb8b8 100644 --- a/src/librustc/middle/typeck/check/vtable.rs +++ b/src/librustc/middle/typeck/check/vtable.rs @@ -28,7 +28,7 @@ use core::result::{Result, Ok, Err}; use core::result; use core::uint; use core::vec; -use std::oldmap::HashMap; +use core::hashmap::linear::LinearSet; use syntax::ast; use syntax::ast_util; use syntax::codemap::span; @@ -234,14 +234,14 @@ pub fn lookup_vtable(vcx: &VtableContext, _ => { let mut found = ~[]; - let mut impls_seen = HashMap(); + let mut impls_seen = LinearSet::new(); match vcx.ccx.coherence_info.extension_methods.find(&trait_id) { None => { // Nothing found. Continue. } Some(implementations) => { - let implementations: &mut ~[@Impl] = implementations; + let implementations: &mut ~[@Impl] = *implementations; // implementations is the list of all impls in scope for // trait_ty. (Usually, there's just one.) for uint::range(0, implementations.len()) |i| { @@ -250,10 +250,10 @@ pub fn lookup_vtable(vcx: &VtableContext, // im is one specific impl of trait_ty. // First, ensure we haven't processed this impl yet. - if impls_seen.contains_key(&im.did) { + if impls_seen.contains(&im.did) { loop; } - impls_seen.insert(im.did, ()); + impls_seen.insert(im.did); // ty::impl_traits gives us the list of all // traits that im implements. Again, usually diff --git a/src/librustc/middle/typeck/coherence.rs b/src/librustc/middle/typeck/coherence.rs index d4bf95bb8bba0..0b3eca7c07df0 100644 --- a/src/librustc/middle/typeck/coherence.rs +++ b/src/librustc/middle/typeck/coherence.rs @@ -56,7 +56,7 @@ use syntax::visit::{visit_mod}; use util::ppaux::ty_to_str; use core::result::Ok; -use core::hashmap::linear::LinearSet; +use core::hashmap::linear::{LinearMap, LinearSet}; use core::uint; use std::oldmap::HashMap; @@ -104,6 +104,32 @@ pub fn get_base_type(inference_context: @mut InferCtxt, } } +pub fn type_is_defined_in_local_crate(original_type: t) -> bool { + /*! + * + * For coherence, when we have `impl Trait for Type`, we need to + * guarantee that `Type` is "local" to the + * crate. For our purposes, this means that it must contain + * some nominal type defined in this crate. + */ + + let mut found_nominal = false; + do ty::walk_ty(original_type) |t| { + match get(t).sty { + ty_enum(def_id, _) | + ty_trait(def_id, _, _) | + ty_struct(def_id, _) => { + if def_id.crate == ast::local_crate { + found_nominal = true; + } + } + + _ => { } + } + } + return found_nominal; +} + // Returns the def ID of the base type, if there is one. pub fn get_base_type_def_id(inference_context: @mut InferCtxt, span: span, @@ -142,18 +168,17 @@ pub fn method_to_MethodInfo(ast_method: @method) -> @MethodInfo { pub struct CoherenceInfo { // Contains implementations of methods that are inherent to a type. // Methods in these implementations don't need to be exported. - inherent_methods: HashMap, + inherent_methods: @mut LinearMap, // Contains implementations of methods associated with a trait. For these, // the associated trait must be imported at the call site. - extension_methods: HashMap, - + extension_methods: @mut LinearMap, } pub fn CoherenceInfo() -> CoherenceInfo { CoherenceInfo { - inherent_methods: HashMap(), - extension_methods: HashMap(), + inherent_methods: @mut LinearMap::new(), + extension_methods: @mut LinearMap::new(), } } @@ -162,8 +187,7 @@ pub fn CoherenceChecker(crate_context: @mut CrateCtxt) -> CoherenceChecker { crate_context: crate_context, inference_context: new_infer_ctxt(crate_context.tcx), - base_type_def_ids: HashMap(), - privileged_implementations: HashMap() + base_type_def_ids: HashMap() } } @@ -175,11 +199,6 @@ pub struct CoherenceChecker { // definition ID. base_type_def_ids: HashMap, - - // A set of implementations in privileged scopes; i.e. those - // implementations that are defined in the same scope as their base types. - - privileged_implementations: HashMap, } pub impl CoherenceChecker { @@ -380,7 +399,7 @@ pub impl CoherenceChecker { .insert(base_def_id, implementation_list); } Some(existing_implementation_list) => { - implementation_list = existing_implementation_list; + implementation_list = *existing_implementation_list; } } @@ -397,7 +416,7 @@ pub impl CoherenceChecker { .insert(trait_id, implementation_list); } Some(existing_implementation_list) => { - implementation_list = existing_implementation_list; + implementation_list = *existing_implementation_list; } } @@ -472,7 +491,7 @@ pub impl CoherenceChecker { match extension_methods.find(&trait_def_id) { Some(impls) => { - let impls: &mut ~[@Impl] = impls; + let impls: &mut ~[@Impl] = *impls; for uint::range(0, impls.len()) |i| { f(impls[i]); } @@ -616,27 +635,11 @@ pub impl CoherenceChecker { visit_mod(module_, item.span, item.id, (), visitor); } item_impl(_, opt_trait, _, _) => { - let mut ok = false; - match self.base_type_def_ids.find( - &local_def(item.id)) { - - None => { - // Nothing to do. - } - Some(base_type_def_id) => { - // Check to see whether the implementation is - // in the same crate as its base type. - - if base_type_def_id.crate == local_crate { - // Record that this implementation is OK. - self.privileged_implementations.insert - (item.id, ()); - ok = true; - } - } - } - - if !ok { + // `for_ty` is `Type` in `impl Trait for Type` + let for_ty = + ty::node_id_to_type(self.crate_context.tcx, + item.id); + if !type_is_defined_in_local_crate(for_ty) { // This implementation is not in scope of its base // type. This still might be OK if the trait is // defined in the same crate. @@ -656,25 +659,24 @@ pub impl CoherenceChecker { implement a trait or \ new type instead"); } - _ => () - } - for opt_trait.each |trait_ref| { - // This is OK if and only if the trait was - // defined in this crate. - - let trait_def_id = - self.trait_ref_to_trait_def_id( - *trait_ref); - - if trait_def_id.crate != local_crate { - let session = self.crate_context.tcx.sess; - session.span_err(item.span, - ~"cannot provide an \ - extension \ - implementation for a \ - trait not defined in \ - this crate"); + Some(trait_ref) => { + // This is OK if and only if the trait was + // defined in this crate. + + let trait_def_id = + self.trait_ref_to_trait_def_id( + trait_ref); + + if trait_def_id.crate != local_crate { + let session = self.crate_context.tcx.sess; + session.span_err(item.span, + ~"cannot provide an \ + extension \ + implementation for a \ + trait not defined in \ + this crate"); + } } } } diff --git a/src/librustc/middle/typeck/infer/lattice.rs b/src/librustc/middle/typeck/infer/lattice.rs index 1ce590647653e..a83d6f1755ecc 100644 --- a/src/librustc/middle/typeck/infer/lattice.rs +++ b/src/librustc/middle/typeck/infer/lattice.rs @@ -51,27 +51,23 @@ use util::common::indenter; use std::list; pub trait LatticeValue { - static fn sub(&self, cf: &CombineFields, a: &Self, b: &Self) -> ures; - static fn lub(&self, cf: &CombineFields, a: &Self, b: &Self) - -> cres; - static fn glb(&self, cf: &CombineFields, a: &Self, b: &Self) - -> cres; + fn sub(cf: &CombineFields, a: &Self, b: &Self) -> ures; + fn lub(cf: &CombineFields, a: &Self, b: &Self) -> cres; + fn glb(cf: &CombineFields, a: &Self, b: &Self) -> cres; } pub type LatticeOp = &'self fn(cf: &CombineFields, a: &T, b: &T) -> cres; impl LatticeValue for ty::t { - static fn sub(&self, cf: &CombineFields, a: &ty::t, b: &ty::t) -> ures { + fn sub(cf: &CombineFields, a: &ty::t, b: &ty::t) -> ures { Sub(*cf).tys(*a, *b).to_ures() } - static fn lub(&self, cf: &CombineFields, a: &ty::t, b: &ty::t) - -> cres { + fn lub(cf: &CombineFields, a: &ty::t, b: &ty::t) -> cres { Lub(*cf).tys(*a, *b) } - static fn glb(&self, cf: &CombineFields, a: &ty::t, b: &ty::t) - -> cres { + fn glb(cf: &CombineFields, a: &ty::t, b: &ty::t) -> cres { Glb(*cf).tys(*a, *b) } } diff --git a/src/librustc/middle/typeck/infer/mod.rs b/src/librustc/middle/typeck/infer/mod.rs index 11da6b60328ce..c376fef696c05 100644 --- a/src/librustc/middle/typeck/infer/mod.rs +++ b/src/librustc/middle/typeck/infer/mod.rs @@ -712,7 +712,7 @@ pub impl InferCtxt { let actual_ty = self.resolve_type_vars_if_possible(actual_ty); // Don't report an error if actual type is ty_err. - if ty::type_contains_err(actual_ty) { + if ty::type_is_error(actual_ty) { return; } let error_str = err.map_default(~"", |t_err| diff --git a/src/librustc/middle/typeck/infer/region_inference.rs b/src/librustc/middle/typeck/infer/region_inference.rs index 534e50e115f78..f0b5ce9ff60a5 100644 --- a/src/librustc/middle/typeck/infer/region_inference.rs +++ b/src/librustc/middle/typeck/infer/region_inference.rs @@ -563,7 +563,7 @@ enum Constraint { } impl cmp::Eq for Constraint { - pure fn eq(&self, other: &Constraint) -> bool { + fn eq(&self, other: &Constraint) -> bool { match ((*self), (*other)) { (ConstrainVarSubVar(v0a, v1a), ConstrainVarSubVar(v0b, v1b)) => { v0a == v0b && v1a == v1b @@ -579,11 +579,11 @@ impl cmp::Eq for Constraint { (ConstrainVarSubReg(*), _) => false } } - pure fn ne(&self, other: &Constraint) -> bool { !(*self).eq(other) } + fn ne(&self, other: &Constraint) -> bool { !(*self).eq(other) } } impl to_bytes::IterBytes for Constraint { - pure fn iter_bytes(&self, +lsb0: bool, f: to_bytes::Cb) { + fn iter_bytes(&self, +lsb0: bool, f: to_bytes::Cb) { match *self { ConstrainVarSubVar(ref v0, ref v1) => to_bytes::iter_bytes_3(&0u8, v0, v1, lsb0, f), @@ -603,14 +603,14 @@ struct TwoRegions { } impl cmp::Eq for TwoRegions { - pure fn eq(&self, other: &TwoRegions) -> bool { + fn eq(&self, other: &TwoRegions) -> bool { (*self).a == (*other).a && (*self).b == (*other).b } - pure fn ne(&self, other: &TwoRegions) -> bool { !(*self).eq(other) } + fn ne(&self, other: &TwoRegions) -> bool { !(*self).eq(other) } } impl to_bytes::IterBytes for TwoRegions { - pure fn iter_bytes(&self, +lsb0: bool, f: to_bytes::Cb) { + fn iter_bytes(&self, +lsb0: bool, f: to_bytes::Cb) { to_bytes::iter_bytes_2(&self.a, &self.b, lsb0, f) } } @@ -1175,10 +1175,10 @@ priv impl RegionVarBindings { // ______________________________________________________________________ -#[deriving_eq] +#[deriving(Eq)] enum Direction { Incoming = 0, Outgoing = 1 } -#[deriving_eq] +#[deriving(Eq)] enum Classification { Expanding, Contracting } enum GraphNodeValue { NoValue, Value(Region), ErrorValue } diff --git a/src/librustc/middle/typeck/infer/resolve.rs b/src/librustc/middle/typeck/infer/resolve.rs index 1d9594d930c6d..038dc524bec07 100644 --- a/src/librustc/middle/typeck/infer/resolve.rs +++ b/src/librustc/middle/typeck/infer/resolve.rs @@ -62,23 +62,23 @@ use syntax::ast; use core::vec; -pub const resolve_nested_tvar: uint = 0b0000000001; -pub const resolve_rvar: uint = 0b0000000010; -pub const resolve_ivar: uint = 0b0000000100; -pub const resolve_fvar: uint = 0b0000001000; -pub const resolve_fnvar: uint = 0b0000010000; -pub const resolve_all: uint = 0b0000011111; -pub const force_tvar: uint = 0b0000100000; -pub const force_rvar: uint = 0b0001000000; -pub const force_ivar: uint = 0b0010000000; -pub const force_fvar: uint = 0b0100000000; -pub const force_fnvar: uint = 0b1000000000; -pub const force_all: uint = 0b1111100000; - -pub const not_regions: uint = !(force_rvar | resolve_rvar); - -pub const try_resolve_tvar_shallow: uint = 0; -pub const resolve_and_force_all_but_regions: uint = +pub static resolve_nested_tvar: uint = 0b0000000001; +pub static resolve_rvar: uint = 0b0000000010; +pub static resolve_ivar: uint = 0b0000000100; +pub static resolve_fvar: uint = 0b0000001000; +pub static resolve_fnvar: uint = 0b0000010000; +pub static resolve_all: uint = 0b0000011111; +pub static force_tvar: uint = 0b0000100000; +pub static force_rvar: uint = 0b0001000000; +pub static force_ivar: uint = 0b0010000000; +pub static force_fvar: uint = 0b0100000000; +pub static force_fnvar: uint = 0b1000000000; +pub static force_all: uint = 0b1111100000; + +pub static not_regions: uint = !(force_rvar | resolve_rvar); + +pub static try_resolve_tvar_shallow: uint = 0; +pub static resolve_and_force_all_but_regions: uint = (resolve_all | force_all) & not_regions; pub struct ResolveState { diff --git a/src/librustc/middle/typeck/infer/test.rs b/src/librustc/middle/typeck/infer/test.rs index 867bcc30fa4ea..6a4def65fe744 100644 --- a/src/librustc/middle/typeck/infer/test.rs +++ b/src/librustc/middle/typeck/infer/test.rs @@ -47,7 +47,7 @@ struct RH { sub: &[RH] } -const EMPTY_SOURCE_STR: &str = "/* Hello, world! */"; +static EMPTY_SOURCE_STR: &str = "/* Hello, world! */"; fn setup_env(test_name: &str, source_string: &str) -> Env { let messages = @DVec(); diff --git a/src/librustc/middle/typeck/infer/unify.rs b/src/librustc/middle/typeck/infer/unify.rs index fe77b62de4376..7711794d91db5 100644 --- a/src/librustc/middle/typeck/infer/unify.rs +++ b/src/librustc/middle/typeck/infer/unify.rs @@ -35,8 +35,8 @@ pub struct Node { } pub trait UnifyVid { - static fn appropriate_vals_and_bindings(&self, infcx: &'v mut InferCtxt) - -> &'v mut ValsAndBindings; + fn appropriate_vals_and_bindings(infcx: &'v mut InferCtxt) + -> &'v mut ValsAndBindings; } pub impl InferCtxt { @@ -144,7 +144,7 @@ pub impl InferCtxt { // doesn't have a subtyping relationship we need to worry about. pub trait SimplyUnifiable { - static fn to_type_err(&self, expected_found) -> ty::type_err; + fn to_type_err(expected_found) -> ty::type_err; } pub fn mk_err(+a_is_expected: bool, @@ -235,36 +235,34 @@ pub impl InferCtxt { // ______________________________________________________________________ impl UnifyVid> for ty::TyVid { - static fn appropriate_vals_and_bindings(&self, infcx: &'v mut InferCtxt) + fn appropriate_vals_and_bindings(infcx: &'v mut InferCtxt) -> &'v mut ValsAndBindings> { return &mut infcx.ty_var_bindings; } } impl UnifyVid> for ty::IntVid { - static fn appropriate_vals_and_bindings(&self, infcx: &'v mut InferCtxt) + fn appropriate_vals_and_bindings(infcx: &'v mut InferCtxt) -> &'v mut ValsAndBindings> { return &mut infcx.int_var_bindings; } } impl SimplyUnifiable for IntVarValue { - static fn to_type_err(&self, err: expected_found) - -> ty::type_err { + fn to_type_err(err: expected_found) -> ty::type_err { return ty::terr_int_mismatch(err); } } impl UnifyVid> for ty::FloatVid { - static fn appropriate_vals_and_bindings(&self, infcx: &'v mut InferCtxt) + fn appropriate_vals_and_bindings(infcx: &'v mut InferCtxt) -> &'v mut ValsAndBindings> { return &mut infcx.float_var_bindings; } } impl SimplyUnifiable for ast::float_ty { - static fn to_type_err(&self, err: expected_found) - -> ty::type_err { + fn to_type_err(err: expected_found) -> ty::type_err { return ty::terr_float_mismatch(err); } } diff --git a/src/librustc/middle/typeck/mod.rs b/src/librustc/middle/typeck/mod.rs index ed1a3d33f4cc1..7724b43b50f85 100644 --- a/src/librustc/middle/typeck/mod.rs +++ b/src/librustc/middle/typeck/mod.rs @@ -51,8 +51,8 @@ independently: use core::prelude::*; use middle::resolve; -use middle::ty::{ty_param_substs_and_ty, vstore_uniq}; use middle::ty; +use util::common::time; use util::ppaux; use core::result; @@ -329,6 +329,7 @@ pub fn check_crate(tcx: ty::ctxt, trait_map: resolve::TraitMap, crate: @ast::crate) -> (method_map, vtable_map) { + let time_passes = tcx.sess.time_passes(); let ccx = @mut CrateCtxt { trait_map: trait_map, method_map: oldmap::HashMap(), @@ -336,10 +337,16 @@ pub fn check_crate(tcx: ty::ctxt, coherence_info: @coherence::CoherenceInfo(), tcx: tcx }; - collect::collect_item_types(ccx, crate); - coherence::check_coherence(ccx, crate); - check::check_item_types(ccx, crate); + time(time_passes, ~"type collecting", || + collect::collect_item_types(ccx, crate)); + + time(time_passes, ~"method resolution", || + coherence::check_coherence(ccx, crate)); + + time(time_passes, ~"type checking", || + check::check_item_types(ccx, crate)); + check_for_main_fn(ccx); tcx.sess.abort_if_errors(); (ccx.method_map, ccx.vtable_map) diff --git a/src/librustc/rustc.rc b/src/librustc/rustc.rc index 296c94f3299cb..6a778a8336190 100644 --- a/src/librustc/rustc.rc +++ b/src/librustc/rustc.rc @@ -24,7 +24,6 @@ #[allow(non_camel_case_types)]; #[allow(deprecated_mode)]; #[warn(deprecated_pattern)]; -#[deny(deprecated_self)]; #[no_core]; @@ -286,7 +285,7 @@ pub fn run_compiler(args: &~[~str], demitter: diagnostic::Emitter) { compile_input(sess, cfg, input, &odir, &ofile); } -#[deriving_eq] +#[deriving(Eq)] pub enum monitor_msg { fatal, done, diff --git a/src/librustc/util/common.rs b/src/librustc/util/common.rs index c7945f74f55a5..1cd3982c7e84b 100644 --- a/src/librustc/util/common.rs +++ b/src/librustc/util/common.rs @@ -16,6 +16,16 @@ use syntax::visit; use core::str; use std::oldmap::HashMap; +use std; + +pub fn time(do_it: bool, what: ~str, thunk: &fn() -> T) -> T { + if !do_it { return thunk(); } + let start = std::time::precise_time_s(); + let rv = thunk(); + let end = std::time::precise_time_s(); + io::println(fmt!("time: %3.3f s\t%s", end - start, what)); + rv +} pub fn indent(op: &fn() -> R) -> R { // Use in conjunction with the log post-processor like `src/etc/indenter` diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs index c332d3ac6744d..eb63d675d80af 100644 --- a/src/librustc/util/ppaux.rs +++ b/src/librustc/util/ppaux.rs @@ -488,7 +488,7 @@ pub fn parameterized(cx: ctxt, pub fn ty_to_short_str(cx: ctxt, typ: t) -> ~str { let mut s = encoder::encoded_ty(cx, typ); - if str::len(s) >= 32u { s = str::slice(s, 0u, 32u); } + if str::len(s) >= 32u { s = str::slice(s, 0u, 32u).to_owned(); } return s; } diff --git a/src/librustdoc/config.rs b/src/librustdoc/config.rs index 956d6ba2c5bfd..84f2f5191f31a 100644 --- a/src/librustdoc/config.rs +++ b/src/librustdoc/config.rs @@ -29,10 +29,10 @@ pub enum OutputFormat { } impl cmp::Eq for OutputFormat { - pure fn eq(&self, other: &OutputFormat) -> bool { + fn eq(&self, other: &OutputFormat) -> bool { ((*self) as uint) == ((*other) as uint) } - pure fn ne(&self, other: &OutputFormat) -> bool { !(*self).eq(other) } + fn ne(&self, other: &OutputFormat) -> bool { !(*self).eq(other) } } /// How to organize the output @@ -44,10 +44,10 @@ pub enum OutputStyle { } impl cmp::Eq for OutputStyle { - pure fn eq(&self, other: &OutputStyle) -> bool { + fn eq(&self, other: &OutputStyle) -> bool { ((*self) as uint) == ((*other) as uint) } - pure fn ne(&self, other: &OutputStyle) -> bool { !(*self).eq(other) } + fn ne(&self, other: &OutputStyle) -> bool { !(*self).eq(other) } } /// The configuration for a rustdoc session diff --git a/src/librustdoc/demo.rs b/src/librustdoc/demo.rs index ad57af8942d35..c5fb8f289f65e 100644 --- a/src/librustdoc/demo.rs +++ b/src/librustdoc/demo.rs @@ -24,7 +24,7 @@ use core::prelude::*; /// The base price of a muffin on a non-holiday -const price_of_a_muffin: float = 70f; +static price_of_a_muffin: float = 70f; struct WaitPerson { hair_color: ~str diff --git a/src/librustdoc/desc_to_brief_pass.rs b/src/librustdoc/desc_to_brief_pass.rs index 51574c2c3c7e5..957b94d18f532 100644 --- a/src/librustdoc/desc_to_brief_pass.rs +++ b/src/librustdoc/desc_to_brief_pass.rs @@ -127,8 +127,7 @@ fn extract(desc: Option<~str>) -> Option<~str> { } fn parse_desc(desc: ~str) -> Option<~str> { - - const max_brief_len: uint = 120u; + static max_brief_len: uint = 120u; match first_sentence(copy desc) { Some(first_sentence) => { @@ -171,7 +170,7 @@ fn first_sentence_(s: &str) -> ~str { }; match idx { Some(idx) if idx > 2u => { - str::from_slice(str::view(s, 0, idx - 1)) + str::from_slice(str::slice(s, 0, idx - 1)) } _ => { if str::ends_with(s, ~".") { diff --git a/src/librustdoc/doc.rs b/src/librustdoc/doc.rs index ae45f54941730..4ed510c353b55 100644 --- a/src/librustdoc/doc.rs +++ b/src/librustdoc/doc.rs @@ -19,18 +19,18 @@ use core::vec; pub type AstId = int; -#[deriving_eq] +#[deriving(Eq)] pub struct Doc { pages: ~[Page] } -#[deriving_eq] +#[deriving(Eq)] pub enum Page { CratePage(CrateDoc), ItemPage(ItemTag) } -#[deriving_eq] +#[deriving(Eq)] pub enum Implementation { Required, Provided, @@ -40,7 +40,7 @@ pub enum Implementation { * Most rustdocs can be parsed into 'sections' according to their markdown * headers */ -#[deriving_eq] +#[deriving(Eq)] pub struct Section { header: ~str, body: ~str @@ -49,12 +49,12 @@ pub struct Section { // FIXME (#2596): We currently give topmod the name of the crate. There // would probably be fewer special cases if the crate had its own name // and topmod's name was the empty string. -#[deriving_eq] +#[deriving(Eq)] pub struct CrateDoc { topmod: ModDoc } -#[deriving_eq] +#[deriving(Eq)] pub enum ItemTag { ModTag(ModDoc), NmodTag(NmodDoc), @@ -67,7 +67,7 @@ pub enum ItemTag { StructTag(StructDoc) } -#[deriving_eq] +#[deriving(Eq)] pub struct ItemDoc { id: AstId, name: ~str, @@ -79,20 +79,20 @@ pub struct ItemDoc { reexport: bool } -#[deriving_eq] +#[deriving(Eq)] pub struct SimpleItemDoc { item: ItemDoc, sig: Option<~str> } -#[deriving_eq] +#[deriving(Eq)] pub struct ModDoc { item: ItemDoc, items: ~[ItemTag], index: Option } -#[deriving_eq] +#[deriving(Eq)] pub struct NmodDoc { item: ItemDoc, fns: ~[FnDoc], @@ -103,26 +103,26 @@ pub type ConstDoc = SimpleItemDoc; pub type FnDoc = SimpleItemDoc; -#[deriving_eq] +#[deriving(Eq)] pub struct EnumDoc { item: ItemDoc, variants: ~[VariantDoc] } -#[deriving_eq] +#[deriving(Eq)] pub struct VariantDoc { name: ~str, desc: Option<~str>, sig: Option<~str> } -#[deriving_eq] +#[deriving(Eq)] pub struct TraitDoc { item: ItemDoc, methods: ~[MethodDoc] } -#[deriving_eq] +#[deriving(Eq)] pub struct MethodDoc { name: ~str, brief: Option<~str>, @@ -132,7 +132,7 @@ pub struct MethodDoc { implementation: Implementation, } -#[deriving_eq] +#[deriving(Eq)] pub struct ImplDoc { item: ItemDoc, trait_types: ~[~str], @@ -142,14 +142,14 @@ pub struct ImplDoc { pub type TyDoc = SimpleItemDoc; -#[deriving_eq] +#[deriving(Eq)] pub struct StructDoc { item: ItemDoc, fields: ~[~str], sig: Option<~str> } -#[deriving_eq] +#[deriving(Eq)] pub struct Index { entries: ~[IndexEntry] } @@ -164,7 +164,7 @@ pub struct Index { * * brief - The brief description * * link - A format-specific string representing the link target */ -#[deriving_eq] +#[deriving(Eq)] pub struct IndexEntry { kind: ~str, name: ~str, @@ -358,11 +358,11 @@ impl PageUtils for ~[Page] { } pub trait Item { - pure fn item(&self) -> ItemDoc; + fn item(&self) -> ItemDoc; } impl Item for ItemTag { - pure fn item(&self) -> ItemDoc { + fn item(&self) -> ItemDoc { match self { &doc::ModTag(ref doc) => copy doc.item, &doc::NmodTag(ref doc) => copy doc.item, @@ -378,64 +378,64 @@ impl Item for ItemTag { } impl Item for SimpleItemDoc { - pure fn item(&self) -> ItemDoc { copy self.item } + fn item(&self) -> ItemDoc { copy self.item } } impl Item for ModDoc { - pure fn item(&self) -> ItemDoc { copy self.item } + fn item(&self) -> ItemDoc { copy self.item } } impl Item for NmodDoc { - pure fn item(&self) -> ItemDoc { copy self.item } + fn item(&self) -> ItemDoc { copy self.item } } impl Item for EnumDoc { - pure fn item(&self) -> ItemDoc { copy self.item } + fn item(&self) -> ItemDoc { copy self.item } } impl Item for TraitDoc { - pure fn item(&self) -> ItemDoc { copy self.item } + fn item(&self) -> ItemDoc { copy self.item } } impl Item for ImplDoc { - pure fn item(&self) -> ItemDoc { copy self.item } + fn item(&self) -> ItemDoc { copy self.item } } impl Item for StructDoc { - pure fn item(&self) -> ItemDoc { copy self.item } + fn item(&self) -> ItemDoc { copy self.item } } pub trait ItemUtils { - pure fn id(&self) -> AstId; - pure fn name(&self) -> ~str; - pure fn path(&self) -> ~[~str]; - pure fn brief(&self) -> Option<~str>; - pure fn desc(&self) -> Option<~str>; - pure fn sections(&self) -> ~[Section]; + fn id(&self) -> AstId; + fn name(&self) -> ~str; + fn path(&self) -> ~[~str]; + fn brief(&self) -> Option<~str>; + fn desc(&self) -> Option<~str>; + fn sections(&self) -> ~[Section]; } impl ItemUtils for A { - pure fn id(&self) -> AstId { + fn id(&self) -> AstId { self.item().id } - pure fn name(&self) -> ~str { + fn name(&self) -> ~str { copy self.item().name } - pure fn path(&self) -> ~[~str] { + fn path(&self) -> ~[~str] { copy self.item().path } - pure fn brief(&self) -> Option<~str> { + fn brief(&self) -> Option<~str> { copy self.item().brief } - pure fn desc(&self) -> Option<~str> { + fn desc(&self) -> Option<~str> { copy self.item().desc } - pure fn sections(&self) -> ~[Section] { + fn sections(&self) -> ~[Section] { copy self.item().sections } } diff --git a/src/librustdoc/extract.rs b/src/librustdoc/extract.rs index 5e5c843da26da..942dd3e01cbd5 100644 --- a/src/librustdoc/extract.rs +++ b/src/librustdoc/extract.rs @@ -184,7 +184,7 @@ fn constdoc_from_const(itemdoc: doc::ItemDoc) -> doc::ConstDoc { #[test] fn should_extract_const_name_and_id() { - let doc = test::mk_doc(~"const a: int = 0;"); + let doc = test::mk_doc(~"static a: int = 0;"); fail_unless!(doc.cratemod().consts()[0].id() != 0); fail_unless!(doc.cratemod().consts()[0].name() == ~"a"); } diff --git a/src/librustdoc/fold.rs b/src/librustdoc/fold.rs index e9d9732d51fd3..2cd9ef3671d6e 100644 --- a/src/librustdoc/fold.rs +++ b/src/librustdoc/fold.rs @@ -378,7 +378,7 @@ fn default_fold_should_produce_same_doc() { #[test] fn default_fold_should_produce_same_consts() { - let source = ~"const a: int = 0;"; + let source = ~"static a: int = 0;"; let ast = parse::from_str(source); let doc = extract::extract(ast, ~""); let fld = default_seq_fold(()); diff --git a/src/librustdoc/markdown_pass.rs b/src/librustdoc/markdown_pass.rs index 70d5c730569e7..73f3aa53c250d 100644 --- a/src/librustdoc/markdown_pass.rs +++ b/src/librustdoc/markdown_pass.rs @@ -45,8 +45,8 @@ fn run( writer_factory: WriterFactory ) -> doc::Doc { - pure fn mods_last(item1: &doc::ItemTag, item2: &doc::ItemTag) -> bool { - pure fn is_mod(item: &doc::ItemTag) -> bool { + fn mods_last(item1: &doc::ItemTag, item2: &doc::ItemTag) -> bool { + fn is_mod(item: &doc::ItemTag) -> bool { match *item { doc::ModTag(_) => true, _ => false @@ -127,7 +127,7 @@ fn write_page(ctxt: &Ctxt, page: &doc::Page) { write_item_no_header(ctxt, doc); } } - ctxt.w.write_done(); + ctxt.w.put_done(); } #[test] @@ -146,8 +146,8 @@ fn should_request_new_writer_for_each_page() { } fn write_title(ctxt: &Ctxt, page: doc::Page) { - ctxt.w.write_line(fmt!("%% %s", make_title(page))); - ctxt.w.write_line(~""); + ctxt.w.put_line(fmt!("%% %s", make_title(page))); + ctxt.w.put_line(~""); } fn make_title(page: doc::Page) -> ~str { @@ -198,8 +198,8 @@ fn write_header(ctxt: &Ctxt, lvl: Hlvl, doc: doc::ItemTag) { fn write_header_(ctxt: &Ctxt, lvl: Hlvl, title: ~str) { let hashes = str::from_chars(vec::from_elem(lvl as uint, '#')); - ctxt.w.write_line(fmt!("%s %s", hashes, title)); - ctxt.w.write_line(~""); + ctxt.w.put_line(fmt!("%s %s", hashes, title)); + ctxt.w.put_line(~""); } pub fn header_kind(doc: doc::ItemTag) -> ~str { @@ -332,8 +332,8 @@ fn write_desc( ) { match desc { Some(desc) => { - ctxt.w.write_line(desc); - ctxt.w.write_line(~""); + ctxt.w.put_line(desc); + ctxt.w.put_line(~""); } None => () } @@ -347,8 +347,8 @@ fn write_sections(ctxt: &Ctxt, sections: &[doc::Section]) { fn write_section(ctxt: &Ctxt, section: doc::Section) { write_header_(ctxt, H4, copy section.header); - ctxt.w.write_line(copy section.body); - ctxt.w.write_line(~""); + ctxt.w.put_line(copy section.body); + ctxt.w.put_line(~""); } #[test] @@ -398,7 +398,7 @@ fn write_item_(ctxt: &Ctxt, doc: doc::ItemTag, write_header: bool) { doc::TraitTag(TraitDoc) => write_trait(ctxt, TraitDoc), doc::ImplTag(ImplDoc) => write_impl(ctxt, ImplDoc), doc::TyTag(TyDoc) => write_type(ctxt, TyDoc), - doc::StructTag(StructDoc) => write_struct(ctxt, StructDoc), + doc::StructTag(StructDoc) => put_struct(ctxt, StructDoc), } } @@ -428,13 +428,13 @@ fn write_index(ctxt: &Ctxt, index: doc::Index) { let header = header_text_(entry.kind, entry.name); let id = copy entry.link; if entry.brief.is_some() { - ctxt.w.write_line(fmt!("* [%s](%s) - %s", + ctxt.w.put_line(fmt!("* [%s](%s) - %s", header, id, (&entry.brief).get())); } else { - ctxt.w.write_line(fmt!("* [%s](%s)", header, id)); + ctxt.w.put_line(fmt!("* [%s](%s)", header, id)); } } - ctxt.w.write_line(~""); + ctxt.w.put_line(~""); } #[test] @@ -526,8 +526,8 @@ fn write_fnlike( fn write_sig(ctxt: &Ctxt, sig: Option<~str>) { match sig { Some(sig) => { - ctxt.w.write_line(code_block_indent(sig)); - ctxt.w.write_line(~""); + ctxt.w.put_line(code_block_indent(sig)); + ctxt.w.put_line(~""); } None => fail!(~"unimplemented") } @@ -594,7 +594,7 @@ fn write_const( #[test] fn should_write_const_header() { - let markdown = test::render(~"const a: bool = true;"); + let markdown = test::render(~"static a: bool = true;"); fail_unless!(str::contains(markdown, ~"## Const `a`\n\n")); } @@ -602,7 +602,7 @@ fn should_write_const_header() { fn should_write_const_description() { let markdown = test::render( ~"#[doc = \"b\"]\ - const a: bool = true;"); + static a: bool = true;"); fail_unless!(str::contains(markdown, ~"\n\nb\n\n")); } @@ -641,7 +641,7 @@ fn write_variants( write_variant(ctxt, copy *variant); } - ctxt.w.write_line(~""); + ctxt.w.put_line(~""); } fn write_variant(ctxt: &Ctxt, doc: doc::VariantDoc) { @@ -649,10 +649,10 @@ fn write_variant(ctxt: &Ctxt, doc: doc::VariantDoc) { let sig = (&doc.sig).get(); match copy doc.desc { Some(desc) => { - ctxt.w.write_line(fmt!("* `%s` - %s", sig, desc)); + ctxt.w.put_line(fmt!("* `%s` - %s", sig, desc)); } None => { - ctxt.w.write_line(fmt!("* `%s`", sig)); + ctxt.w.put_line(fmt!("* `%s`", sig)); } } } @@ -804,7 +804,7 @@ fn should_write_type_signature() { fail_unless!(str::contains(markdown, ~"\n\n type t = int\n\n")); } -fn write_struct( +fn put_struct( ctxt: &Ctxt, doc: doc::StructDoc ) { @@ -813,7 +813,7 @@ fn write_struct( } #[test] -fn should_write_struct_header() { +fn should_put_struct_header() { let markdown = test::render(~"struct S { field: () }"); fail_unless!(str::contains(markdown, ~"## Struct `S`\n\n")); } diff --git a/src/librustdoc/markdown_writer.rs b/src/librustdoc/markdown_writer.rs index 45fef5b80b814..4c68e632f83eb 100644 --- a/src/librustdoc/markdown_writer.rs +++ b/src/librustdoc/markdown_writer.rs @@ -34,21 +34,21 @@ pub type Writer = ~fn(v: WriteInstr); pub type WriterFactory = ~fn(page: doc::Page) -> Writer; pub trait WriterUtils { - fn write_str(&self, +str: ~str); - fn write_line(&self, +str: ~str); - fn write_done(&self); + fn put_str(&self, +str: ~str); + fn put_line(&self, +str: ~str); + fn put_done(&self); } impl WriterUtils for Writer { - fn write_str(&self, str: ~str) { + fn put_str(&self, str: ~str) { (*self)(Write(str)); } - fn write_line(&self, str: ~str) { - self.write_str(str + ~"\n"); + fn put_line(&self, str: ~str) { + self.put_str(str + ~"\n"); } - fn write_done(&self) { + fn put_done(&self) { (*self)(Done) } } @@ -157,7 +157,7 @@ fn readclose(fd: libc::c_int) -> ~str { let mut bytes = [0, ..4096]; while !reader.eof() { let nread = reader.read(bytes, bytes.len()); - writer.write(bytes.view(0, nread)); + writer.write(bytes.slice(0, nread).to_owned()); } }); os::fclose(file); diff --git a/src/librustdoc/rustdoc.rc b/src/librustdoc/rustdoc.rc index 5cae8e31657ea..9eb3e81662806 100644 --- a/src/librustdoc/rustdoc.rc +++ b/src/librustdoc/rustdoc.rc @@ -22,7 +22,6 @@ #[no_core]; #[allow(non_implicitly_copyable_typarams)]; -#[deny(deprecated_self)]; extern mod core(vers = "0.6"); extern mod std(vers = "0.6"); diff --git a/src/librustdoc/sectionalize_pass.rs b/src/librustdoc/sectionalize_pass.rs index e64d4ccf69e7c..8b058048ff4ac 100644 --- a/src/librustdoc/sectionalize_pass.rs +++ b/src/librustdoc/sectionalize_pass.rs @@ -154,7 +154,7 @@ fn sectionalize(desc: Option<~str>) -> (Option<~str>, ~[doc::Section]) { fn parse_header(line: ~str) -> Option<~str> { if str::starts_with(line, ~"# ") { - Some(str::slice(line, 2u, str::len(line))) + Some(str::slice(line, 2u, str::len(line)).to_owned()) } else { None } diff --git a/src/librustdoc/sort_item_name_pass.rs b/src/librustdoc/sort_item_name_pass.rs index 0e6d83fa45f3b..b3fb874cdb260 100644 --- a/src/librustdoc/sort_item_name_pass.rs +++ b/src/librustdoc/sort_item_name_pass.rs @@ -16,7 +16,7 @@ use pass::Pass; use sort_pass; pub fn mk_pass() -> Pass { - pure fn by_item_name(item1: &doc::ItemTag, item2: &doc::ItemTag) -> bool { + fn by_item_name(item1: &doc::ItemTag, item2: &doc::ItemTag) -> bool { (*item1).name() <= (*item2).name() } sort_pass::mk_pass(~"sort_item_name", by_item_name) diff --git a/src/librustdoc/sort_item_type_pass.rs b/src/librustdoc/sort_item_type_pass.rs index cddd5068816cd..5919f1b0c2fbe 100644 --- a/src/librustdoc/sort_item_type_pass.rs +++ b/src/librustdoc/sort_item_type_pass.rs @@ -15,8 +15,8 @@ use pass::Pass; use sort_pass; pub fn mk_pass() -> Pass { - pure fn by_score(item1: &doc::ItemTag, item2: &doc::ItemTag) -> bool { - pure fn score(item: &doc::ItemTag) -> int { + fn by_score(item1: &doc::ItemTag, item2: &doc::ItemTag) -> bool { + fn score(item: &doc::ItemTag) -> int { match *item { doc::ConstTag(_) => 0, doc::TyTag(_) => 1, @@ -45,7 +45,7 @@ fn test() { ~"mod imod { } \ extern mod inmod { } \ - const iconst: int = 0; \ + static iconst: int = 0; \ fn ifn() { } \ enum ienum { ivar } \ trait itrait { fn a(); } \ diff --git a/src/librustdoc/sort_pass.rs b/src/librustdoc/sort_pass.rs index 4f4c5ea65d4d8..e66eb3c0fae30 100644 --- a/src/librustdoc/sort_pass.rs +++ b/src/librustdoc/sort_pass.rs @@ -21,7 +21,7 @@ use util::NominalOp; use std::sort; -pub type ItemLtEqOp = @pure fn(v1: &doc::ItemTag, v2: &doc::ItemTag) -> bool; +pub type ItemLtEqOp = @fn(v1: &doc::ItemTag, v2: &doc::ItemTag) -> bool; type ItemLtEq = NominalOp; @@ -59,7 +59,7 @@ fn fold_mod( #[test] fn test() { - pure fn name_lteq(item1: &doc::ItemTag, item2: &doc::ItemTag) -> bool { + fn name_lteq(item1: &doc::ItemTag, item2: &doc::ItemTag) -> bool { (*item1).name() <= (*item2).name() } @@ -76,7 +76,7 @@ fn test() { #[test] fn should_be_stable() { - pure fn always_eq(_item1: &doc::ItemTag, _item2: &doc::ItemTag) -> bool { + fn always_eq(_item1: &doc::ItemTag, _item2: &doc::ItemTag) -> bool { true } diff --git a/src/librustdoc/text_pass.rs b/src/librustdoc/text_pass.rs index 797f276de0a6e..65e7228eeaea2 100644 --- a/src/librustdoc/text_pass.rs +++ b/src/librustdoc/text_pass.rs @@ -311,7 +311,7 @@ mod test { let doc = (attr_pass::mk_pass().f)(srv.clone(), doc); let doc = (desc_to_brief_pass::mk_pass().f)(srv.clone(), doc); let doc = (sectionalize_pass::mk_pass().f)(srv.clone(), doc); - (mk_pass(~"", |s| str::trim(s) ).f)(srv.clone(), doc) + (mk_pass(~"", |s| str::trim(s).to_owned() ).f)(srv.clone(), doc) } } } diff --git a/src/librustdoc/trim_pass.rs b/src/librustdoc/trim_pass.rs index 58d629163e2ea..a1439e2e14932 100644 --- a/src/librustdoc/trim_pass.rs +++ b/src/librustdoc/trim_pass.rs @@ -18,10 +18,8 @@ is interpreted as the brief description. use pass::Pass; use text_pass; -use core::str; - pub fn mk_pass() -> Pass { - text_pass::mk_pass(~"trim", |s| str::trim(s) ) + text_pass::mk_pass(~"trim", |s| s.trim().to_owned() ) } #[test] diff --git a/src/librustdoc/tystr_pass.rs b/src/librustdoc/tystr_pass.rs index 638274d0bb8ee..8289de4e4e712 100644 --- a/src/librustdoc/tystr_pass.rs +++ b/src/librustdoc/tystr_pass.rs @@ -69,13 +69,13 @@ fn get_fn_sig(srv: astsrv::Srv, fn_id: doc::AstId) -> Option<~str> { match ctxt.ast_map.get(&fn_id) { ast_map::node_item(@ast::item { ident: ident, - node: ast::item_fn(ref decl, _, ref tys, _), _ + node: ast::item_fn(ref decl, purity, ref tys, _), _ }, _) | ast_map::node_foreign_item(@ast::foreign_item { ident: ident, - node: ast::foreign_item_fn(ref decl, _, ref tys), _ + node: ast::foreign_item_fn(ref decl, purity, ref tys), _ }, _, _, _) => { - Some(pprust::fun_to_str(decl, ident, None, tys, + Some(pprust::fun_to_str(decl, purity, ident, None, tys, extract::interner())) } _ => fail!(~"get_fn_sig: fn_id not bound to a fn item") @@ -121,7 +121,7 @@ fn fold_const( #[test] fn should_add_const_types() { - let doc = test::mk_doc(~"const a: bool = true;"); + let doc = test::mk_doc(~"static a: bool = true;"); fail_unless!(doc.cratemod().consts()[0].sig == Some(~"bool")); } @@ -214,6 +214,7 @@ fn get_method_sig( ast::required(ty_m) => { Some(pprust::fun_to_str( &ty_m.decl, + ty_m.purity, ty_m.ident, Some(ty_m.self_ty.node), &ty_m.generics, @@ -223,6 +224,7 @@ fn get_method_sig( ast::provided(m) => { Some(pprust::fun_to_str( &m.decl, + m.purity, m.ident, Some(m.self_ty.node), &m.generics, @@ -243,6 +245,7 @@ fn get_method_sig( Some(method) => { Some(pprust::fun_to_str( &method.decl, + method.purity, method.ident, Some(method.self_ty.node), &method.generics, diff --git a/src/librustdoc/unindent_pass.rs b/src/librustdoc/unindent_pass.rs index 6edf53785cbb9..ecd72950468e1 100644 --- a/src/librustdoc/unindent_pass.rs +++ b/src/librustdoc/unindent_pass.rs @@ -78,13 +78,13 @@ fn unindent(s: &str) -> ~str { }; if !lines.is_empty() { - let unindented = ~[lines.head().trim()] + let unindented = ~[lines.head().trim().to_owned()] + do lines.tail().map |line| { if str::is_whitespace(*line) { copy *line } else { fail_unless!(str::len(*line) >= min_indent); - str::slice(*line, min_indent, str::len(*line)) + str::slice(*line, min_indent, str::len(*line)).to_owned() } }; str::connect(unindented, ~"\n") diff --git a/src/librusti/rusti.rc b/src/librusti/rusti.rc index 182cfc43ade9e..e04cc9e389840 100644 --- a/src/librusti/rusti.rc +++ b/src/librusti/rusti.rc @@ -22,7 +22,6 @@ #[allow(vecs_implicitly_copyable, non_implicitly_copyable_typarams)]; -#[deny(deprecated_self)]; extern mod core(vers = "0.6"); extern mod std(vers = "0.6"); @@ -283,7 +282,7 @@ fn run_cmd(repl: &mut Repl, _in: @io::Reader, _out: @io::Writer, for args.each |arg| { let (crate, filename) = if arg.ends_with(".rs") || arg.ends_with(".rc") { - (arg.substr(0, arg.len() - 3), *arg) + (arg.substr(0, arg.len() - 3).to_owned(), *arg) } else { (*arg, arg + ~".rs") }; @@ -386,6 +385,10 @@ pub fn main() { stmts: ~"" }; + io::println("WARNING: The Rust REPL is experimental and may be"); + io::println("unstable. If you encounter problems, please use the"); + io::println("compiler instead."); + unsafe { do rl::complete |line, suggest| { if line.starts_with(":") { diff --git a/src/librustpkg/rustpkg.rc b/src/librustpkg/rustpkg.rc index 5b9f3c3cd229e..2032969fbca6c 100644 --- a/src/librustpkg/rustpkg.rc +++ b/src/librustpkg/rustpkg.rc @@ -20,7 +20,6 @@ #[no_core]; #[allow(vecs_implicitly_copyable, non_implicitly_copyable_typarams)]; -#[deny(deprecated_self)]; extern mod core(vers = "0.6"); extern mod std(vers = "0.6"); @@ -57,7 +56,7 @@ struct PackageScript { } impl PackageScript { - static fn parse(parent: &Path) -> Result { + fn parse(parent: &Path) -> Result { let script = parent.push(~"pkg.rs"); if !os::path_exists(&script) { @@ -867,6 +866,9 @@ impl Ctx { } pub fn main() { + io::println("WARNING: The Rust package manager is experimental and may"); + io::println("be unstable."); + let args = os::args(); let opts = ~[getopts::optflag(~"h"), getopts::optflag(~"help"), getopts::optflag(~"j"), getopts::optflag(~"json"), diff --git a/src/librustpkg/util.rs b/src/librustpkg/util.rs index 0572cf771dbed..8e5d7e95ae17a 100644 --- a/src/librustpkg/util.rs +++ b/src/librustpkg/util.rs @@ -139,7 +139,7 @@ fn add_pkg_module(ctx: @mut ReadyCtx, m: ast::_mod) -> ast::_mod { let item = quote_item! ( mod __pkg { extern mod rustpkg (vers="0.6"); - const listeners : &[rustpkg::Listener] = $listeners; + static listeners : &[rustpkg::Listener] = $listeners; #[main] fn main() { rustpkg::run(listeners); diff --git a/src/libstd/arc.rs b/src/libstd/arc.rs index 5a08884777c18..d037acff0ede7 100644 --- a/src/libstd/arc.rs +++ b/src/libstd/arc.rs @@ -25,13 +25,13 @@ use core::ptr; use core::task; /// As sync::condvar, a mechanism for unlock-and-descheduling and signalling. -pub struct Condvar { +pub struct Condvar<'self> { is_mutex: bool, failed: &'self mut bool, - cond: &'self sync::Condvar/&self + cond: &'self sync::Condvar<'self> } -pub impl Condvar/&self { +pub impl<'self> Condvar<'self> { /// Atomically exit the associated ARC and block until a signal is sent. #[inline(always)] fn wait(&self) { self.wait_on(0) } @@ -375,7 +375,7 @@ pub impl RWARC { } /// To be called inside of the write_downgrade block. - fn downgrade(&self, token: RWWriteMode/&a) -> RWReadMode/&a { + fn downgrade(&self, token: RWWriteMode<'a, T>) -> RWReadMode<'a, T> { // The rwlock should assert that the token belongs to us for us. let state = unsafe { get_shared_immutable_state(&self.x) }; let RWWriteMode { @@ -420,7 +420,7 @@ pub struct RWReadMode<'self, T> { token: sync::RWlockReadMode<'self>, } -pub impl RWWriteMode/&self { +pub impl RWWriteMode<'self, T> { /// Access the pre-downgrade RWARC in write mode. fn write(&self, blk: &fn(x: &mut T) -> U) -> U { match *self { @@ -458,7 +458,7 @@ pub impl RWWriteMode/&self { } } -pub impl RWReadMode/&self { +pub impl RWReadMode<'self, T> { /// Access the post-downgrade rwlock in read mode. fn read(&self, blk: &fn(x: &T) -> U) -> U { match *self { diff --git a/src/libstd/arena.rs b/src/libstd/arena.rs index 68132a1c08d02..a26132d92ca01 100644 --- a/src/libstd/arena.rs +++ b/src/libstd/arena.rs @@ -68,7 +68,7 @@ pub mod rustrt { // This probably belongs somewhere else. Needs to be kept in sync with // changes to glue... -const tydesc_drop_glue_index: size_t = 3 as size_t; +static tydesc_drop_glue_index: size_t = 3 as size_t; // The way arena uses arrays is really deeply awful. The arrays are // allocated, and have capacities reserved, but the fill for the array @@ -88,6 +88,7 @@ pub struct Arena { priv mut chunks: @List, } +#[unsafe_destructor] impl Drop for Arena { fn finalize(&self) { unsafe { @@ -122,7 +123,7 @@ pub fn Arena() -> Arena { } #[inline(always)] -pure fn round_up_to(base: uint, align: uint) -> uint { +fn round_up_to(base: uint, align: uint) -> uint { (base + (align - 1)) & !(align - 1) } diff --git a/src/libstd/base64.rs b/src/libstd/base64.rs index 56ce54be44e01..ff026324404ab 100644 --- a/src/libstd/base64.rs +++ b/src/libstd/base64.rs @@ -13,11 +13,11 @@ use core::str; use core::vec; pub trait ToBase64 { - pure fn to_base64(&self) -> ~str; + fn to_base64(&self) -> ~str; } impl ToBase64 for &'self [u8] { - pure fn to_base64(&self) -> ~str { + fn to_base64(&self) -> ~str { let chars = str::chars( ~"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/" ); @@ -70,17 +70,17 @@ impl ToBase64 for &'self [u8] { } impl ToBase64 for &'self str { - pure fn to_base64(&self) -> ~str { + fn to_base64(&self) -> ~str { str::to_bytes(*self).to_base64() } } pub trait FromBase64 { - pure fn from_base64(&self) -> ~[u8]; + fn from_base64(&self) -> ~[u8]; } impl FromBase64 for ~[u8] { - pure fn from_base64(&self) -> ~[u8] { + fn from_base64(&self) -> ~[u8] { if self.len() % 4u != 0u { fail!(~"invalid base64 length"); } let len = self.len(); @@ -142,7 +142,7 @@ impl FromBase64 for ~[u8] { } impl FromBase64 for ~str { - pure fn from_base64(&self) -> ~[u8] { + fn from_base64(&self) -> ~[u8] { str::to_bytes(*self).from_base64() } } diff --git a/src/libstd/bigint.rs b/src/libstd/bigint.rs index e128859bb7dde..7d20eb7b891fe 100644 --- a/src/libstd/bigint.rs +++ b/src/libstd/bigint.rs @@ -44,25 +44,25 @@ pub mod BigDigit { #[cfg(target_arch = "x86")] #[cfg(target_arch = "arm")] #[cfg(target_arch = "mips")] - pub const bits: uint = 16; + pub static bits: uint = 16; #[cfg(target_arch = "x86_64")] - pub const bits: uint = 32; + pub static bits: uint = 32; - pub const base: uint = 1 << bits; - priv const hi_mask: uint = (-1 as uint) << bits; - priv const lo_mask: uint = (-1 as uint) >> bits; + pub static base: uint = 1 << bits; + priv static hi_mask: uint = (-1 as uint) << bits; + priv static lo_mask: uint = (-1 as uint) >> bits; - priv pure fn get_hi(n: uint) -> BigDigit { (n >> bits) as BigDigit } - priv pure fn get_lo(n: uint) -> BigDigit { (n & lo_mask) as BigDigit } + priv fn get_hi(n: uint) -> BigDigit { (n >> bits) as BigDigit } + priv fn get_lo(n: uint) -> BigDigit { (n & lo_mask) as BigDigit } /// Split one machine sized unsigned integer into two BigDigits. - pub pure fn from_uint(n: uint) -> (BigDigit, BigDigit) { + pub fn from_uint(n: uint) -> (BigDigit, BigDigit) { (get_hi(n), get_lo(n)) } /// Join two BigDigits into one machine sized unsigned integer - pub pure fn to_uint(hi: BigDigit, lo: BigDigit) -> uint { + pub fn to_uint(hi: BigDigit, lo: BigDigit) -> uint { (lo as uint) | ((hi as uint) << bits) } } @@ -78,29 +78,29 @@ pub struct BigUint { } impl Eq for BigUint { - pure fn eq(&self, other: &BigUint) -> bool { self.cmp(other) == 0 } - pure fn ne(&self, other: &BigUint) -> bool { self.cmp(other) != 0 } + fn eq(&self, other: &BigUint) -> bool { self.cmp(other) == 0 } + fn ne(&self, other: &BigUint) -> bool { self.cmp(other) != 0 } } impl Ord for BigUint { - pure fn lt(&self, other: &BigUint) -> bool { self.cmp(other) < 0 } - pure fn le(&self, other: &BigUint) -> bool { self.cmp(other) <= 0 } - pure fn ge(&self, other: &BigUint) -> bool { self.cmp(other) >= 0 } - pure fn gt(&self, other: &BigUint) -> bool { self.cmp(other) > 0 } + fn lt(&self, other: &BigUint) -> bool { self.cmp(other) < 0 } + fn le(&self, other: &BigUint) -> bool { self.cmp(other) <= 0 } + fn ge(&self, other: &BigUint) -> bool { self.cmp(other) >= 0 } + fn gt(&self, other: &BigUint) -> bool { self.cmp(other) > 0 } } impl ToStr for BigUint { - pure fn to_str(&self) -> ~str { self.to_str_radix(10) } + fn to_str(&self) -> ~str { self.to_str_radix(10) } } impl from_str::FromStr for BigUint { - static pure fn from_str(s: &str) -> Option { + fn from_str(s: &str) -> Option { BigUint::from_str_radix(s, 10) } } impl Shl for BigUint { - pure fn shl(&self, rhs: &uint) -> BigUint { + fn shl(&self, rhs: &uint) -> BigUint { let n_unit = *rhs / BigDigit::bits; let n_bits = *rhs % BigDigit::bits; return self.shl_unit(n_unit).shl_bits(n_bits); @@ -108,7 +108,7 @@ impl Shl for BigUint { } impl Shr for BigUint { - pure fn shr(&self, rhs: &uint) -> BigUint { + fn shr(&self, rhs: &uint) -> BigUint { let n_unit = *rhs / BigDigit::bits; let n_bits = *rhs % BigDigit::bits; return self.shr_unit(n_unit).shr_bits(n_bits); @@ -116,15 +116,15 @@ impl Shr for BigUint { } impl Zero for BigUint { - static pure fn zero() -> BigUint { BigUint::new(~[]) } + fn zero() -> BigUint { BigUint::new(~[]) } } impl One for BigUint { - static pub pure fn one() -> BigUint { BigUint::new(~[1]) } + pub fn one() -> BigUint { BigUint::new(~[1]) } } impl Add for BigUint { - pure fn add(&self, other: &BigUint) -> BigUint { + fn add(&self, other: &BigUint) -> BigUint { let new_len = uint::max(self.data.len(), other.data.len()); let mut carry = 0; @@ -143,7 +143,7 @@ impl Add for BigUint { } impl Sub for BigUint { - pure fn sub(&self, other: &BigUint) -> BigUint { + fn sub(&self, other: &BigUint) -> BigUint { let new_len = uint::max(self.data.len(), other.data.len()); let mut borrow = 0; @@ -168,7 +168,7 @@ impl Sub for BigUint { } impl Mul for BigUint { - pure fn mul(&self, other: &BigUint) -> BigUint { + fn mul(&self, other: &BigUint) -> BigUint { if self.is_zero() || other.is_zero() { return Zero::zero(); } let s_len = self.data.len(), o_len = other.data.len(); @@ -200,7 +200,7 @@ impl Mul for BigUint { return ll + mm.shl_unit(half_len) + hh.shl_unit(half_len * 2); - pure fn mul_digit(a: &BigUint, n: BigDigit) -> BigUint { + fn mul_digit(a: &BigUint, n: BigDigit) -> BigUint { if n == 0 { return Zero::zero(); } if n == 1 { return copy *a; } @@ -216,14 +216,14 @@ impl Mul for BigUint { return BigUint::new(prod + [carry]); } - pure fn cut_at(a: &BigUint, n: uint) -> (BigUint, BigUint) { + fn cut_at(a: &BigUint, n: uint) -> (BigUint, BigUint) { let mid = uint::min(a.data.len(), n); return (BigUint::from_slice(vec::slice(a.data, mid, a.data.len())), BigUint::from_slice(vec::slice(a.data, 0, mid))); } - pure fn sub_sign(a: BigUint, b: BigUint) -> (int, BigUint) { + fn sub_sign(a: BigUint, b: BigUint) -> (int, BigUint) { match a.cmp(&b) { s if s < 0 => (s, b - a), s if s > 0 => (s, a - b), @@ -234,36 +234,36 @@ impl Mul for BigUint { } impl Div for BigUint { - pure fn div(&self, other: &BigUint) -> BigUint { + fn div(&self, other: &BigUint) -> BigUint { let (d, _) = self.divmod(other); return d; } } impl Modulo for BigUint { - pure fn modulo(&self, other: &BigUint) -> BigUint { + fn modulo(&self, other: &BigUint) -> BigUint { let (_, m) = self.divmod(other); return m; } } impl Neg for BigUint { - pure fn neg(&self) -> BigUint { fail!() } + fn neg(&self) -> BigUint { fail!() } } impl IntConvertible for BigUint { - pure fn to_int(&self) -> int { + fn to_int(&self) -> int { uint::min(self.to_uint(), int::max_value as uint) as int } - static pure fn from_int(n: int) -> BigUint { + fn from_int(n: int) -> BigUint { if (n < 0) { Zero::zero() } else { BigUint::from_uint(n as uint) } } } pub impl BigUint { /// Creates and initializes an BigUint. - static pub pure fn new(v: ~[BigDigit]) -> BigUint { + pub fn new(v: ~[BigDigit]) -> BigUint { // omit trailing zeros let new_len = v.rposition(|n| *n != 0).map_default(0, |p| *p + 1); @@ -274,7 +274,7 @@ pub impl BigUint { } /// Creates and initializes an BigUint. - static pub pure fn from_uint(n: uint) -> BigUint { + pub fn from_uint(n: uint) -> BigUint { match BigDigit::from_uint(n) { (0, 0) => Zero::zero(), (0, n0) => BigUint::new(~[n0]), @@ -283,18 +283,18 @@ pub impl BigUint { } /// Creates and initializes an BigUint. - static pub pure fn from_slice(slice: &[BigDigit]) -> BigUint { + pub fn from_slice(slice: &[BigDigit]) -> BigUint { return BigUint::new(vec::from_slice(slice)); } /// Creates and initializes an BigUint. - static pub pure fn from_str_radix(s: &str, radix: uint) + pub fn from_str_radix(s: &str, radix: uint) -> Option { BigUint::parse_bytes(str::to_bytes(s), radix) } /// Creates and initializes an BigUint. - static pub pure fn parse_bytes(buf: &[u8], radix: uint) + pub fn parse_bytes(buf: &[u8], radix: uint) -> Option { let (base, unit_len) = get_radix_base(radix); let base_num: BigUint = BigUint::from_uint(base); @@ -316,15 +316,15 @@ pub impl BigUint { } } - pure fn abs(&self) -> BigUint { copy *self } + fn abs(&self) -> BigUint { copy *self } /// Compare two BigUint value. - pure fn cmp(&self, other: &BigUint) -> int { + fn cmp(&self, other: &BigUint) -> int { let s_len = self.data.len(), o_len = other.data.len(); if s_len < o_len { return -1; } if s_len > o_len { return 1; } - for vec::rev_eachi(self.data) |i, elm| { + for self.data.eachi_reverse |i, elm| { match (*elm, other.data[i]) { (l, r) if l < r => return -1, (l, r) if l > r => return 1, @@ -334,7 +334,7 @@ pub impl BigUint { return 0; } - pure fn divmod(&self, other: &BigUint) -> (BigUint, BigUint) { + fn divmod(&self, other: &BigUint) -> (BigUint, BigUint) { if other.is_zero() { fail!() } if self.is_zero() { return (Zero::zero(), Zero::zero()); } if *other == One::one() { return (copy *self, Zero::zero()); } @@ -355,7 +355,7 @@ pub impl BigUint { let (d, m) = divmod_inner(self << shift, other << shift); return (d, m >> shift); - pure fn divmod_inner(a: BigUint, b: BigUint) -> (BigUint, BigUint) { + fn divmod_inner(a: BigUint, b: BigUint) -> (BigUint, BigUint) { let mut r = a; let mut d = Zero::zero::(); let mut n = 1; @@ -377,7 +377,7 @@ pub impl BigUint { return (d, r); } - pure fn div_estimate(a: &BigUint, b: &BigUint, n: uint) + fn div_estimate(a: &BigUint, b: &BigUint, n: uint) -> (BigUint, BigUint, BigUint) { if a.data.len() < n { return (Zero::zero(), Zero::zero(), copy *a); @@ -387,7 +387,7 @@ pub impl BigUint { let bn = *b.data.last(); let mut d = ~[]; let mut carry = 0; - for vec::rev_each(an) |elt| { + for an.each_reverse |elt| { let ai = BigDigit::to_uint(carry, *elt); let di = ai / (bn as uint); fail_unless!(di < BigDigit::base); @@ -405,26 +405,26 @@ pub impl BigUint { } } - pure fn quot(&self, other: &BigUint) -> BigUint { + fn quot(&self, other: &BigUint) -> BigUint { let (q, _) = self.quotrem(other); return q; } - pure fn rem(&self, other: &BigUint) -> BigUint { + fn rem(&self, other: &BigUint) -> BigUint { let (_, r) = self.quotrem(other); return r; } - pure fn quotrem(&self, other: &BigUint) -> (BigUint, BigUint) { + fn quotrem(&self, other: &BigUint) -> (BigUint, BigUint) { self.divmod(other) } - pure fn is_zero(&self) -> bool { self.data.is_empty() } - pure fn is_not_zero(&self) -> bool { !self.data.is_empty() } - pure fn is_positive(&self) -> bool { self.is_not_zero() } - pure fn is_negative(&self) -> bool { false } - pure fn is_nonpositive(&self) -> bool { self.is_zero() } - pure fn is_nonnegative(&self) -> bool { true } + fn is_zero(&self) -> bool { self.data.is_empty() } + fn is_not_zero(&self) -> bool { !self.data.is_empty() } + fn is_positive(&self) -> bool { self.is_not_zero() } + fn is_negative(&self) -> bool { false } + fn is_nonpositive(&self) -> bool { self.is_zero() } + fn is_nonnegative(&self) -> bool { true } - pure fn to_uint(&self) -> uint { + fn to_uint(&self) -> uint { match self.data.len() { 0 => 0, 1 => self.data[0] as uint, @@ -433,7 +433,7 @@ pub impl BigUint { } } - pure fn to_str_radix(&self, radix: uint) -> ~str { + fn to_str_radix(&self, radix: uint) -> ~str { fail_unless!(1 < radix && radix <= 16); let (base, max_len) = get_radix_base(radix); if base == BigDigit::base { @@ -441,7 +441,7 @@ pub impl BigUint { } return fill_concat(convert_base(copy *self, base), radix, max_len); - pure fn convert_base(n: BigUint, base: uint) -> ~[BigDigit] { + fn convert_base(n: BigUint, base: uint) -> ~[BigDigit] { let divider = BigUint::from_uint(base); let mut result = ~[]; let mut r = n; @@ -456,22 +456,23 @@ pub impl BigUint { return result; } - pure fn fill_concat(v: &[BigDigit], radix: uint, l: uint) -> ~str { + fn fill_concat(v: &[BigDigit], radix: uint, l: uint) -> ~str { if v.is_empty() { return ~"0" } - str::trim_left_chars(str::concat(vec::reversed(v).map(|n| { + let s = str::concat(vec::reversed(v).map(|n| { let s = uint::to_str_radix(*n as uint, radix); str::from_chars(vec::from_elem(l - s.len(), '0')) + s - })), ['0']) + })); + str::trim_left_chars(s, ['0']).to_owned() } } - priv pure fn shl_unit(self, n_unit: uint) -> BigUint { + priv fn shl_unit(self, n_unit: uint) -> BigUint { if n_unit == 0 || self.is_zero() { return self; } return BigUint::new(vec::from_elem(n_unit, 0) + self.data); } - priv pure fn shl_bits(self, n_bits: uint) -> BigUint { + priv fn shl_bits(self, n_bits: uint) -> BigUint { if n_bits == 0 || self.is_zero() { return self; } let mut carry = 0; @@ -486,7 +487,7 @@ pub impl BigUint { return BigUint::new(shifted + [carry]); } - priv pure fn shr_unit(self, n_unit: uint) -> BigUint { + priv fn shr_unit(self, n_unit: uint) -> BigUint { if n_unit == 0 { return self; } if self.data.len() < n_unit { return Zero::zero(); } return BigUint::from_slice( @@ -494,12 +495,12 @@ pub impl BigUint { ); } - priv pure fn shr_bits(self, n_bits: uint) -> BigUint { + priv fn shr_bits(self, n_bits: uint) -> BigUint { if n_bits == 0 || self.data.is_empty() { return self; } let mut borrow = 0; let mut shifted = ~[]; - for vec::rev_each(self.data) |elem| { + for self.data.each_reverse |elem| { shifted = ~[(*elem >> n_bits) | borrow] + shifted; borrow = *elem << (uint::bits - n_bits); } @@ -508,7 +509,7 @@ pub impl BigUint { } #[cfg(target_arch = "x86_64")] -priv pure fn get_radix_base(radix: uint) -> (uint, uint) { +priv fn get_radix_base(radix: uint) -> (uint, uint) { fail_unless!(1 < radix && radix <= 16); match radix { 2 => (4294967296, 32), @@ -533,7 +534,7 @@ priv pure fn get_radix_base(radix: uint) -> (uint, uint) { #[cfg(target_arch = "arm")] #[cfg(target_arch = "x86")] #[cfg(target_arch = "mips")] -priv pure fn get_radix_base(radix: uint) -> (uint, uint) { +priv fn get_radix_base(radix: uint) -> (uint, uint) { fail_unless!(1 < radix && radix <= 16); match radix { 2 => (65536, 16), @@ -556,23 +557,19 @@ priv pure fn get_radix_base(radix: uint) -> (uint, uint) { } /// A Sign is a BigInt's composing element. +#[deriving(Eq)] pub enum Sign { Minus, Zero, Plus } -impl Eq for Sign { - pure fn eq(&self, other: &Sign) -> bool { self.cmp(other) == 0 } - pure fn ne(&self, other: &Sign) -> bool { self.cmp(other) != 0 } -} - impl Ord for Sign { - pure fn lt(&self, other: &Sign) -> bool { self.cmp(other) < 0 } - pure fn le(&self, other: &Sign) -> bool { self.cmp(other) <= 0 } - pure fn ge(&self, other: &Sign) -> bool { self.cmp(other) >= 0 } - pure fn gt(&self, other: &Sign) -> bool { self.cmp(other) > 0 } + fn lt(&self, other: &Sign) -> bool { self.cmp(other) < 0 } + fn le(&self, other: &Sign) -> bool { self.cmp(other) <= 0 } + fn ge(&self, other: &Sign) -> bool { self.cmp(other) >= 0 } + fn gt(&self, other: &Sign) -> bool { self.cmp(other) > 0 } } pub impl Sign { /// Compare two Sign. - pure fn cmp(&self, other: &Sign) -> int { + fn cmp(&self, other: &Sign) -> int { match (*self, *other) { (Minus, Minus) | (Zero, Zero) | (Plus, Plus) => 0, (Minus, Zero) | (Minus, Plus) | (Zero, Plus) => -1, @@ -581,7 +578,7 @@ pub impl Sign { } /// Negate Sign value. - pure fn neg(&self) -> Sign { + fn neg(&self) -> Sign { match *self { Minus => Plus, Zero => Zero, @@ -597,53 +594,53 @@ pub struct BigInt { } impl Eq for BigInt { - pure fn eq(&self, other: &BigInt) -> bool { self.cmp(other) == 0 } - pure fn ne(&self, other: &BigInt) -> bool { self.cmp(other) != 0 } + fn eq(&self, other: &BigInt) -> bool { self.cmp(other) == 0 } + fn ne(&self, other: &BigInt) -> bool { self.cmp(other) != 0 } } impl Ord for BigInt { - pure fn lt(&self, other: &BigInt) -> bool { self.cmp(other) < 0 } - pure fn le(&self, other: &BigInt) -> bool { self.cmp(other) <= 0 } - pure fn ge(&self, other: &BigInt) -> bool { self.cmp(other) >= 0 } - pure fn gt(&self, other: &BigInt) -> bool { self.cmp(other) > 0 } + fn lt(&self, other: &BigInt) -> bool { self.cmp(other) < 0 } + fn le(&self, other: &BigInt) -> bool { self.cmp(other) <= 0 } + fn ge(&self, other: &BigInt) -> bool { self.cmp(other) >= 0 } + fn gt(&self, other: &BigInt) -> bool { self.cmp(other) > 0 } } impl ToStr for BigInt { - pure fn to_str(&self) -> ~str { self.to_str_radix(10) } + fn to_str(&self) -> ~str { self.to_str_radix(10) } } impl from_str::FromStr for BigInt { - static pure fn from_str(s: &str) -> Option { + fn from_str(s: &str) -> Option { BigInt::from_str_radix(s, 10) } } impl Shl for BigInt { - pure fn shl(&self, rhs: &uint) -> BigInt { + fn shl(&self, rhs: &uint) -> BigInt { BigInt::from_biguint(self.sign, self.data << *rhs) } } impl Shr for BigInt { - pure fn shr(&self, rhs: &uint) -> BigInt { + fn shr(&self, rhs: &uint) -> BigInt { BigInt::from_biguint(self.sign, self.data >> *rhs) } } impl Zero for BigInt { - static pub pure fn zero() -> BigInt { + pub fn zero() -> BigInt { BigInt::from_biguint(Zero, Zero::zero()) } } impl One for BigInt { - static pub pure fn one() -> BigInt { + pub fn one() -> BigInt { BigInt::from_biguint(Plus, One::one()) } } impl Add for BigInt { - pure fn add(&self, other: &BigInt) -> BigInt { + fn add(&self, other: &BigInt) -> BigInt { match (self.sign, other.sign) { (Zero, _) => copy *other, (_, Zero) => copy *self, @@ -657,7 +654,7 @@ impl Add for BigInt { } impl Sub for BigInt { - pure fn sub(&self, other: &BigInt) -> BigInt { + fn sub(&self, other: &BigInt) -> BigInt { match (self.sign, other.sign) { (Zero, _) => -other, (_, Zero) => copy *self, @@ -677,7 +674,7 @@ impl Sub for BigInt { } impl Mul for BigInt { - pure fn mul(&self, other: &BigInt) -> BigInt { + fn mul(&self, other: &BigInt) -> BigInt { match (self.sign, other.sign) { (Zero, _) | (_, Zero) => Zero::zero(), (Plus, Plus) | (Minus, Minus) => { @@ -691,27 +688,27 @@ impl Mul for BigInt { } impl Div for BigInt { - pure fn div(&self, other: &BigInt) -> BigInt { + fn div(&self, other: &BigInt) -> BigInt { let (d, _) = self.divmod(other); return d; } } impl Modulo for BigInt { - pure fn modulo(&self, other: &BigInt) -> BigInt { + fn modulo(&self, other: &BigInt) -> BigInt { let (_, m) = self.divmod(other); return m; } } impl Neg for BigInt { - pure fn neg(&self) -> BigInt { + fn neg(&self) -> BigInt { BigInt::from_biguint(self.sign.neg(), copy self.data) } } impl IntConvertible for BigInt { - pure fn to_int(&self) -> int { + fn to_int(&self) -> int { match self.sign { Plus => uint::min(self.to_uint(), int::max_value as uint) as int, Zero => 0, @@ -720,7 +717,7 @@ impl IntConvertible for BigInt { } } - static pure fn from_int(n: int) -> BigInt { + fn from_int(n: int) -> BigInt { if n > 0 { return BigInt::from_biguint(Plus, BigUint::from_uint(n as uint)); } @@ -735,12 +732,12 @@ impl IntConvertible for BigInt { pub impl BigInt { /// Creates and initializes an BigInt. - static pub pure fn new(sign: Sign, v: ~[BigDigit]) -> BigInt { + pub fn new(sign: Sign, v: ~[BigDigit]) -> BigInt { BigInt::from_biguint(sign, BigUint::new(v)) } /// Creates and initializes an BigInt. - static pub pure fn from_biguint(sign: Sign, data: BigUint) -> BigInt { + pub fn from_biguint(sign: Sign, data: BigUint) -> BigInt { if sign == Zero || data.is_zero() { return BigInt { sign: Zero, data: Zero::zero() }; } @@ -748,24 +745,24 @@ pub impl BigInt { } /// Creates and initializes an BigInt. - static pub pure fn from_uint(n: uint) -> BigInt { + pub fn from_uint(n: uint) -> BigInt { if n == 0 { return Zero::zero(); } return BigInt::from_biguint(Plus, BigUint::from_uint(n)); } /// Creates and initializes an BigInt. - static pub pure fn from_slice(sign: Sign, slice: &[BigDigit]) -> BigInt { + pub fn from_slice(sign: Sign, slice: &[BigDigit]) -> BigInt { BigInt::from_biguint(sign, BigUint::from_slice(slice)) } /// Creates and initializes an BigInt. - static pub pure fn from_str_radix(s: &str, radix: uint) + pub fn from_str_radix(s: &str, radix: uint) -> Option { BigInt::parse_bytes(str::to_bytes(s), radix) } /// Creates and initializes an BigInt. - static pub pure fn parse_bytes(buf: &[u8], radix: uint) + pub fn parse_bytes(buf: &[u8], radix: uint) -> Option { if buf.is_empty() { return None; } let mut sign = Plus; @@ -778,11 +775,11 @@ pub impl BigInt { .map(|bu| BigInt::from_biguint(sign, *bu)); } - pure fn abs(&self) -> BigInt { + fn abs(&self) -> BigInt { BigInt::from_biguint(Plus, copy self.data) } - pure fn cmp(&self, other: &BigInt) -> int { + fn cmp(&self, other: &BigInt) -> int { let ss = self.sign, os = other.sign; if ss < os { return -1; } if ss > os { return 1; } @@ -795,7 +792,7 @@ pub impl BigInt { } } - pure fn divmod(&self, other: &BigInt) -> (BigInt, BigInt) { + fn divmod(&self, other: &BigInt) -> (BigInt, BigInt) { // m.sign == other.sign let (d_ui, m_ui) = self.data.divmod(&other.data); let d = BigInt::from_biguint(Plus, d_ui), @@ -817,16 +814,16 @@ pub impl BigInt { } } - pure fn quot(&self, other: &BigInt) -> BigInt { + fn quot(&self, other: &BigInt) -> BigInt { let (q, _) = self.quotrem(other); return q; } - pure fn rem(&self, other: &BigInt) -> BigInt { + fn rem(&self, other: &BigInt) -> BigInt { let (_, r) = self.quotrem(other); return r; } - pure fn quotrem(&self, other: &BigInt) -> (BigInt, BigInt) { + fn quotrem(&self, other: &BigInt) -> (BigInt, BigInt) { // r.sign == self.sign let (q_ui, r_ui) = self.data.quotrem(&other.data); let q = BigInt::from_biguint(Plus, q_ui); @@ -840,14 +837,14 @@ pub impl BigInt { } } - pure fn is_zero(&self) -> bool { self.sign == Zero } - pure fn is_not_zero(&self) -> bool { self.sign != Zero } - pure fn is_positive(&self) -> bool { self.sign == Plus } - pure fn is_negative(&self) -> bool { self.sign == Minus } - pure fn is_nonpositive(&self) -> bool { self.sign != Plus } - pure fn is_nonnegative(&self) -> bool { self.sign != Minus } + fn is_zero(&self) -> bool { self.sign == Zero } + fn is_not_zero(&self) -> bool { self.sign != Zero } + fn is_positive(&self) -> bool { self.sign == Plus } + fn is_negative(&self) -> bool { self.sign == Minus } + fn is_nonpositive(&self) -> bool { self.sign != Plus } + fn is_nonnegative(&self) -> bool { self.sign != Minus } - pure fn to_uint(&self) -> uint { + fn to_uint(&self) -> uint { match self.sign { Plus => self.data.to_uint(), Zero => 0, @@ -855,7 +852,7 @@ pub impl BigInt { } } - pure fn to_str_radix(&self, radix: uint) -> ~str { + fn to_str_radix(&self, radix: uint) -> ~str { match self.sign { Plus => self.data.to_str_radix(radix), Zero => ~"0", @@ -1045,9 +1042,9 @@ mod biguint_tests { fail_unless!(BigUint::new(~[0, 0, -1]).to_uint() == uint::max_value); } - const sum_triples: &'static [(&'static [BigDigit], - &'static [BigDigit], - &'static [BigDigit])] = &[ + static sum_triples: &'static [(&'static [BigDigit], + &'static [BigDigit], + &'static [BigDigit])] = &[ (&[], &[], &[]), (&[], &[ 1], &[ 1]), (&[ 1], &[ 1], &[ 2]), @@ -1085,9 +1082,9 @@ mod biguint_tests { } } - const mul_triples: &'static [(&'static [BigDigit], - &'static [BigDigit], - &'static [BigDigit])] = &[ + static mul_triples: &'static [(&'static [BigDigit], + &'static [BigDigit], + &'static [BigDigit])] = &[ (&[], &[], &[]), (&[], &[ 1], &[]), (&[ 2], &[], &[]), @@ -1111,10 +1108,10 @@ mod biguint_tests { (&[ 0, 0, 1], &[ 0, 0, 0, 1], &[0, 0, 0, 0, 0, 1]) ]; - const divmod_quadruples: &'static [(&'static [BigDigit], - &'static [BigDigit], - &'static [BigDigit], - &'static [BigDigit])] + static divmod_quadruples: &'static [(&'static [BigDigit], + &'static [BigDigit], + &'static [BigDigit], + &'static [BigDigit])] = &[ (&[ 1], &[ 2], &[], &[1]), (&[ 1, 1], &[ 2], &[-1/2+1], &[1]), @@ -1399,9 +1396,9 @@ mod bigint_tests { ).to_uint() == 0); } - const sum_triples: &'static [(&'static [BigDigit], - &'static [BigDigit], - &'static [BigDigit])] = &[ + static sum_triples: &'static [(&'static [BigDigit], + &'static [BigDigit], + &'static [BigDigit])] = &[ (&[], &[], &[]), (&[], &[ 1], &[ 1]), (&[ 1], &[ 1], &[ 2]), @@ -1451,9 +1448,9 @@ mod bigint_tests { } } - const mul_triples: &'static [(&'static [BigDigit], - &'static [BigDigit], - &'static [BigDigit])] = &[ + static mul_triples: &'static [(&'static [BigDigit], + &'static [BigDigit], + &'static [BigDigit])] = &[ (&[], &[], &[]), (&[], &[ 1], &[]), (&[ 2], &[], &[]), @@ -1477,10 +1474,10 @@ mod bigint_tests { (&[ 0, 0, 1], &[ 0, 0, 0, 1], &[0, 0, 0, 0, 0, 1]) ]; - const divmod_quadruples: &'static [(&'static [BigDigit], - &'static [BigDigit], - &'static [BigDigit], - &'static [BigDigit])] + static divmod_quadruples: &'static [(&'static [BigDigit], + &'static [BigDigit], + &'static [BigDigit], + &'static [BigDigit])] = &[ (&[ 1], &[ 2], &[], &[1]), (&[ 1, 1], &[ 2], &[-1/2+1], &[1]), diff --git a/src/libstd/bitv.rs b/src/libstd/bitv.rs index 430a5eab64e0b..3acc95a3aad62 100644 --- a/src/libstd/bitv.rs +++ b/src/libstd/bitv.rs @@ -27,7 +27,7 @@ fn small_mask(nbits: uint) -> uint { } pub impl SmallBitv { - static fn new(bits: uint) -> SmallBitv { + fn new(bits: uint) -> SmallBitv { SmallBitv {bits: bits} } @@ -62,7 +62,7 @@ pub impl SmallBitv { } #[inline(always)] - pure fn get(&self, i: uint) -> bool { + fn get(&self, i: uint) -> bool { (self.bits & (1 << i)) != 0 } @@ -124,7 +124,7 @@ fn big_mask(nbits: uint, elem: uint) -> uint { } pub impl BigBitv { - static fn new(storage: ~[uint]) -> BigBitv { + fn new(storage: ~[uint]) -> BigBitv { BigBitv {storage: storage} } @@ -181,7 +181,7 @@ pub impl BigBitv { } #[inline(always)] - pure fn get(&self, i: uint) -> bool { + fn get(&self, i: uint) -> bool { let w = i / uint::bits; let b = i % uint::bits; let x = 1 & self.storage[w] >> b; @@ -256,7 +256,7 @@ priv impl Bitv { } pub impl Bitv { - static fn new(nbits: uint, init: bool) -> Bitv { + fn new(nbits: uint, init: bool) -> Bitv { let rep = if nbits <= uint::bits { Small(~SmallBitv::new(if init {!0} else {0})) } @@ -299,7 +299,7 @@ pub impl Bitv { /// Retrieve the value at index `i` #[inline(always)] - pure fn get(&self, i: uint) -> bool { + fn get(&self, i: uint) -> bool { fail_unless!((i < self.nbits)); match self.rep { Big(ref b) => b.get(i), @@ -555,13 +555,13 @@ pub fn from_fn(len: uint, f: &fn(index: uint) -> bool) -> Bitv { } impl ops::Index for Bitv { - pure fn index(&self, i: uint) -> bool { + fn index(&self, i: uint) -> bool { self.get(i) } } #[inline(always)] -pure fn iterate_bits(base: uint, bits: uint, f: &fn(uint) -> bool) -> bool { +fn iterate_bits(base: uint, bits: uint, f: &fn(uint) -> bool) -> bool { if bits == 0 { return true; } @@ -592,12 +592,12 @@ pub struct BitvSet { pub impl BitvSet { /// Creates a new bit vector set with initially no contents - static fn new() -> BitvSet { + fn new() -> BitvSet { BitvSet{ size: 0, bitv: BigBitv::new(~[0]) } } /// Creates a new bit vector set from the given bit vector - static fn from_bitv(bitv: Bitv) -> BitvSet { + fn from_bitv(bitv: Bitv) -> BitvSet { let mut size = 0; for bitv.ones |_| { size += 1; @@ -612,7 +612,7 @@ pub impl BitvSet { /// Returns the capacity in bits for this bit vector. Inserting any /// element less than this amount will not trigger a resizing. - pure fn capacity(&self) -> uint { self.bitv.storage.len() * uint::bits } + fn capacity(&self) -> uint { self.bitv.storage.len() * uint::bits } /// Consumes this set to return the underlying bit vector fn unwrap(self) -> Bitv { @@ -667,9 +667,9 @@ pub impl BitvSet { } impl BaseIter for BitvSet { - pure fn size_hint(&self) -> Option { Some(self.len()) } + fn size_hint(&self) -> Option { Some(self.len()) } - pure fn each(&self, blk: &fn(v: &uint) -> bool) { + fn each(&self, blk: &fn(v: &uint) -> bool) { for self.bitv.storage.eachi |i, &w| { if !iterate_bits(i * uint::bits, w, |b| blk(&b)) { return; @@ -679,7 +679,7 @@ impl BaseIter for BitvSet { } impl cmp::Eq for BitvSet { - pure fn eq(&self, other: &BitvSet) -> bool { + fn eq(&self, other: &BitvSet) -> bool { if self.size != other.size { return false; } @@ -696,12 +696,12 @@ impl cmp::Eq for BitvSet { return true; } - pure fn ne(&self, other: &BitvSet) -> bool { !self.eq(other) } + fn ne(&self, other: &BitvSet) -> bool { !self.eq(other) } } impl Container for BitvSet { - pure fn len(&const self) -> uint { self.size } - pure fn is_empty(&const self) -> bool { self.size == 0 } + fn len(&const self) -> uint { self.size } + fn is_empty(&const self) -> bool { self.size == 0 } } impl Mutable for BitvSet { @@ -712,7 +712,7 @@ impl Mutable for BitvSet { } impl Set for BitvSet { - pure fn contains(&self, value: &uint) -> bool { + fn contains(&self, value: &uint) -> bool { *value < self.bitv.storage.len() * uint::bits && self.bitv.get(*value) } @@ -748,14 +748,14 @@ impl Set for BitvSet { return true; } - pure fn is_disjoint(&self, other: &BitvSet) -> bool { + fn is_disjoint(&self, other: &BitvSet) -> bool { for self.intersection(other) |_| { return false; } return true; } - pure fn is_subset(&self, other: &BitvSet) -> bool { + fn is_subset(&self, other: &BitvSet) -> bool { for self.each_common(other) |_, w1, w2| { if w1 & w2 != w1 { return false; @@ -774,11 +774,11 @@ impl Set for BitvSet { return true; } - pure fn is_superset(&self, other: &BitvSet) -> bool { + fn is_superset(&self, other: &BitvSet) -> bool { other.is_subset(self) } - pure fn difference(&self, other: &BitvSet, f: &fn(&uint) -> bool) { + fn difference(&self, other: &BitvSet, f: &fn(&uint) -> bool) { for self.each_common(other) |i, w1, w2| { if !iterate_bits(i, w1 & !w2, |b| f(&b)) { return; @@ -790,7 +790,7 @@ impl Set for BitvSet { ); } - pure fn symmetric_difference(&self, other: &BitvSet, + fn symmetric_difference(&self, other: &BitvSet, f: &fn(&uint) -> bool) { for self.each_common(other) |i, w1, w2| { if !iterate_bits(i, w1 ^ w2, |b| f(&b)) { @@ -802,7 +802,7 @@ impl Set for BitvSet { ); } - pure fn intersection(&self, other: &BitvSet, f: &fn(&uint) -> bool) { + fn intersection(&self, other: &BitvSet, f: &fn(&uint) -> bool) { for self.each_common(other) |i, w1, w2| { if !iterate_bits(i, w1 & w2, |b| f(&b)) { return; @@ -810,7 +810,7 @@ impl Set for BitvSet { } } - pure fn union(&self, other: &BitvSet, f: &fn(&uint) -> bool) { + fn union(&self, other: &BitvSet, f: &fn(&uint) -> bool) { for self.each_common(other) |i, w1, w2| { if !iterate_bits(i, w1 | w2, |b| f(&b)) { return; @@ -827,11 +827,11 @@ priv impl BitvSet { /// both have in common. The three yielded arguments are (bit location, /// w1, w2) where the bit location is the number of bits offset so far, /// and w1/w2 are the words coming from the two vectors self, other. - pure fn each_common(&self, other: &BitvSet, + fn each_common(&self, other: &BitvSet, f: &fn(uint, uint, uint) -> bool) { let min = uint::min(self.bitv.storage.len(), other.bitv.storage.len()); - for self.bitv.storage.view(0, min).eachi |i, &w| { + for self.bitv.storage.slice(0, min).eachi |i, &w| { if !f(i * uint::bits, w, other.bitv.storage[i]) { return; } @@ -845,19 +845,19 @@ priv impl BitvSet { /// The yielded arguments are a bool, the bit offset, and a word. The bool /// is true if the word comes from 'self', and false if it comes from /// 'other'. - pure fn each_outlier(&self, other: &BitvSet, + fn each_outlier(&self, other: &BitvSet, f: &fn(bool, uint, uint) -> bool) { let len1 = self.bitv.storage.len(); let len2 = other.bitv.storage.len(); let min = uint::min(len1, len2); /* only one of these loops will execute and that's the point */ - for self.bitv.storage.view(min, len1).eachi |i, &w| { + for self.bitv.storage.slice(min, len1).eachi |i, &w| { if !f(true, (i + min) * uint::bits, w) { return; } } - for other.bitv.storage.view(min, len2).eachi |i, &w| { + for other.bitv.storage.slice(min, len2).eachi |i, &w| { if !f(false, (i + min) * uint::bits, w) { return; } @@ -877,7 +877,7 @@ mod tests { use core::vec; use core::rand; - const bench_bits : uint = 1 << 14; + static bench_bits : uint = 1 << 14; #[test] pub fn test_to_str() { diff --git a/src/libstd/c_vec.rs b/src/libstd/c_vec.rs index 8e75f694fa3d4..1787be75e24d2 100644 --- a/src/libstd/c_vec.rs +++ b/src/libstd/c_vec.rs @@ -54,11 +54,14 @@ struct DtorRes { dtor: Option<@fn()>, } +#[unsafe_destructor] impl Drop for DtorRes { fn finalize(&self) { - match self.dtor { - option::None => (), - option::Some(f) => f() + unsafe { + match self.dtor { + option::None => (), + option::Some(f) => f() + } } } } @@ -138,7 +141,7 @@ pub fn set(t: CVec, ofs: uint, v: T) { */ /// Returns the length of the vector -pub pure fn len(t: CVec) -> uint { t.len } +pub fn len(t: CVec) -> uint { t.len } /// Returns a pointer to the first element of the vector pub unsafe fn ptr(t: CVec) -> *mut T { t.base } diff --git a/src/libstd/cmp.rs b/src/libstd/cmp.rs index b6362f83f4426..93a2f4e2acc74 100644 --- a/src/libstd/cmp.rs +++ b/src/libstd/cmp.rs @@ -14,39 +14,39 @@ use core::f32; use core::f64; use core::float; -pub const FUZZY_EPSILON: float = 1.0e-6; +pub static FUZZY_EPSILON: float = 1.0e-6; pub trait FuzzyEq { - pure fn fuzzy_eq(&self, other: &Self) -> bool; - pure fn fuzzy_eq_eps(&self, other: &Self, epsilon: &Eps) -> bool; + fn fuzzy_eq(&self, other: &Self) -> bool; + fn fuzzy_eq_eps(&self, other: &Self, epsilon: &Eps) -> bool; } impl FuzzyEq for float { - pure fn fuzzy_eq(&self, other: &float) -> bool { + fn fuzzy_eq(&self, other: &float) -> bool { self.fuzzy_eq_eps(other, &FUZZY_EPSILON) } - pure fn fuzzy_eq_eps(&self, other: &float, epsilon: &float) -> bool { + fn fuzzy_eq_eps(&self, other: &float, epsilon: &float) -> bool { float::abs(*self - *other) < *epsilon } } impl FuzzyEq for f32 { - pure fn fuzzy_eq(&self, other: &f32) -> bool { + fn fuzzy_eq(&self, other: &f32) -> bool { self.fuzzy_eq_eps(other, &(FUZZY_EPSILON as f32)) } - pure fn fuzzy_eq_eps(&self, other: &f32, epsilon: &f32) -> bool { + fn fuzzy_eq_eps(&self, other: &f32, epsilon: &f32) -> bool { f32::abs(*self - *other) < *epsilon } } impl FuzzyEq for f64 { - pure fn fuzzy_eq(&self, other: &f64) -> bool { + fn fuzzy_eq(&self, other: &f64) -> bool { self.fuzzy_eq_eps(other, &(FUZZY_EPSILON as f64)) } - pure fn fuzzy_eq_eps(&self, other: &f64, epsilon: &f64) -> bool { + fn fuzzy_eq_eps(&self, other: &f64, epsilon: &f64) -> bool { f64::abs(*self - *other) < *epsilon } } @@ -71,11 +71,11 @@ mod test_complex{ struct Complex { r: float, i: float } impl FuzzyEq for Complex { - pure fn fuzzy_eq(&self, other: &Complex) -> bool { + fn fuzzy_eq(&self, other: &Complex) -> bool { self.fuzzy_eq_eps(other, &FUZZY_EPSILON) } - pure fn fuzzy_eq_eps(&self, other: &Complex, + fn fuzzy_eq_eps(&self, other: &Complex, epsilon: &float) -> bool { self.r.fuzzy_eq_eps(&other.r, epsilon) && self.i.fuzzy_eq_eps(&other.i, epsilon) diff --git a/src/libstd/comm.rs b/src/libstd/comm.rs index 99f6fa4c8cf59..9f68c6762228d 100644 --- a/src/libstd/comm.rs +++ b/src/libstd/comm.rs @@ -26,8 +26,6 @@ pub struct DuplexStream { } // Allow these methods to be used without import: -#[cfg(stage1)] -#[cfg(stage2)] pub impl DuplexStream { fn send(&self, x: T) { self.chan.send(x) @@ -41,7 +39,7 @@ pub impl DuplexStream { fn try_recv(&self) -> Option { self.port.try_recv() } - pure fn peek(&self) -> bool { + fn peek(&self) -> bool { self.port.peek() } } @@ -69,13 +67,13 @@ impl GenericPort for DuplexStream { } impl Peekable for DuplexStream { - pure fn peek(&self) -> bool { + fn peek(&self) -> bool { self.port.peek() } } impl Selectable for DuplexStream { - pure fn header(&self) -> *pipes::PacketHeader { + fn header(&self) -> *pipes::PacketHeader { self.port.header() } } diff --git a/src/libstd/deque.rs b/src/libstd/deque.rs index 86304f48e7929..e6fcbdc84c877 100644 --- a/src/libstd/deque.rs +++ b/src/libstd/deque.rs @@ -8,11 +8,13 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +//! A double-ended queue implemented as a circular buffer + use core::container::{Container, Mutable}; use core::prelude::*; use core::vec; -const initial_capacity: uint = 32u; // 2^5 +static initial_capacity: uint = 32u; // 2^5 pub struct Deque { priv nelts: uint, @@ -23,10 +25,10 @@ pub struct Deque { impl Container for Deque { /// Return the number of elements in the deque - pure fn len(&const self) -> uint { self.nelts } + fn len(&const self) -> uint { self.nelts } /// Return true if the deque contains no elements - pure fn is_empty(&const self) -> bool { self.len() == 0 } + fn is_empty(&const self) -> bool { self.len() == 0 } } impl Mutable for Deque { @@ -41,7 +43,7 @@ impl Mutable for Deque { pub impl Deque { /// Create an empty Deque - static pure fn new() -> Deque { + fn new() -> Deque { Deque{nelts: 0, lo: 0, hi: 0, elts: vec::from_fn(initial_capacity, |_| None)} } @@ -251,15 +253,15 @@ mod tests { fail_unless!(*deq.get(3) == d); } - #[deriving_eq] + #[deriving(Eq)] enum Taggy { One(int), Two(int, int), Three(int, int, int), } - #[deriving_eq] + #[deriving(Eq)] enum Taggypar { Onepar(int), Twopar(int, int), Threepar(int, int, int), } - #[deriving_eq] + #[deriving(Eq)] struct RecCy { x: int, y: int, diff --git a/src/libstd/ebml.rs b/src/libstd/ebml.rs index 4ab119abf1c94..92898af2993de 100644 --- a/src/libstd/ebml.rs +++ b/src/libstd/ebml.rs @@ -69,7 +69,7 @@ pub mod reader { // ebml reading impl ops::Index for Doc { - pure fn index(&self, tag: uint) -> Doc { + fn index(&self, tag: uint) -> Doc { unsafe { get_doc(*self, tag) } @@ -545,7 +545,7 @@ pub mod writer { // Set to true to generate more debugging in EBML code. // Totally lame approach. - const debug: bool = false; + static debug: bool = false; priv impl Encoder { // used internally to emit things like the vector length and so on diff --git a/src/libstd/flatpipes.rs b/src/libstd/flatpipes.rs index c5515c63b29a2..587509af9fa84 100644 --- a/src/libstd/flatpipes.rs +++ b/src/libstd/flatpipes.rs @@ -254,7 +254,7 @@ pub trait ByteChan { fn send(&self, val: ~[u8]); } -const CONTINUE: [u8 * 4] = [0xAA, 0xBB, 0xCC, 0xDD]; +static CONTINUE: [u8 * 4] = [0xAA, 0xBB, 0xCC, 0xDD]; impl,P:BytePort> GenericPort for FlatPort { fn recv(&self) -> T { @@ -314,7 +314,7 @@ impl,C:ByteChan> GenericChan for FlatChan { } pub impl,P:BytePort> FlatPort { - static fn new(u: U, p: P) -> FlatPort { + fn new(u: U, p: P) -> FlatPort { FlatPort { unflattener: u, byte_port: p @@ -323,7 +323,7 @@ pub impl,P:BytePort> FlatPort { } pub impl,C:ByteChan> FlatChan { - static fn new(f: F, c: C) -> FlatChan { + fn new(f: F, c: C) -> FlatChan { FlatChan { flattener: f, byte_chan: c @@ -376,7 +376,7 @@ pub mod flatteners { } pub impl PodUnflattener { - static fn new() -> PodUnflattener { + fn new() -> PodUnflattener { PodUnflattener { bogus: () } @@ -384,7 +384,7 @@ pub mod flatteners { } pub impl PodFlattener { - static fn new() -> PodFlattener { + fn new() -> PodFlattener { PodFlattener { bogus: () } @@ -419,7 +419,7 @@ pub mod flatteners { } pub impl> DeserializingUnflattener { - static fn new(deserialize_buffer: DeserializeBuffer) + fn new(deserialize_buffer: DeserializeBuffer) -> DeserializingUnflattener { DeserializingUnflattener { deserialize_buffer: deserialize_buffer @@ -428,7 +428,7 @@ pub mod flatteners { } pub impl> SerializingFlattener { - static fn new(serialize_value: SerializeValue) + fn new(serialize_value: SerializeValue) -> SerializingFlattener { SerializingFlattener { serialize_value: serialize_value @@ -459,15 +459,15 @@ pub mod flatteners { } pub trait FromReader { - static fn from_reader(r: @Reader) -> Self; + fn from_reader(r: @Reader) -> Self; } pub trait FromWriter { - static fn from_writer(w: @Writer) -> Self; + fn from_writer(w: @Writer) -> Self; } - impl FromReader for json::Decoder/&self { - static fn from_reader(r: @Reader) -> json::Decoder/&self { + impl FromReader for json::Decoder<'self> { + fn from_reader(r: @Reader) -> json::Decoder<'self> { match json::from_reader(r) { Ok(json) => { json::Decoder(json) @@ -478,13 +478,13 @@ pub mod flatteners { } impl FromWriter for json::Encoder { - static fn from_writer(w: @Writer) -> json::Encoder { + fn from_writer(w: @Writer) -> json::Encoder { json::Encoder(w) } } impl FromReader for ebml::reader::Decoder { - static fn from_reader(r: @Reader) -> ebml::reader::Decoder { + fn from_reader(r: @Reader) -> ebml::reader::Decoder { let buf = @r.read_whole_stream(); let doc = ebml::reader::Doc(buf); ebml::reader::Decoder(doc) @@ -492,7 +492,7 @@ pub mod flatteners { } impl FromWriter for ebml::writer::Encoder { - static fn from_writer(w: @Writer) -> ebml::writer::Encoder { + fn from_writer(w: @Writer) -> ebml::writer::Encoder { ebml::writer::Encoder(w) } } @@ -543,7 +543,7 @@ pub mod bytepipes { } pub impl ReaderBytePort { - static fn new(r: R) -> ReaderBytePort { + fn new(r: R) -> ReaderBytePort { ReaderBytePort { reader: r } @@ -551,7 +551,7 @@ pub mod bytepipes { } pub impl WriterByteChan { - static fn new(w: W) -> WriterByteChan { + fn new(w: W) -> WriterByteChan { WriterByteChan { writer: w } @@ -571,7 +571,7 @@ pub mod bytepipes { fn try_recv(&self, count: uint) -> Option<~[u8]> { if vec::uniq_len(&const self.buf) >= count { let mut bytes = ::core::util::replace(&mut self.buf, ~[]); - self.buf = bytes.slice(count, bytes.len()); + self.buf = bytes.slice(count, bytes.len()).to_owned(); bytes.truncate(count); return Some(bytes); } else if vec::uniq_len(&const self.buf) > 0 { @@ -606,7 +606,7 @@ pub mod bytepipes { } pub impl PipeBytePort { - static fn new(p: Port<~[u8]>) -> PipeBytePort { + fn new(p: Port<~[u8]>) -> PipeBytePort { PipeBytePort { port: p, buf: ~[] @@ -615,7 +615,7 @@ pub mod bytepipes { } pub impl PipeByteChan { - static fn new(c: Chan<~[u8]>) -> PipeByteChan { + fn new(c: Chan<~[u8]>) -> PipeByteChan { PipeByteChan { chan: c } @@ -921,7 +921,7 @@ mod test { } fn test_try_recv_none3(loader: PortLoader

) { - const CONTINUE: [u8 * 4] = [0xAA, 0xBB, 0xCC, 0xDD]; + static CONTINUE: [u8 * 4] = [0xAA, 0xBB, 0xCC, 0xDD]; // The control word is followed by garbage let bytes = CONTINUE.to_vec() + ~[0]; let port = loader(bytes); @@ -940,7 +940,7 @@ mod test { fn test_try_recv_none4(+loader: PortLoader

) { fail_unless!(do task::try || { - const CONTINUE: [u8 * 4] = [0xAA, 0xBB, 0xCC, 0xDD]; + static CONTINUE: [u8 * 4] = [0xAA, 0xBB, 0xCC, 0xDD]; // The control word is followed by a valid length, // then undeserializable garbage let len_bytes = do io::u64_to_be_bytes( diff --git a/src/libstd/future.rs b/src/libstd/future.rs index 4867204ea39aa..29771fa350122 100644 --- a/src/libstd/future.rs +++ b/src/libstd/future.rs @@ -35,6 +35,7 @@ pub struct Future { // FIXME(#2829) -- futures should not be copyable, because they close // over ~fn's that have pipes and so forth within! +#[unsafe_destructor] impl Drop for Future { fn finalize(&self) {} } @@ -55,7 +56,7 @@ pub impl Future { pub impl Future { - pure fn get_ref(&self) -> &'self A { + fn get_ref(&self) -> &'self A { /*! * Executes the future's closure and then returns a borrowed * pointer to the result. The borrowed pointer lasts as long as diff --git a/src/libstd/getopts.rs b/src/libstd/getopts.rs index 0b615e0c0dadb..de8a8f343816c 100644 --- a/src/libstd/getopts.rs +++ b/src/libstd/getopts.rs @@ -86,20 +86,20 @@ use core::option::{Some, None}; use core::str; use core::vec; -#[deriving_eq] +#[deriving(Eq)] pub enum Name { Long(~str), Short(char), } -#[deriving_eq] +#[deriving(Eq)] pub enum HasArg { Yes, No, Maybe, } -#[deriving_eq] +#[deriving(Eq)] pub enum Occur { Req, Optional, Multi, } /// A description of a possible option -#[deriving_eq] +#[deriving(Eq)] pub struct Opt { name: Name, hasarg: HasArg, @@ -146,14 +146,14 @@ pub fn optmulti(name: &str) -> Opt { return Opt {name: mkname(name), hasarg: Yes, occur: Multi}; } -#[deriving_eq] +#[deriving(Eq)] enum Optval { Val(~str), Given, } /** * The result of checking command line arguments. Contains a vector * of matches and a vector of free strings. */ -#[deriving_eq] +#[deriving(Eq)] pub struct Matches { opts: ~[Opt], vals: ~[~[Optval]], @@ -179,7 +179,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. */ -#[deriving_eq] +#[deriving(Eq)] pub enum Fail_ { ArgumentMissing(~str), UnrecognizedOption(~str), @@ -243,7 +243,7 @@ pub fn getopts(args: &[~str], opts: &[Opt]) -> Result { let mut names; let mut i_arg = None; if cur[1] == '-' as u8 { - let tail = str::slice(cur, 2, curlen); + let tail = str::slice(cur, 2, curlen).to_owned(); let tail_eq = str::splitn_char(tail, '=', 1); if tail_eq.len() <= 1 { names = ~[Long(tail)]; @@ -279,7 +279,7 @@ pub fn getopts(args: &[~str], opts: &[Opt]) -> Result { No => false }; if arg_follows && j < curlen { - i_arg = Some(cur.slice(j, curlen)); + i_arg = Some(cur.slice(j, curlen).to_owned()); break; } else { last_valid_opt_id = None; @@ -446,7 +446,7 @@ pub fn opt_default(mm: &Matches, nm: &str, def: &str) -> Option<~str> { _ => Some::<~str>(str::from_slice(def)) } } -#[deriving_eq] +#[deriving(Eq)] pub enum FailType { ArgumentMissing_, UnrecognizedOption_, @@ -469,7 +469,7 @@ pub mod groups { /** one group of options, e.g., both -h and --help, along with * their shared description and properties */ - #[deriving_eq] + #[deriving(Eq)] pub struct OptGroup { short_name: ~str, long_name: ~str, diff --git a/src/libstd/io_util.rs b/src/libstd/io_util.rs index 7d673feaf254c..50d2eb6a78521 100644 --- a/src/libstd/io_util.rs +++ b/src/libstd/io_util.rs @@ -17,7 +17,7 @@ pub struct BufReader { } pub impl BufReader { - static pub fn new(v: ~[u8]) -> BufReader { + pub fn new(v: ~[u8]) -> BufReader { BufReader { buf: v, pos: 0 diff --git a/src/libstd/json.rs b/src/libstd/json.rs index f2f37604fb564..a9b9b2977cded 100644 --- a/src/libstd/json.rs +++ b/src/libstd/json.rs @@ -14,20 +14,14 @@ //! json serialization +use core::prelude::*; +use core::io::{WriterUtil, ReaderUtil}; +use core::hashmap::linear::LinearMap; + use serialize::Encodable; use serialize; use sort::Sort; -use core::char; -use core::cmp::{Eq, Ord}; -use core::float; -use core::io::{WriterUtil, ReaderUtil}; -use core::io; -use core::prelude::*; -use core::hashmap::linear::LinearMap; -use core::str; -use core::to_str; - /// Represents a json value pub enum Json { Number(float), @@ -41,6 +35,7 @@ pub enum Json { pub type List = ~[Json]; pub type Object = LinearMap<~str, Json>; +#[deriving(Eq)] pub struct Error { line: uint, col: uint, @@ -49,7 +44,7 @@ pub struct Error { fn escape_str(s: &str) -> ~str { let mut escaped = ~"\""; - for str::chars_each(s) |c| { + for str::each_char(s) |c| { match c { '"' => escaped += ~"\\\"", '\\' => escaped += ~"\\\\", @@ -351,7 +346,7 @@ pub fn to_writer(wr: @io::Writer, json: &Json) { } /// Encodes a json value into a string -pub pure fn to_str(json: &Json) -> ~str { +pub fn to_str(json: &Json) -> ~str { unsafe { // ugh, should be safe io::with_str_writer(|wr| to_writer(wr, json)) @@ -755,7 +750,7 @@ pub fn Decoder(json: Json) -> Decoder { Decoder { json: json, stack: ~[] } } -priv impl Decoder/&self { +priv impl Decoder<'self> { fn peek(&self) -> &'self Json { if vec::uniq_len(&const self.stack) == 0 { self.stack.push(&self.json); @@ -771,7 +766,7 @@ priv impl Decoder/&self { } } -impl serialize::Decoder for Decoder/&self { +impl serialize::Decoder for Decoder<'self> { fn read_nil(&self) -> () { debug!("read_nil"); match *self.pop() { @@ -953,7 +948,7 @@ impl serialize::Decoder for Decoder/&self { } impl Eq for Json { - pure fn eq(&self, other: &Json) -> bool { + fn eq(&self, other: &Json) -> bool { match (self) { &Number(f0) => match other { &Number(f1) => f0 == f1, _ => false }, @@ -986,12 +981,12 @@ impl Eq for Json { } } } - pure fn ne(&self, other: &Json) -> bool { !self.eq(other) } + fn ne(&self, other: &Json) -> bool { !self.eq(other) } } /// Test if two json values are less than one another impl Ord for Json { - pure fn lt(&self, other: &Json) -> bool { + fn lt(&self, other: &Json) -> bool { match (*self) { Number(f0) => { match *other { @@ -1061,18 +1056,9 @@ impl Ord for Json { } } } - pure fn le(&self, other: &Json) -> bool { !(*other).lt(&(*self)) } - pure fn ge(&self, other: &Json) -> bool { !(*self).lt(other) } - pure fn gt(&self, other: &Json) -> bool { (*other).lt(&(*self)) } -} - -impl Eq for Error { - pure fn eq(&self, other: &Error) -> bool { - (*self).line == other.line && - (*self).col == other.col && - (*self).msg == other.msg - } - pure fn ne(&self, other: &Error) -> bool { !(*self).eq(other) } + fn le(&self, other: &Json) -> bool { !(*other).lt(&(*self)) } + fn ge(&self, other: &Json) -> bool { !(*self).lt(other) } + fn gt(&self, other: &Json) -> bool { (*other).lt(&(*self)) } } trait ToJson { fn to_json(&self) -> Json; } @@ -1197,11 +1183,11 @@ impl ToJson for Option { } impl to_str::ToStr for Json { - pure fn to_str(&self) -> ~str { to_str(self) } + fn to_str(&self) -> ~str { to_str(self) } } impl to_str::ToStr for Error { - pure fn to_str(&self) -> ~str { + fn to_str(&self) -> ~str { fmt!("%u:%u: %s", self.line, self.col, *self.msg) } } @@ -1284,20 +1270,6 @@ mod tests { fail_unless!(a == b); } - // two fns copied from libsyntax/util/testing.rs. - // Should they be in their own crate? - pub pure fn check_equal_ptr (given : &T, expected: &T) { - if !((given == expected) && (expected == given )) { - fail!(fmt!("given %?, expected %?",given,expected)); - } - } - - pub pure fn check_equal (given : T, expected: T) { - if !((given == expected) && (expected == given )) { - fail!(fmt!("given %?, expected %?",given,expected)); - } - } - #[test] fn test_write_enum () { let bw = @io::BytesWriter(); @@ -1315,7 +1287,7 @@ mod tests { } } } - check_equal(str::from_bytes(bw.bytes), ~"[\"frog\",[\"Henry\",349]]"); + assert_eq!(str::from_bytes(bw.bytes), ~"[\"frog\",[\"Henry\",349]]"); } #[test] @@ -1330,7 +1302,7 @@ mod tests { } } } - check_equal(str::from_bytes(bw.bytes), ~"\"jodhpurs\""); + assert_eq!(str::from_bytes(bw.bytes), ~"\"jodhpurs\""); } #[test] @@ -1342,7 +1314,7 @@ mod tests { do encoder.emit_enum_variant (~"None",37,1242) { } } - check_equal(str::from_bytes(bw.bytes), ~"null"); + assert_eq!(str::from_bytes(bw.bytes), ~"null"); } #[test] diff --git a/src/libstd/list.rs b/src/libstd/list.rs index 3a0f299257e09..b918f8505c802 100644 --- a/src/libstd/list.rs +++ b/src/libstd/list.rs @@ -15,14 +15,14 @@ use core::option::*; use core::prelude::*; use core::vec; -#[deriving_eq] +#[deriving(Eq)] pub enum List { Cons(T, @List), Nil, } /// Create a list from a vector -pub pure fn from_vec(v: &[T]) -> @List { +pub fn from_vec(v: &[T]) -> @List { vec::foldr(v, @Nil::, |h, t| @Cons(*h, t)) } @@ -52,7 +52,7 @@ pub 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. */ -pub pure 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 { @@ -74,7 +74,7 @@ pub fn has(ls: @List, elt: T) -> bool { } /// Returns true if the list is empty -pub pure fn is_empty(ls: @List) -> bool { +pub fn is_empty(ls: @List) -> bool { match *ls { Nil => true, _ => false @@ -82,14 +82,14 @@ pub pure fn is_empty(ls: @List) -> bool { } /// Returns the length of a list -pub pure 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 -pub pure fn tail(ls: @List) -> @List { +pub fn tail(ls: @List) -> @List { match *ls { Cons(_, tl) => return tl, Nil => fail!(~"list empty") @@ -97,7 +97,7 @@ pub pure fn tail(ls: @List) -> @List { } /// Returns the first element of a list -pub pure fn head(ls: @List) -> T { +pub fn head(ls: @List) -> T { match *ls { Cons(copy hd, _) => hd, // makes me sad @@ -106,7 +106,7 @@ pub pure fn head(ls: @List) -> T { } /// Appends one list to another -pub pure fn append(l: @List, m: @List) -> @List { +pub fn append(l: @List, m: @List) -> @List { match *l { Nil => return m, Cons(copy x, xs) => { @@ -119,13 +119,13 @@ pub pure fn append(l: @List, m: @List) -> @List { /* /// Push one element into the front of a list, returning a new list /// THIS VERSION DOESN'T ACTUALLY WORK -pure fn push(ll: &mut @list, vv: T) { +fn push(ll: &mut @list, vv: T) { ll = &mut @cons(vv, *ll) } */ /// Iterate over a list -pub pure fn iter(l: @List, f: &fn(&T)) { +pub fn iter(l: @List, f: &fn(&T)) { let mut cur = l; loop { cur = match *cur { @@ -139,7 +139,7 @@ pub pure fn iter(l: @List, f: &fn(&T)) { } /// Iterate over a list -pub pure 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 { diff --git a/src/libstd/md4.rs b/src/libstd/md4.rs index df254543512b0..e20ac624278f7 100644 --- a/src/libstd/md4.rs +++ b/src/libstd/md4.rs @@ -19,7 +19,7 @@ struct Quad { d: u32 } -pub pure fn md4(msg: &[u8]) -> Quad { +pub fn md4(msg: &[u8]) -> Quad { // subtle: if orig_len is merely uint, then the code below // which performs shifts by 32 bits or more has undefined // results. @@ -45,7 +45,7 @@ pub pure fn md4(msg: &[u8]) -> Quad { let mut c = 0x98badcfeu32; let mut d = 0x10325476u32; - pure fn rot(r: int, x: u32) -> u32 { + fn rot(r: int, x: u32) -> u32 { let r = r as u32; (x << r) | (x >> (32u32 - r)) } @@ -103,9 +103,9 @@ pub pure fn md4(msg: &[u8]) -> Quad { return Quad {a: a, b: b, c: c, d: d}; } -pub pure fn md4_str(msg: &[u8]) -> ~str { +pub fn md4_str(msg: &[u8]) -> ~str { let Quad {a, b, c, d} = md4(msg); - pure fn app(a: u32, b: u32, c: u32, d: u32, f: &fn(u32)) { + fn app(a: u32, b: u32, c: u32, d: u32, f: &fn(u32)) { f(a); f(b); f(c); f(d); } let mut result = ~""; @@ -121,7 +121,7 @@ pub pure fn md4_str(msg: &[u8]) -> ~str { result } -pub pure 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_ip.rs b/src/libstd/net_ip.rs index 04283674d88be..15593571b43ca 100644 --- a/src/libstd/net_ip.rs +++ b/src/libstd/net_ip.rs @@ -21,20 +21,20 @@ use core::vec; use iotask = uv::iotask::IoTask; use interact = uv::iotask::interact; -use sockaddr_in = core::unstable::uvll::sockaddr_in; -use sockaddr_in6 = core::unstable::uvll::sockaddr_in6; -use addrinfo = core::unstable::uvll::addrinfo; -use uv_getaddrinfo_t = core::unstable::uvll::uv_getaddrinfo_t; -use uv_ip4_name = core::unstable::uvll::ip4_name; -use uv_ip4_port = core::unstable::uvll::ip4_port; -use uv_ip6_name = core::unstable::uvll::ip6_name; -use uv_ip6_port = core::unstable::uvll::ip6_port; -use uv_getaddrinfo = core::unstable::uvll::getaddrinfo; -use uv_freeaddrinfo = core::unstable::uvll::freeaddrinfo; -use create_uv_getaddrinfo_t = core::unstable::uvll::getaddrinfo_t; -use set_data_for_req = core::unstable::uvll::set_data_for_req; -use get_data_for_req = core::unstable::uvll::get_data_for_req; -use ll = core::unstable::uvll; +use sockaddr_in = super::uv_ll::sockaddr_in; +use sockaddr_in6 = super::uv_ll::sockaddr_in6; +use addrinfo = super::uv_ll::addrinfo; +use uv_getaddrinfo_t = super::uv_ll::uv_getaddrinfo_t; +use uv_ip4_name = super::uv_ll::ip4_name; +use uv_ip4_port = super::uv_ll::ip4_port; +use uv_ip6_name = super::uv_ll::ip6_name; +use uv_ip6_port = super::uv_ll::ip6_port; +use uv_getaddrinfo = super::uv_ll::getaddrinfo; +use uv_freeaddrinfo = super::uv_ll::freeaddrinfo; +use create_uv_getaddrinfo_t = super::uv_ll::getaddrinfo_t; +use set_data_for_req = super::uv_ll::set_data_for_req; +use get_data_for_req = super::uv_ll::get_data_for_req; +use ll = super::uv_ll; /// An IP address pub enum IpAddr { diff --git a/src/libstd/net_tcp.rs b/src/libstd/net_tcp.rs index a93e94e0d0430..c49f65d0f99b8 100644 --- a/src/libstd/net_tcp.rs +++ b/src/libstd/net_tcp.rs @@ -55,6 +55,7 @@ pub struct TcpSocket { socket_data: @TcpSocketData, } +#[unsafe_destructor] impl Drop for TcpSocket { fn finalize(&self) { unsafe { diff --git a/src/libstd/net_url.rs b/src/libstd/net_url.rs index 0bb8fdd373871..21b60584635fc 100644 --- a/src/libstd/net_url.rs +++ b/src/libstd/net_url.rs @@ -25,7 +25,7 @@ use core::to_str::ToStr; use core::to_str; use core::uint; -#[deriving_eq] +#[deriving(Eq)] struct Url { scheme: ~str, user: Option, @@ -36,7 +36,7 @@ struct Url { fragment: Option<~str> } -#[deriving_eq] +#[deriving(Eq)] struct UserInfo { user: ~str, pass: Option<~str> @@ -45,7 +45,7 @@ struct UserInfo { pub type Query = ~[(~str, ~str)]; pub impl Url { - static pure fn new( + fn new( scheme: ~str, user: Option, host: ~str, @@ -67,7 +67,7 @@ pub impl Url { } pub impl UserInfo { - static pure fn new(user: ~str, pass: Option<~str>) -> UserInfo { + fn new(user: ~str, pass: Option<~str>) -> UserInfo { UserInfo { user: user, pass: pass } } } @@ -117,7 +117,7 @@ fn encode_inner(s: &str, full_url: bool) -> ~str { * * This function is compliant with RFC 3986. */ -pub pure fn encode(s: &str) -> ~str { +pub fn encode(s: &str) -> ~str { // FIXME(#3722): unsafe only because encode_inner does (string) IO unsafe {encode_inner(s, true)} } @@ -129,7 +129,7 @@ pub pure fn encode(s: &str) -> ~str { * This function is compliant with RFC 3986. */ -pub pure fn encode_component(s: &str) -> ~str { +pub fn encode_component(s: &str) -> ~str { // FIXME(#3722): unsafe only because encode_inner does (string) IO unsafe {encode_inner(s, false)} } @@ -177,7 +177,7 @@ fn decode_inner(s: &str, full_url: bool) -> ~str { * * This will only decode escape sequences generated by encode. */ -pub pure fn decode(s: &str) -> ~str { +pub fn decode(s: &str) -> ~str { // FIXME(#3722): unsafe only because decode_inner does (string) IO unsafe {decode_inner(s, true)} } @@ -185,7 +185,7 @@ pub pure fn decode(s: &str) -> ~str { /** * Decode a string encoded with percent encoding. */ -pub pure fn decode_component(s: &str) -> ~str { +pub fn decode_component(s: &str) -> ~str { // FIXME(#3722): unsafe only because decode_inner does (string) IO unsafe {decode_inner(s, false)} } @@ -297,7 +297,7 @@ pub fn decode_form_urlencoded(s: &[u8]) -> LinearMap<~str, ~[~str]> { } -pure fn split_char_first(s: &str, c: char) -> (~str, ~str) { +fn split_char_first(s: &str, c: char) -> (~str, ~str) { let len = str::len(s); let mut index = len; let mut mat = 0; @@ -317,14 +317,14 @@ pure fn split_char_first(s: &str, c: char) -> (~str, ~str) { } } if index+mat == len { - return (str::slice(s, 0, index), ~""); + return (str::slice(s, 0, index).to_owned(), ~""); } else { - return (str::slice(s, 0, index), - str::slice(s, index + mat, str::len(s))); + return (str::slice(s, 0, index).to_owned(), + str::slice(s, index + mat, str::len(s)).to_owned()); } } -pure fn userinfo_from_str(uinfo: &str) -> UserInfo { +fn userinfo_from_str(uinfo: &str) -> UserInfo { let (user, p) = split_char_first(uinfo, ':'); let pass = if str::len(p) == 0 { None @@ -334,14 +334,14 @@ pure fn userinfo_from_str(uinfo: &str) -> UserInfo { return UserInfo::new(user, pass); } -pure fn userinfo_to_str(userinfo: &UserInfo) -> ~str { +fn userinfo_to_str(userinfo: &UserInfo) -> ~str { match userinfo.pass { Some(ref pass) => fmt!("%s:%s@", userinfo.user, *pass), None => fmt!("%s@", userinfo.user), } } -pure fn query_from_str(rawquery: &str) -> Query { +fn query_from_str(rawquery: &str) -> Query { let mut query: Query = ~[]; if str::len(rawquery) != 0 { for str::split_char(rawquery, '&').each |p| { @@ -353,7 +353,7 @@ pure fn query_from_str(rawquery: &str) -> Query { return query; } -pub pure fn query_to_str(query: &Query) -> ~str { +pub fn query_to_str(query: &Query) -> ~str { unsafe { // FIXME(#3722): unsafe only because decode_inner does (string) IO let mut strvec = ~[]; @@ -372,7 +372,7 @@ pub pure fn query_to_str(query: &Query) -> ~str { } // returns the scheme and the rest of the url, or a parsing error -pub pure fn get_scheme(rawurl: &str) -> Result<(~str, ~str), ~str> { +pub fn get_scheme(rawurl: &str) -> Result<(~str, ~str), ~str> { for str::each_chari(rawurl) |i,c| { match c { 'A' .. 'Z' | 'a' .. 'z' => loop, @@ -386,8 +386,8 @@ pub pure fn get_scheme(rawurl: &str) -> Result<(~str, ~str), ~str> { if i == 0 { return Err(~"url: Scheme cannot be empty."); } else { - return Ok((rawurl.slice(0,i), - rawurl.slice(i+1,str::len(rawurl)))); + return Ok((rawurl.slice(0,i).to_owned(), + rawurl.slice(i+1,str::len(rawurl)).to_owned())); } } _ => { @@ -398,7 +398,7 @@ pub pure fn get_scheme(rawurl: &str) -> Result<(~str, ~str), ~str> { return Err(~"url: Scheme must be terminated with a colon."); } -#[deriving_eq] +#[deriving(Eq)] enum Input { Digit, // all digits Hex, // digits and letters a-f @@ -406,7 +406,7 @@ enum Input { } // returns userinfo, host, port, and unparsed part, or an error -pure fn get_authority(rawurl: &str) -> +fn get_authority(rawurl: &str) -> Result<(Option, ~str, Option<~str>, ~str), ~str> { if !str::starts_with(rawurl, ~"//") { // there is no authority. @@ -489,7 +489,7 @@ pure fn get_authority(rawurl: &str) -> } Ip6Host => { if colon_count > 7 { - host = str::slice(rawurl, begin, i); + host = str::slice(rawurl, begin, i).to_owned(); pos = i; st = InPort; } @@ -506,13 +506,13 @@ pure fn get_authority(rawurl: &str) -> colon_count = 0; // reset count match st { Start => { - let user = str::slice(rawurl, begin, i); + let user = str::slice(rawurl, begin, i).to_owned(); userinfo = Some(UserInfo::new(user, None)); st = InHost; } PassHostPort => { - let user = str::slice(rawurl, begin, pos); - let pass = str::slice(rawurl, pos+1, i); + let user = str::slice(rawurl, begin, pos).to_owned(); + let pass = str::slice(rawurl, pos+1, i).to_owned(); userinfo = Some(UserInfo::new(user, Some(pass))); st = InHost; } @@ -534,7 +534,7 @@ pure fn get_authority(rawurl: &str) -> let end = end; // make end immutable so it can be captured - let host_is_end_plus_one: &pure fn() -> bool = || { + let host_is_end_plus_one: &fn() -> bool = || { end+1 == len && !['?', '#', '/'].contains(&(rawurl[end] as char)) }; @@ -543,37 +543,37 @@ pure fn get_authority(rawurl: &str) -> match st { Start => { if host_is_end_plus_one() { - host = str::slice(rawurl, begin, end+1); + host = str::slice(rawurl, begin, end+1).to_owned(); } else { - host = str::slice(rawurl, begin, end); + host = str::slice(rawurl, begin, end).to_owned(); } } PassHostPort | Ip6Port => { if in != Digit { return Err(~"Non-digit characters in port."); } - host = str::slice(rawurl, begin, pos); - port = Some(str::slice(rawurl, pos+1, end)); + host = str::slice(rawurl, begin, pos).to_owned(); + port = Some(str::slice(rawurl, pos+1, end).to_owned()); } Ip6Host | InHost => { - host = str::slice(rawurl, begin, end); + host = str::slice(rawurl, begin, end).to_owned(); } InPort => { if in != Digit { return Err(~"Non-digit characters in port."); } - port = Some(str::slice(rawurl, pos+1, end)); + port = Some(str::slice(rawurl, pos+1, end).to_owned()); } } let rest = if host_is_end_plus_one() { ~"" } - else { str::slice(rawurl, end, len) }; + else { str::slice(rawurl, end, len).to_owned() }; return Ok((userinfo, host, port, rest)); } // returns the path and unparsed part of url, or an error -pure fn get_path(rawurl: &str, authority: bool) -> +fn get_path(rawurl: &str, authority: bool) -> Result<(~str, ~str), ~str> { let len = str::len(rawurl); let mut end = len; @@ -599,25 +599,25 @@ pure fn get_path(rawurl: &str, authority: bool) -> } } - return Ok((decode_component(str::slice(rawurl, 0, end)), - str::slice(rawurl, end, len))); + return Ok((decode_component(str::slice(rawurl, 0, end).to_owned()), + str::slice(rawurl, end, len).to_owned())); } // returns the parsed query and the fragment, if present -pure fn get_query_fragment(rawurl: &str) -> +fn get_query_fragment(rawurl: &str) -> Result<(Query, Option<~str>), ~str> { if !str::starts_with(rawurl, ~"?") { if str::starts_with(rawurl, ~"#") { let f = decode_component(str::slice(rawurl, 1, - str::len(rawurl))); + str::len(rawurl)).to_owned()); return Ok((~[], Some(f))); } else { return Ok((~[], None)); } } let (q, r) = split_char_first(str::slice(rawurl, 1, - str::len(rawurl)), '#'); + str::len(rawurl)).to_owned(), '#'); let f = if str::len(r) != 0 { Some(decode_component(r)) } else { None }; return Ok((query_from_str(q), f)); @@ -636,7 +636,7 @@ pure fn get_query_fragment(rawurl: &str) -> * */ -pub pure fn from_str(rawurl: &str) -> Result { +pub fn from_str(rawurl: &str) -> Result { // scheme let (scheme, rest) = match get_scheme(rawurl) { Ok(val) => val, @@ -666,7 +666,7 @@ pub pure fn from_str(rawurl: &str) -> Result { } impl FromStr for Url { - static pure fn from_str(s: &str) -> Option { + fn from_str(s: &str) -> Option { match from_str(s) { Ok(url) => Some(url), Err(_) => None @@ -689,7 +689,7 @@ impl FromStr for Url { * result in just "http://somehost.com". * */ -pub pure fn to_str(url: &Url) -> ~str { +pub fn to_str(url: &Url) -> ~str { let user = match url.user { Some(ref user) => userinfo_to_str(user), None => ~"", @@ -716,13 +716,13 @@ pub pure fn to_str(url: &Url) -> ~str { } impl to_str::ToStr for Url { - pub pure fn to_str(&self) -> ~str { + pub fn to_str(&self) -> ~str { to_str(self) } } impl to_bytes::IterBytes for Url { - pure fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) { + fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) { self.to_str().iter_bytes(lsb0, f) } } diff --git a/src/libstd/oldmap.rs b/src/libstd/oldmap.rs index 0a07a24e8ee5c..b40237cf5848f 100644 --- a/src/libstd/oldmap.rs +++ b/src/libstd/oldmap.rs @@ -8,13 +8,10 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -//! A map type - **deprecated**, use `core::hashmap` instead +//! A deprecated compatibility layer on top of `core::hashmap` -use core::container::{Container, Mutable, Map}; -use core::cmp::Eq; +use core::prelude::*; use core::hash::Hash; -use core::io::WriterUtil; -use core::to_str::ToStr; use core::prelude::*; use core::to_bytes::IterBytes; use core::vec; @@ -24,353 +21,80 @@ pub type Set = HashMap; pub type HashMap = chained::T; -pub mod util { - pub struct Rational { - // : int::positive(*.den); - num: int, - den: int, - } - - 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 - } -} - - -// 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. pub mod chained { - use super::util; - - use core::io; use core::ops; - use core::option; use core::prelude::*; - use core::uint; - use core::vec; - - const initial_capacity: uint = 32u; // 2^5 - - struct Entry { - hash: uint, - key: K, - value: V, - mut next: Option<@Entry> - } + use core::hashmap::linear::LinearMap; struct HashMap_ { - mut count: uint, - mut chains: ~[Option<@Entry>] - } - - pub type T = @HashMap_; - - enum SearchResult { - NotFound, - FoundFirst(uint, @Entry), - FoundAfter(@Entry, @Entry) + priv map: LinearMap } - priv impl HashMap_ { - pure fn search_rem(&self, k: &K, h: uint, idx: uint, - e_root: @Entry) -> SearchResult { - let mut e0 = e_root; - let mut comp = 1u; // for logging - loop { - match copy e0.next { - None => { - debug!("search_tbl: absent, comp %u, hash %u, idx %u", - comp, h, idx); - return NotFound; - } - Some(e1) => { - comp += 1u; - if e1.hash == h && e1.key == *k { - debug!( - "search_tbl: present, comp %u, hash %u, idx %u", - comp, h, idx); - return FoundAfter(e0, e1); - } else { - e0 = e1; - } - } - } - }; - } - - pure fn search_tbl(&self, k: &K, h: uint) -> SearchResult { - let idx = h % vec::uniq_len(&const self.chains); - match copy self.chains[idx] { - None => { - debug!("search_tbl: none, comp %u, hash %u, idx %u", - 0u, h, idx); - return NotFound; - } - Some(e) => { - if e.hash == h && e.key == *k { - debug!("search_tbl: present, comp %u, hash %u, \ - idx %u", 1u, h, idx); - return FoundFirst(idx, e); - } else { - return self.search_rem(k, h, idx, e); - } - } - } - } - - fn rehash(@self) { - let n_old_chains = vec::uniq_len(&const self.chains); - let n_new_chains: uint = uint::next_power_of_two(n_old_chains+1u); - let mut new_chains = chains(n_new_chains); - for self.each_entry |entry| { - let idx = entry.hash % n_new_chains; - entry.next = new_chains[idx]; - new_chains[idx] = Some(entry); - } - self.chains = new_chains; - } - } + pub type T = @mut HashMap_; pub impl HashMap_ { - pure fn each_entry(&self, blk: &fn(@Entry) -> bool) { - // n.b. we can't use vec::iter() here because self.chains - // is stored in a mutable location. - let mut i = 0u, n = vec::uniq_len(&const self.chains); - while i < n { - let mut chain = self.chains[i]; - loop { - chain = match chain { - None => break, - Some(entry) => { - let next = entry.next; - if !blk(entry) { return; } - next - } - } - } - i += 1u; - } - } - - fn clear(@self) { - self.count = 0u; - self.chains = chains(initial_capacity); + fn clear(&mut self) { + self.map.clear() } } impl Container for HashMap_ { - pure fn len(&const self) -> uint { self.count } - pure fn is_empty(&const self) -> bool { self.count == 0 } + fn len(&const self) -> uint { self.map.len() } + fn is_empty(&const self) -> bool { self.map.is_empty() } } pub impl HashMap_ { - pure fn contains_key(@self, k: &K) -> bool { - let hash = k.hash_keyed(0,0) as uint; - match self.search_tbl(k, hash) { - NotFound => false, - FoundFirst(*) | FoundAfter(*) => true - } + fn contains_key(&self, k: &K) -> bool { + self.map.contains_key(k) } - fn insert(@self, k: K, v: V) -> bool { - let hash = k.hash_keyed(0,0) as uint; - match self.search_tbl(&k, hash) { - NotFound => { - self.count += 1u; - let idx = hash % vec::uniq_len(&const self.chains); - let old_chain = self.chains[idx]; - self.chains[idx] = Some(@Entry { - hash: hash, - key: k, - value: v, - next: old_chain}); - - // consider rehashing if more 3/4 full - let nchains = vec::uniq_len(&const self.chains); - let load = util::Rational { - num: (self.count + 1u) as int, - den: nchains as int, - }; - if !util::rational_leq(load, util::Rational {num:3, den:4}) { - self.rehash(); - } - - return true; - } - FoundFirst(idx, entry) => { - self.chains[idx] = Some(@Entry { - hash: hash, - key: k, - value: v, - next: entry.next}); - return false; - } - FoundAfter(prev, entry) => { - prev.next = Some(@Entry { - hash: hash, - key: k, - value: v, - next: entry.next}); - return false; - } - } + fn insert(&mut self, k: K, v: V) -> bool { + self.map.insert(k, v) } - fn remove(@self, k: &K) -> bool { - match self.search_tbl(k, k.hash_keyed(0,0) as uint) { - NotFound => false, - FoundFirst(idx, entry) => { - self.count -= 1u; - self.chains[idx] = entry.next; - true - } - FoundAfter(eprev, entry) => { - self.count -= 1u; - eprev.next = entry.next; - true - } - } + fn remove(&mut self, k: &K) -> bool { + self.map.remove(k) } - pure fn each(@self, blk: &fn(key: &K, value: &V) -> bool) { - for self.each_entry |entry| { - if !blk(&entry.key, &entry.value) { break; } - } + fn each(&self, blk: &fn(key: &K, value: &V) -> bool) { + do self.map.each |&(k, v)| { blk(k, v) } } - pure fn each_key(@self, blk: &fn(key: &K) -> bool) { - self.each(|k, _v| blk(k)) + fn each_key(&self, blk: &fn(key: &K) -> bool) { + self.map.each_key(blk) } - pure fn each_value(@self, blk: &fn(value: &V) -> bool) { - self.each(|_k, v| blk(v)) + fn each_value(&self, blk: &fn(value: &V) -> bool) { + self.map.each_value(blk) } } pub impl HashMap_ { - pure fn find(&self, k: &K) -> Option { - match self.search_tbl(k, k.hash_keyed(0,0) as uint) { - NotFound => None, - FoundFirst(_, entry) => Some(entry.value), - FoundAfter(_, entry) => Some(entry.value) - } + fn find(&self, k: &K) -> Option { + self.map.find(k).map(|&x| copy *x) } - fn update_with_key(@self, key: K, newval: V, ff: &fn(K, V, V) -> V) - -> bool { -/* - match self.find(key) { - None => return self.insert(key, val), - Some(copy orig) => return self.insert(key, ff(key, orig, val)) - } -*/ - - let hash = key.hash_keyed(0,0) as uint; - match self.search_tbl(&key, hash) { - NotFound => { - self.count += 1u; - let idx = hash % vec::uniq_len(&const self.chains); - let old_chain = self.chains[idx]; - self.chains[idx] = Some(@Entry { - hash: hash, - key: key, - value: newval, - next: old_chain}); - - // consider rehashing if more 3/4 full - let nchains = vec::uniq_len(&const self.chains); - let load = util::Rational { - num: (self.count + 1u) as int, - den: nchains as int, - }; - if !util::rational_leq(load, util::Rational {num:3, den:4}) { - self.rehash(); - } - - return true; - } - FoundFirst(idx, entry) => { - self.chains[idx] = Some(@Entry { - hash: hash, - key: key, - value: ff(key, entry.value, newval), - next: entry.next}); - return false; - } - FoundAfter(prev, entry) => { - prev.next = Some(@Entry { - hash: hash, - key: key, - value: ff(key, entry.value, newval), - next: entry.next}); - return false; - } + fn update(&mut self, key: K, newval: V, ff: &fn(V, V) -> V) -> bool { + match self.find(&key) { + None => self.insert(key, newval), + Some(orig) => self.insert(key, ff(orig, newval)) } } - fn update(@self, key: K, newval: V, ff: &fn(V, V) -> V) -> bool { - return self.update_with_key(key, newval, |_k, v, v1| ff(v,v1)); - } - - pure fn get(&self, k: &K) -> V { - let opt_v = self.find(k); - if opt_v.is_none() { - fail!(fmt!("Key not found in table: %?", k)); - } - option::unwrap(opt_v) - } - } - - pub impl - HashMap_ { - fn to_writer(&self, wr: @io::Writer) { - if self.count == 0u { - wr.write_str(~"{}"); - return; - } - - wr.write_str(~"{ "); - let mut first = true; - for self.each_entry |entry| { - if !first { - wr.write_str(~", "); - } - first = false; - wr.write_str(entry.key.to_str()); - wr.write_str(~": "); - wr.write_str((copy entry.value).to_str()); - }; - wr.write_str(~" }"); - } - } - - impl ToStr - for HashMap_ { - pure fn to_str(&self) -> ~str { - unsafe { - // Meh -- this should be safe - do io::with_str_writer |wr| { self.to_writer(wr) } - } + fn get(&self, k: &K) -> V { + copy *self.map.get(k) } } impl ops::Index for HashMap_ { - pure fn index(&self, k: K) -> V { + fn index(&self, k: K) -> V { self.get(&k) } } - fn chains(nchains: uint) -> ~[Option<@Entry>] { - vec::from_elem(nchains, None) - } - pub fn mk() -> T { - let slf: T = @HashMap_ {count: 0u, - chains: chains(initial_capacity)}; - slf + @mut HashMap_{map: LinearMap::new()} } } @@ -391,7 +115,7 @@ pub fn set_add(set: Set, key: K) } /// Convert a set into a vector. -pub pure fn vec_from_set(s: Set) -> ~[T] { +pub fn vec_from_set(s: Set) -> ~[T] { do vec::build_sized(s.len()) |push| { for s.each_key() |&k| { push(k); @@ -422,8 +146,8 @@ mod tests { #[test] fn test_simple() { debug!("*** starting test_simple"); - pure fn eq_uint(x: &uint, y: &uint) -> bool { *x == *y } - pure fn uint_id(x: &uint) -> uint { *x } + fn eq_uint(x: &uint, y: &uint) -> bool { *x == *y } + fn uint_id(x: &uint) -> uint { *x } debug!("uint -> uint"); let hm_uu: HashMap = HashMap::(); @@ -491,8 +215,8 @@ mod tests { fn test_growth() { debug!("*** starting test_growth"); let num_to_insert: uint = 64u; - pure fn eq_uint(x: &uint, y: &uint) -> bool { *x == *y } - pure fn uint_id(x: &uint) -> uint { *x } + fn eq_uint(x: &uint, y: &uint) -> bool { *x == *y } + fn uint_id(x: &uint) -> uint { *x } debug!("uint -> uint"); let hm_uu: HashMap = HashMap::(); @@ -661,35 +385,4 @@ mod tests { fail_unless!(map.get(&~"b") == 2); fail_unless!(map.get(&~"c") == 3); } - - #[test] - fn test_update_with_key() { - let map = HashMap::<~str, uint>(); - - // given a new key, initialize it with this new count, given - // given an existing key, add more to its count - fn addMoreToCount(_k: ~str, v0: uint, v1: uint) -> uint { - v0 + v1 - } - - fn addMoreToCount_simple(v0: uint, v1: uint) -> uint { - v0 + v1 - } - - // count the number of several types of animal, - // adding in groups as we go - map.update(~"cat", 1, addMoreToCount_simple); - map.update_with_key(~"mongoose", 1, addMoreToCount); - map.update(~"cat", 7, addMoreToCount_simple); - map.update_with_key(~"ferret", 3, addMoreToCount); - map.update_with_key(~"cat", 2, addMoreToCount); - - // check the total counts - fail_unless!(map.find(&~"cat").get() == 10); - fail_unless!(map.find(&~"ferret").get() == 3); - fail_unless!(map.find(&~"mongoose").get() == 1); - - // sadly, no mythical animals were counted! - fail_unless!(map.find(&~"unicorn").is_none()); - } } diff --git a/src/libstd/par.rs b/src/libstd/par.rs index 17ae48e03b93f..6f69ac4e1bd69 100644 --- a/src/libstd/par.rs +++ b/src/libstd/par.rs @@ -22,10 +22,10 @@ use future_spawn = future::spawn; * The maximum number of tasks this module will spawn for a single * operation. */ -const max_tasks : uint = 32u; +static max_tasks : uint = 32u; /// The minimum number of elements each task will process. -const min_granularity : uint = 1024u; +static min_granularity : uint = 1024u; /** * An internal helper to map a function over a large vector and diff --git a/src/libstd/priority_queue.rs b/src/libstd/priority_queue.rs index a5a291c5b18f5..ff00d26882d32 100644 --- a/src/libstd/priority_queue.rs +++ b/src/libstd/priority_queue.rs @@ -31,16 +31,16 @@ impl BaseIter for PriorityQueue { /// Visit all values in the underlying vector. /// /// The values are **not** visited in order. - pure fn each(&self, f: &fn(&T) -> bool) { self.data.each(f) } - pure fn size_hint(&self) -> Option { self.data.size_hint() } + fn each(&self, f: &fn(&T) -> bool) { self.data.each(f) } + fn size_hint(&self) -> Option { self.data.size_hint() } } impl Container for PriorityQueue { /// Returns the length of the queue - pure fn len(&const self) -> uint { vec::uniq_len(&const self.data) } + fn len(&const self) -> uint { vec::uniq_len(&const self.data) } /// Returns true if a queue contains no elements - pure fn is_empty(&const self) -> bool { self.len() == 0 } + fn is_empty(&const self) -> bool { self.len() == 0 } } impl Mutable for PriorityQueue { @@ -50,15 +50,15 @@ impl Mutable for PriorityQueue { pub impl PriorityQueue { /// Returns the greatest item in the queue - fails if empty - pure fn top(&self) -> &'self T { &self.data[0] } + fn top(&self) -> &'self T { &self.data[0] } /// Returns the greatest item in the queue - None if empty - pure fn maybe_top(&self) -> Option<&'self T> { + fn maybe_top(&self) -> Option<&'self T> { if self.is_empty() { None } else { Some(self.top()) } } /// Returns the number of elements the queue can hold without reallocating - pure fn capacity(&self) -> uint { vec::capacity(&self.data) } + fn capacity(&self) -> uint { vec::capacity(&self.data) } fn reserve(&mut self, n: uint) { vec::reserve(&mut self.data, n) } @@ -102,31 +102,31 @@ pub impl PriorityQueue { } /// Consume the PriorityQueue and return the underlying vector - pure fn to_vec(self) -> ~[T] { let PriorityQueue{data: v} = self; v } + fn to_vec(self) -> ~[T] { let PriorityQueue{data: v} = self; v } /// Consume the PriorityQueue and return a vector in sorted /// (ascending) order - pure fn to_sorted_vec(self) -> ~[T] { + fn to_sorted_vec(self) -> ~[T] { let mut q = self; let mut end = q.len(); while end > 1 { end -= 1; q.data[end] <-> q.data[0]; - unsafe { q.siftdown_range(0, end) } // purity-checking workaround + q.siftdown_range(0, end) } q.to_vec() } /// Create an empty PriorityQueue - static pure fn new() -> PriorityQueue { PriorityQueue{data: ~[],} } + fn new() -> PriorityQueue { PriorityQueue{data: ~[],} } /// Create a PriorityQueue from a vector (heapify) - static pure fn from_vec(xs: ~[T]) -> PriorityQueue { + fn from_vec(xs: ~[T]) -> PriorityQueue { let mut q = PriorityQueue{data: xs,}; let mut n = q.len() / 2; while n > 0 { n -= 1; - unsafe { q.siftdown(n) }; // purity-checking workaround + q.siftdown(n) } q } diff --git a/src/libstd/rope.rs b/src/libstd/rope.rs index dd2f5b58fb96a..51cf08c8ca1fe 100644 --- a/src/libstd/rope.rs +++ b/src/libstd/rope.rs @@ -47,7 +47,7 @@ pub type Rope = node::Root; */ /// Create an empty rope -pub pure fn empty() -> Rope { +pub fn empty() -> Rope { return node::Empty; } @@ -491,7 +491,7 @@ pub mod iterator { * * Constant time. */ -pub pure fn height(rope: Rope) -> uint { +pub fn height(rope: Rope) -> uint { match (rope) { node::Empty => return 0u, node::Content(x) => return node::height(x) @@ -507,7 +507,7 @@ pub pure fn height(rope: Rope) -> uint { * * Constant time. */ -pub pure fn char_len(rope: Rope) -> uint { +pub fn char_len(rope: Rope) -> uint { match (rope) { node::Empty => return 0u, node::Content(x) => return node::char_len(x) @@ -521,7 +521,7 @@ pub pure fn char_len(rope: Rope) -> uint { * * Constant time. */ -pub pure fn byte_len(rope: Rope) -> uint { +pub fn byte_len(rope: Rope) -> uint { match (rope) { node::Empty => return 0u, node::Content(x) => return node::byte_len(x) @@ -636,14 +636,14 @@ pub mod node { * * This is not a strict value */ - pub const hint_max_leaf_char_len: uint = 256u; + pub static hint_max_leaf_char_len: uint = 256u; /** * The maximal height that _should_ be permitted in a tree. * * This is not a strict value */ - pub const hint_max_node_height: uint = 16u; + pub static hint_max_node_height: uint = 16u; /** * Adopt a string as a node. @@ -761,7 +761,7 @@ pub mod node { } } - pub pure fn byte_len(node: @Node) -> uint { + pub fn byte_len(node: @Node) -> uint { //FIXME (#2744): Could we do this without the pattern-matching? match (*node) { Leaf(y) => y.byte_len, @@ -769,7 +769,7 @@ pub mod node { } } - pub pure fn char_len(node: @Node) -> uint { + pub fn char_len(node: @Node) -> uint { match (*node) { Leaf(y) => y.char_len, Concat(ref y) => y.char_len @@ -1050,7 +1050,7 @@ pub mod node { }) } - pub pure fn height(node: @Node) -> uint { + pub fn height(node: @Node) -> uint { match (*node) { Leaf(_) => 0u, Concat(ref x) => x.height, @@ -1131,7 +1131,7 @@ pub mod node { * proportional to the height of the rope + the (bounded) * length of the largest leaf. */ - pub pure 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 { @@ -1295,7 +1295,7 @@ mod tests { node::Leaf(x) => { *str += str::slice( *x.content, x.byte_offset, - x.byte_offset + x.byte_len); + x.byte_offset + x.byte_len).to_owned(); } node::Concat(ref x) => { aux(str, x.left); diff --git a/src/libstd/semver.rs b/src/libstd/semver.rs index 85996c8ac4ad4..50579db47072b 100644 --- a/src/libstd/semver.rs +++ b/src/libstd/semver.rs @@ -19,7 +19,7 @@ use core::str; use core::to_str::ToStr; use core::uint; -#[deriving_eq] +#[deriving(Eq)] pub enum Identifier { Numeric(uint), AlphaNumeric(~str) @@ -27,7 +27,7 @@ pub enum Identifier { impl cmp::Ord for Identifier { #[inline(always)] - pure fn lt(&self, other: &Identifier) -> bool { + fn lt(&self, other: &Identifier) -> bool { match (self, other) { (&Numeric(a), &Numeric(b)) => a < b, (&Numeric(_), _) => true, @@ -36,22 +36,22 @@ impl cmp::Ord for Identifier { } } #[inline(always)] - pure fn le(&self, other: &Identifier) -> bool { + fn le(&self, other: &Identifier) -> bool { ! (other < self) } #[inline(always)] - pure fn gt(&self, other: &Identifier) -> bool { + fn gt(&self, other: &Identifier) -> bool { other < self } #[inline(always)] - pure fn ge(&self, other: &Identifier) -> bool { + fn ge(&self, other: &Identifier) -> bool { ! (self < other) } } impl ToStr for Identifier { #[inline(always)] - pure fn to_str(&self) -> ~str { + fn to_str(&self) -> ~str { match self { &Numeric(n) => n.to_str(), &AlphaNumeric(ref s) => s.to_str() @@ -60,7 +60,7 @@ impl ToStr for Identifier { } -#[deriving_eq] +#[deriving(Eq)] pub struct Version { major: uint, minor: uint, @@ -71,7 +71,7 @@ pub struct Version { impl ToStr for Version { #[inline(always)] - pure fn to_str(&self) -> ~str { + fn to_str(&self) -> ~str { let s = fmt!("%u.%u.%u", self.major, self.minor, self.patch); let s = if self.pre.is_empty() { s @@ -88,7 +88,7 @@ impl ToStr for Version { impl cmp::Ord for Version { #[inline(always)] - pure fn lt(&self, other: &Version) -> bool { + fn lt(&self, other: &Version) -> bool { self.major < other.major || @@ -121,15 +121,15 @@ impl cmp::Ord for Version { } #[inline(always)] - pure fn le(&self, other: &Version) -> bool { + fn le(&self, other: &Version) -> bool { ! (other < self) } #[inline(always)] - pure fn gt(&self, other: &Version) -> bool { + fn gt(&self, other: &Version) -> bool { other < self } #[inline(always)] - pure fn ge(&self, other: &Version) -> bool { + fn ge(&self, other: &Version) -> bool { ! (self < other) } } @@ -228,7 +228,7 @@ pub fn parse(s: &str) -> Option { do bad_parse::cond.trap(|_| { debug!("bad"); bad = true }).in { do io::with_str_reader(s) |rdr| { let v = parse_reader(rdr); - if bad || v.to_str() != s { + if bad || v.to_str() != s.to_owned() { None } else { Some(v) diff --git a/src/libstd/serialize.rs b/src/libstd/serialize.rs index 2c927b5db16cf..d288c06d2935c 100644 --- a/src/libstd/serialize.rs +++ b/src/libstd/serialize.rs @@ -110,7 +110,7 @@ pub trait Encodable { } pub trait Decodable { - static fn decode(&self, d: &D) -> Self; + fn decode(d: &D) -> Self; } impl Encodable for uint { @@ -118,7 +118,7 @@ impl Encodable for uint { } impl Decodable for uint { - static fn decode(&self, d: &D) -> uint { + fn decode(d: &D) -> uint { d.read_uint() } } @@ -128,7 +128,7 @@ impl Encodable for u8 { } impl Decodable for u8 { - static fn decode(&self, d: &D) -> u8 { + fn decode(d: &D) -> u8 { d.read_u8() } } @@ -138,7 +138,7 @@ impl Encodable for u16 { } impl Decodable for u16 { - static fn decode(&self, d: &D) -> u16 { + fn decode(d: &D) -> u16 { d.read_u16() } } @@ -148,7 +148,7 @@ impl Encodable for u32 { } impl Decodable for u32 { - static fn decode(&self, d: &D) -> u32 { + fn decode(d: &D) -> u32 { d.read_u32() } } @@ -158,7 +158,7 @@ impl Encodable for u64 { } impl Decodable for u64 { - static fn decode(&self, d: &D) -> u64 { + fn decode(d: &D) -> u64 { d.read_u64() } } @@ -168,7 +168,7 @@ impl Encodable for int { } impl Decodable for int { - static fn decode(&self, d: &D) -> int { + fn decode(d: &D) -> int { d.read_int() } } @@ -178,7 +178,7 @@ impl Encodable for i8 { } impl Decodable for i8 { - static fn decode(&self, d: &D) -> i8 { + fn decode(d: &D) -> i8 { d.read_i8() } } @@ -188,7 +188,7 @@ impl Encodable for i16 { } impl Decodable for i16 { - static fn decode(&self, d: &D) -> i16 { + fn decode(d: &D) -> i16 { d.read_i16() } } @@ -198,7 +198,7 @@ impl Encodable for i32 { } impl Decodable for i32 { - static fn decode(&self, d: &D) -> i32 { + fn decode(d: &D) -> i32 { d.read_i32() } } @@ -208,7 +208,7 @@ impl Encodable for i64 { } impl Decodable for i64 { - static fn decode(&self, d: &D) -> i64 { + fn decode(d: &D) -> i64 { d.read_i64() } } @@ -222,7 +222,7 @@ impl Encodable for ~str { } impl Decodable for ~str { - static fn decode(&self, d: &D) -> ~str { + fn decode(d: &D) -> ~str { d.read_owned_str() } } @@ -232,7 +232,7 @@ impl Encodable for @str { } impl Decodable for @str { - static fn decode(&self, d: &D) -> @str { + fn decode(d: &D) -> @str { d.read_managed_str() } } @@ -242,7 +242,7 @@ impl Encodable for float { } impl Decodable for float { - static fn decode(&self, d: &D) -> float { + fn decode(d: &D) -> float { d.read_float() } } @@ -252,7 +252,7 @@ impl Encodable for f32 { } impl Decodable for f32 { - static fn decode(&self, d: &D) -> f32 { + fn decode(d: &D) -> f32 { d.read_f32() } } @@ -261,7 +261,7 @@ impl Encodable for f64 { } impl Decodable for f64 { - static fn decode(&self, d: &D) -> f64 { + fn decode(d: &D) -> f64 { d.read_f64() } } @@ -271,7 +271,7 @@ impl Encodable for bool { } impl Decodable for bool { - static fn decode(&self, d: &D) -> bool { + fn decode(d: &D) -> bool { d.read_bool() } } @@ -281,7 +281,7 @@ impl Encodable for () { } impl Decodable for () { - static fn decode(&self, d: &D) -> () { + fn decode(d: &D) -> () { d.read_nil() } } @@ -299,7 +299,7 @@ impl> Encodable for ~T { } impl> Decodable for ~T { - static fn decode(&self, d: &D) -> ~T { + fn decode(d: &D) -> ~T { d.read_owned(|| ~Decodable::decode(d)) } } @@ -311,7 +311,7 @@ impl> Encodable for @T { } impl> Decodable for @T { - static fn decode(&self, d: &D) -> @T { + fn decode(d: &D) -> @T { d.read_managed(|| @Decodable::decode(d)) } } @@ -337,7 +337,7 @@ impl> Encodable for ~[T] { } impl> Decodable for ~[T] { - static fn decode(&self, d: &D) -> ~[T] { + fn decode(d: &D) -> ~[T] { do d.read_owned_vec |len| { do vec::from_fn(len) |i| { d.read_vec_elt(i, || Decodable::decode(d)) @@ -357,7 +357,7 @@ impl> Encodable for @[T] { } impl> Decodable for @[T] { - static fn decode(&self, d: &D) -> @[T] { + fn decode(d: &D) -> @[T] { do d.read_managed_vec |len| { do at_vec::from_fn(len) |i| { d.read_vec_elt(i, || Decodable::decode(d)) @@ -382,7 +382,7 @@ impl> Encodable for Option { } impl> Decodable for Option { - static fn decode(&self, d: &D) -> Option { + fn decode(d: &D) -> Option { do d.read_enum(~"option") { do d.read_enum_variant |i| { match i { @@ -410,7 +410,7 @@ impl,T1:Encodable> Encodable for (T0, T1) { } impl,T1:Decodable> Decodable for (T0, T1) { - static fn decode(&self, d: &D) -> (T0, T1) { + fn decode(d: &D) -> (T0, T1) { do d.read_tup(2) { ( d.read_tup_elt(0, || Decodable::decode(d)), @@ -445,7 +445,7 @@ impl< T1: Decodable, T2: Decodable > Decodable for (T0, T1, T2) { - static fn decode(&self, d: &D) -> (T0, T1, T2) { + fn decode(d: &D) -> (T0, T1, T2) { do d.read_tup(3) { ( d.read_tup_elt(0, || Decodable::decode(d)), @@ -484,7 +484,7 @@ impl< T2: Decodable, T3: Decodable > Decodable for (T0, T1, T2, T3) { - static fn decode(&self, d: &D) -> (T0, T1, T2, T3) { + fn decode(d: &D) -> (T0, T1, T2, T3) { do d.read_tup(4) { ( d.read_tup_elt(0, || Decodable::decode(d)), @@ -527,7 +527,7 @@ impl< T3: Decodable, T4: Decodable > Decodable for (T0, T1, T2, T3, T4) { - static fn decode(&self, d: &D) + fn decode(d: &D) -> (T0, T1, T2, T3, T4) { do d.read_tup(5) { ( diff --git a/src/libstd/sha1.rs b/src/libstd/sha1.rs index f7e31bc7df758..64399defd54f7 100644 --- a/src/libstd/sha1.rs +++ b/src/libstd/sha1.rs @@ -53,13 +53,13 @@ trait Sha1 { } // Some unexported constants -const digest_buf_len: uint = 5u; -const msg_block_len: uint = 64u; -const work_buf_len: uint = 80u; -const k0: u32 = 0x5A827999u32; -const k1: u32 = 0x6ED9EBA1u32; -const k2: u32 = 0x8F1BBCDCu32; -const k3: u32 = 0xCA62C1D6u32; +static digest_buf_len: uint = 5u; +static msg_block_len: uint = 64u; +static work_buf_len: uint = 80u; +static k0: u32 = 0x5A827999u32; +static k1: u32 = 0x6ED9EBA1u32; +static k2: u32 = 0x8F1BBCDCu32; +static k3: u32 = 0xCA62C1D6u32; /// Construct a `sha` object @@ -399,7 +399,7 @@ mod tests { while left > 0u { let take = (left + 1u) / 2u; sh.input_str(str::slice(t.input, len - left, - take + len - left)); + take + len - left).to_owned()); left = left - take; } let out = sh.result(); diff --git a/src/libstd/smallintmap.rs b/src/libstd/smallintmap.rs index dc2688a20e73d..4ad8d38b072b1 100644 --- a/src/libstd/smallintmap.rs +++ b/src/libstd/smallintmap.rs @@ -24,7 +24,7 @@ pub struct SmallIntMap { impl BaseIter<(uint, &'self V)> for SmallIntMap { /// Visit all key-value pairs in order - pure fn each(&self, it: &fn(&(uint, &'self V)) -> bool) { + fn each(&self, it: &fn(&(uint, &'self V)) -> bool) { for uint::range(0, self.v.len()) |i| { match self.v[i] { Some(ref elt) => if !it(&(i, elt)) { break }, @@ -33,12 +33,12 @@ impl BaseIter<(uint, &'self V)> for SmallIntMap { } } - pure fn size_hint(&self) -> Option { Some(self.len()) } + fn size_hint(&self) -> Option { Some(self.len()) } } impl ReverseIter<(uint, &'self V)> for SmallIntMap { /// Visit all key-value pairs in reverse order - pure fn each_reverse(&self, it: &fn(&(uint, &'self V)) -> bool) { + fn each_reverse(&self, it: &fn(&(uint, &'self V)) -> bool) { for uint::range_rev(self.v.len(), 0) |i| { match self.v[i - 1] { Some(ref elt) => if !it(&(i - 1, elt)) { break }, @@ -50,7 +50,7 @@ impl ReverseIter<(uint, &'self V)> for SmallIntMap { impl Container for SmallIntMap { /// Return the number of elements in the map - pure fn len(&const self) -> uint { + fn len(&const self) -> uint { let mut sz = 0; for uint::range(0, vec::uniq_len(&const self.v)) |i| { match self.v[i] { @@ -62,7 +62,7 @@ impl Container for SmallIntMap { } /// Return true if the map contains no elements - pure fn is_empty(&const self) -> bool { self.len() == 0 } + fn is_empty(&const self) -> bool { self.len() == 0 } } impl Mutable for SmallIntMap { @@ -72,21 +72,21 @@ impl Mutable for SmallIntMap { impl Map for SmallIntMap { /// Return true if the map contains a value for the specified key - pure fn contains_key(&self, key: &uint) -> bool { + fn contains_key(&self, key: &uint) -> bool { self.find(key).is_some() } /// Visit all keys in order - pure fn each_key(&self, blk: &fn(key: &uint) -> bool) { + fn each_key(&self, blk: &fn(key: &uint) -> bool) { self.each(|&(k, _)| blk(&k)) } /// Visit all values in order - pure fn each_value(&self, blk: &fn(value: &V) -> bool) { + fn each_value(&self, blk: &fn(value: &V) -> bool) { self.each(|&(_, v)| blk(v)) } - /// Visit all key-value pairs in order + /// Iterate over the map and mutate the contained values fn mutate_values(&mut self, it: &fn(&uint, &'self mut V) -> bool) { for uint::range(0, self.v.len()) |i| { match self.v[i] { @@ -96,8 +96,8 @@ impl Map for SmallIntMap { } } - /// Iterate over the map and mutate the contained values - pure fn find(&self, key: &uint) -> Option<&'self V> { + /// Return a reference to the value corresponding to the key + fn find(&self, key: &uint) -> Option<&'self V> { if *key < self.v.len() { match self.v[*key] { Some(ref value) => Some(value), @@ -108,6 +108,18 @@ impl Map for SmallIntMap { } } + /// Return a mutable reference to the value corresponding to the key + fn find_mut(&mut self, key: &uint) -> Option<&'self mut V> { + if *key < self.v.len() { + match self.v[*key] { + Some(ref mut value) => Some(value), + None => None + } + } else { + None + } + } + /// Insert a key-value pair into the map. An existing value for a /// key is replaced by the new value. Return true if the key did /// not already exist in the map. @@ -135,9 +147,9 @@ impl Map for SmallIntMap { pub impl SmallIntMap { /// Create an empty SmallIntMap - static pure fn new() -> SmallIntMap { SmallIntMap{v: ~[]} } + fn new() -> SmallIntMap { SmallIntMap{v: ~[]} } - pure fn get(&self, key: &uint) -> &'self V { + fn get(&self, key: &uint) -> &'self V { self.find(key).expect("key not present") } } @@ -160,6 +172,20 @@ pub impl SmallIntMap { #[cfg(test)] mod tests { use super::SmallIntMap; + use core::prelude::*; + + #[test] + fn test_find_mut() { + let mut m = SmallIntMap::new(); + fail_unless!(m.insert(1, 12)); + fail_unless!(m.insert(2, 8)); + fail_unless!(m.insert(5, 14)); + let new = 100; + match m.find_mut(&5) { + None => fail!(), Some(x) => *x = new + } + assert_eq!(m.find(&5), Some(&new)); + } #[test] fn test_len() { diff --git a/src/libstd/sort.rs b/src/libstd/sort.rs index 40be303a14782..1dc990526f0b6 100644 --- a/src/libstd/sort.rs +++ b/src/libstd/sort.rs @@ -16,7 +16,7 @@ use core::util; use core::vec::{len, push}; use core::vec; -type Le = &'self pure fn(v1: &T, v2: &T) -> bool; +type Le = &'self fn(v1: &T, v2: &T) -> bool; /** * Merge sort. Returns a new vector containing the sorted list. @@ -24,7 +24,7 @@ type Le = &'self 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. */ -pub pure fn merge_sort(v: &[const T], le: Le) -> ~[T] { +pub fn merge_sort(v: &[const T], le: Le) -> ~[T] { type Slice = (uint, uint); unsafe {return merge_sort_(v, (0u, len(v)), le);} @@ -177,9 +177,9 @@ impl Sort for &'self mut [T] { fn qsort(self) { quick_sort3(self); } } -const MIN_MERGE: uint = 64; -const MIN_GALLOP: uint = 7; -const INITIAL_TMP_STORAGE: uint = 128; +static MIN_MERGE: uint = 64; +static MIN_GALLOP: uint = 7; +static INITIAL_TMP_STORAGE: uint = 128; pub fn tim_sort(array: &mut [T]) { let size = array.len(); @@ -259,7 +259,7 @@ fn reverse_slice(v: &mut [T], start: uint, end:uint) { } } -pure fn min_run_length(n: uint) -> uint { +fn min_run_length(n: uint) -> uint { let mut n = n; let mut r = 0; // becomes 1 if any 1 bits are shifted off @@ -290,7 +290,7 @@ fn count_run_ascending(array: &mut [T]) -> uint { return run; } -pure fn gallop_left(key: &const T, array: &[const T], +fn gallop_left(key: &const T, array: &[const T], hint: uint) -> uint { let size = array.len(); fail_unless!(size != 0 && hint < size); @@ -339,7 +339,7 @@ pure fn gallop_left(key: &const T, array: &[const T], return ofs; } -pure fn gallop_right(key: &const T, array: &[const T], +fn gallop_right(key: &const T, array: &[const T], hint: uint) -> uint { let size = array.len(); fail_unless!(size != 0 && hint < size); @@ -779,7 +779,7 @@ mod test_qsort { pub fn check_sort(v1: &mut [int], v2: &mut [int]) { let len = vec::len::(v1); - pure fn leual(a: &int, b: &int) -> bool { *a <= *b } + fn leual(a: &int, b: &int) -> bool { *a <= *b } quick_sort::(v1, leual); let mut i = 0u; while i < len { @@ -844,7 +844,7 @@ mod tests { pub fn check_sort(v1: &[int], v2: &[int]) { let len = vec::len::(v1); - pub pure fn le(a: &int, b: &int) -> bool { *a <= *b } + pub fn le(a: &int, b: &int) -> bool { *a <= *b } let f = le; let v3 = merge_sort::(v1, f); let mut i = 0u; @@ -874,7 +874,7 @@ mod tests { #[test] pub fn test_merge_sort_mutable() { - pub pure fn le(a: &int, b: &int) -> bool { *a <= *b } + pub fn le(a: &int, b: &int) -> bool { *a <= *b } let mut v1 = ~[3, 2, 1]; let v2 = merge_sort(v1, le); fail_unless!(v2 == ~[1, 2, 3]); @@ -883,7 +883,7 @@ mod tests { #[test] pub fn test_merge_sort_stability() { // tjc: funny that we have to use parens - pure fn ile(x: &(&'static str), y: &(&'static str)) -> bool + fn ile(x: &(&'static str), y: &(&'static str)) -> bool { unsafe // to_lower is not pure... { @@ -917,16 +917,16 @@ mod test_tim_sort { } impl Ord for CVal { - pure fn lt(&self, other: &CVal) -> bool { + fn lt(&self, other: &CVal) -> bool { unsafe { let rng = rand::Rng(); if rng.gen_float() > 0.995 { fail!(~"It's happening!!!"); } } (*self).val < other.val } - pure fn le(&self, other: &CVal) -> bool { (*self).val <= other.val } - pure fn gt(&self, other: &CVal) -> bool { (*self).val > other.val } - pure fn ge(&self, other: &CVal) -> bool { (*self).val >= other.val } + fn le(&self, other: &CVal) -> bool { (*self).val <= other.val } + fn gt(&self, other: &CVal) -> bool { (*self).val > other.val } + fn ge(&self, other: &CVal) -> bool { (*self).val >= other.val } } fn check_sort(v1: &mut [int], v2: &mut [int]) { @@ -982,10 +982,10 @@ mod test_tim_sort { struct DVal { val: uint } impl Ord for DVal { - pure fn lt(&self, _x: &DVal) -> bool { true } - pure fn le(&self, _x: &DVal) -> bool { true } - pure fn gt(&self, _x: &DVal) -> bool { true } - pure fn ge(&self, _x: &DVal) -> bool { true } + fn lt(&self, _x: &DVal) -> bool { true } + fn le(&self, _x: &DVal) -> bool { true } + fn gt(&self, _x: &DVal) -> bool { true } + fn ge(&self, _x: &DVal) -> bool { true } } #[test] @@ -1190,7 +1190,8 @@ mod big_tests { key: &'self fn(@uint), } - impl Drop for LVal/&self { + #[unsafe_destructor] + impl<'self> Drop for LVal<'self> { fn finalize(&self) { let x = unsafe { task::local_data::local_data_get(self.key) }; match x { @@ -1204,17 +1205,17 @@ mod big_tests { } } - impl Ord for LVal/&self { - pure fn lt(&self, other: &'a LVal/&self) -> bool { + impl<'self> Ord for LVal<'self> { + fn lt(&self, other: &'a LVal<'self>) -> bool { (*self).val < other.val } - pure fn le(&self, other: &'a LVal/&self) -> bool { + fn le(&self, other: &'a LVal<'self>) -> bool { (*self).val <= other.val } - pure fn gt(&self, other: &'a LVal/&self) -> bool { + fn gt(&self, other: &'a LVal<'self>) -> bool { (*self).val > other.val } - pure fn ge(&self, other: &'a LVal/&self) -> bool { + fn ge(&self, other: &'a LVal<'self>) -> bool { (*self).val >= other.val } } diff --git a/src/libstd/std.rc b/src/libstd/std.rc index 85e914a60a140..aa5371671c194 100644 --- a/src/libstd/std.rc +++ b/src/libstd/std.rc @@ -28,7 +28,6 @@ not required in or otherwise suitable for the core library. #[allow(vecs_implicitly_copyable)]; #[deny(non_camel_case_types)]; -#[deny(deprecated_self)]; #[allow(deprecated_mutable_fields)]; #[no_core]; @@ -36,7 +35,7 @@ not required in or otherwise suitable for the core library. extern mod core(vers = "0.6"); use core::*; -pub use uv_ll = core::unstable::uvll; +pub mod uv_ll; // General io and system-services modules diff --git a/src/libstd/sync.rs b/src/libstd/sync.rs index d47232cc5352e..569c67eac93fb 100644 --- a/src/libstd/sync.rs +++ b/src/libstd/sync.rs @@ -167,31 +167,35 @@ type SemRelease = SemReleaseGeneric<'self, ()>; type SemAndSignalRelease = SemReleaseGeneric<'self, ~[Waitqueue]>; struct SemReleaseGeneric { sem: &'self Sem } -impl Drop for SemReleaseGeneric/&self { +#[unsafe_destructor] +impl Drop for SemReleaseGeneric<'self, Q> { fn finalize(&self) { - self.sem.release(); + unsafe { + self.sem.release(); + } } } -fn SemRelease(sem: &'r Sem<()>) -> SemRelease/&r { +fn SemRelease(sem: &'r Sem<()>) -> SemRelease<'r> { SemReleaseGeneric { sem: sem } } fn SemAndSignalRelease(sem: &'r Sem<~[Waitqueue]>) - -> SemAndSignalRelease/&r { + -> SemAndSignalRelease<'r> { SemReleaseGeneric { sem: sem } } /// A mechanism for atomic-unlock-and-deschedule blocking and signalling. -pub struct Condvar { priv sem: &'self Sem<~[Waitqueue]> } +pub struct Condvar<'self> { priv sem: &'self Sem<~[Waitqueue]> } -impl Drop for Condvar/&self { fn finalize(&self) {} } +#[unsafe_destructor] +impl<'self> Drop for Condvar<'self> { fn finalize(&self) {} } -pub impl Condvar/&self { +pub impl Condvar<'self> { /** * Atomically drop the associated lock, and block until a signal is sent. * @@ -261,7 +265,8 @@ pub impl Condvar/&self { sem: &'self Sem<~[Waitqueue]>, } - impl Drop for SemAndSignalReacquire/&self { + #[unsafe_destructor] + impl<'self> Drop for SemAndSignalReacquire<'self> { fn finalize(&self) { unsafe { // Needs to succeed, instead of itself dying. @@ -273,7 +278,7 @@ pub impl Condvar/&self { } fn SemAndSignalReacquire(sem: &'r Sem<~[Waitqueue]>) - -> SemAndSignalReacquire/&r { + -> SemAndSignalReacquire<'r> { SemAndSignalReacquire { sem: sem } @@ -581,7 +586,9 @@ pub impl RWlock { } /// To be called inside of the write_downgrade block. - fn downgrade(&self, token: RWlockWriteMode/&a) -> RWlockReadMode/&a { + fn downgrade<'a>(&self, + token: RWlockWriteMode<'a>) + -> RWlockReadMode<'a> { if !ptr::ref_eq(self, token.lock) { fail!(~"Can't downgrade() with a different rwlock's write_mode!"); } @@ -613,7 +620,8 @@ struct RWlockReleaseRead { lock: &'self RWlock, } -impl Drop for RWlockReleaseRead/&self { +#[unsafe_destructor] +impl<'self> Drop for RWlockReleaseRead<'self> { fn finalize(&self) { unsafe { do task::unkillable { @@ -635,7 +643,7 @@ impl Drop for RWlockReleaseRead/&self { } } -fn RWlockReleaseRead(lock: &'r RWlock) -> RWlockReleaseRead/&r { +fn RWlockReleaseRead<'r>(lock: &'r RWlock) -> RWlockReleaseRead<'r> { RWlockReleaseRead { lock: lock } @@ -643,11 +651,13 @@ fn RWlockReleaseRead(lock: &'r RWlock) -> RWlockReleaseRead/&r { // FIXME(#3588) should go inside of downgrade() #[doc(hidden)] +#[unsafe_destructor] struct RWlockReleaseDowngrade { lock: &'self RWlock, } -impl Drop for RWlockReleaseDowngrade/&self { +#[unsafe_destructor] +impl<'self> Drop for RWlockReleaseDowngrade<'self> { fn finalize(&self) { unsafe { do task::unkillable { @@ -677,21 +687,24 @@ impl Drop for RWlockReleaseDowngrade/&self { } } -fn RWlockReleaseDowngrade(lock: &'r RWlock) -> RWlockReleaseDowngrade/&r { +fn RWlockReleaseDowngrade<'r>(lock: &'r RWlock) + -> RWlockReleaseDowngrade<'r> { RWlockReleaseDowngrade { lock: lock } } /// The "write permission" token used for rwlock.write_downgrade(). -pub struct RWlockWriteMode { priv lock: &'self RWlock } -impl Drop for RWlockWriteMode/&self { fn finalize(&self) {} } +pub struct RWlockWriteMode<'self> { priv lock: &'self RWlock } +#[unsafe_destructor] +impl<'self> Drop for RWlockWriteMode<'self> { fn finalize(&self) {} } /// The "read permission" token used for rwlock.write_downgrade(). pub struct RWlockReadMode { priv lock: &'self RWlock } -impl Drop for RWlockReadMode/&self { fn finalize(&self) {} } +#[unsafe_destructor] +impl<'self> Drop for RWlockReadMode<'self> { fn finalize(&self) {} } -pub impl RWlockWriteMode/&self { +pub impl<'self> RWlockWriteMode<'self> { /// Access the pre-downgrade rwlock in write mode. fn write(&self, blk: &fn() -> U) -> U { blk() } /// Access the pre-downgrade rwlock in write mode with a condvar. @@ -700,7 +713,7 @@ pub impl RWlockWriteMode/&self { } } -pub impl RWlockReadMode/&self { +pub impl<'self> RWlockReadMode<'self> { /// Access the post-downgrade rwlock in read mode. fn read(&self, blk: &fn() -> U) -> U { blk() } } diff --git a/src/libstd/task_pool.rs b/src/libstd/task_pool.rs index 09cab72ab2173..16645f151ee8e 100644 --- a/src/libstd/task_pool.rs +++ b/src/libstd/task_pool.rs @@ -28,6 +28,7 @@ pub struct TaskPool { } +#[unsafe_destructor] impl Drop for TaskPool { fn finalize(&self) { for self.channels.each |channel| { @@ -42,9 +43,10 @@ pub impl TaskPool { /// new scheduler with the given mode. The provided `init_fn_factory` /// returns a function which, given the index of the task, should return /// local data to be kept around in that task. - static fn new(n_tasks: uint, - opt_sched_mode: Option, - init_fn_factory: ~fn() -> ~fn(uint) -> T) -> TaskPool { + fn new(n_tasks: uint, + opt_sched_mode: Option, + init_fn_factory: ~fn() -> ~fn(uint) -> T) + -> TaskPool { fail_unless!(n_tasks >= 1); let channels = do vec::from_fn(n_tasks) |i| { diff --git a/src/libstd/term.rs b/src/libstd/term.rs index 2a8c8b3b06bbd..a6c8884e05d4d 100644 --- a/src/libstd/term.rs +++ b/src/libstd/term.rs @@ -17,24 +17,24 @@ use core::vec; // FIXME (#2807): Windows support. -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; +pub static color_black: u8 = 0u8; +pub static color_red: u8 = 1u8; +pub static color_green: u8 = 2u8; +pub static color_yellow: u8 = 3u8; +pub static color_blue: u8 = 4u8; +pub static color_magenta: u8 = 5u8; +pub static color_cyan: u8 = 6u8; +pub static color_light_gray: u8 = 7u8; +pub static color_light_grey: u8 = 7u8; +pub static color_dark_gray: u8 = 8u8; +pub static color_dark_grey: u8 = 8u8; +pub static color_bright_red: u8 = 9u8; +pub static color_bright_green: u8 = 10u8; +pub static color_bright_yellow: u8 = 11u8; +pub static color_bright_blue: u8 = 12u8; +pub static color_bright_magenta: u8 = 13u8; +pub static color_bright_cyan: u8 = 14u8; +pub static color_bright_white: u8 = 15u8; pub fn esc(writer: @io::Writer) { writer.write(~[0x1bu8, '[' as u8]); } diff --git a/src/libstd/test.rs b/src/libstd/test.rs index fcc60c8d97819..d039e8eef5aa6 100644 --- a/src/libstd/test.rs +++ b/src/libstd/test.rs @@ -53,7 +53,7 @@ pub enum TestName { DynTestName(~str) } impl ToStr for TestName { - pure fn to_str(&self) -> ~str { + fn to_str(&self) -> ~str { match self { &StaticTestName(s) => s.to_str(), &DynTestName(s) => s.to_str() @@ -188,13 +188,13 @@ pub fn parse_opts(args: &[~str]) -> OptRes { either::Left(test_opts) } -#[deriving_eq] +#[deriving(Eq)] pub struct BenchSamples { ns_iter_samples: ~[f64], mb_s: uint } -#[deriving_eq] +#[deriving(Eq)] pub enum TestResult { TrOk, TrFailed, TrIgnored, TrBench(BenchSamples) } struct ConsoleTestState { @@ -477,10 +477,10 @@ fn run_tests(opts: &TestOpts, // Windows tends to dislike being overloaded with threads. #[cfg(windows)] -const sched_overcommit : uint = 1; +static sched_overcommit : uint = 1; #[cfg(unix)] -const sched_overcommit : uint = 4u; +static sched_overcommit : uint = 4u; fn get_concurrency() -> uint { unsafe { @@ -536,7 +536,7 @@ pub fn filter_tests( }; // Sort the tests alphabetically - pure fn lteq(t1: &TestDescAndFn, t2: &TestDescAndFn) -> bool { + fn lteq(t1: &TestDescAndFn, t2: &TestDescAndFn) -> bool { str::le(t1.desc.name.to_str(), t2.desc.name.to_str()) } sort::quick_sort(filtered, lteq); diff --git a/src/libstd/time.rs b/src/libstd/time.rs index d768eef9a8c9b..9ac302ed890ca 100644 --- a/src/libstd/time.rs +++ b/src/libstd/time.rs @@ -17,7 +17,7 @@ use core::prelude::*; use core::result::{Result, Ok, Err}; use core::str; -const NSEC_PER_SEC: i32 = 1_000_000_000_i32; +static NSEC_PER_SEC: i32 = 1_000_000_000_i32; pub mod rustrt { use super::Tm; @@ -40,6 +40,7 @@ pub mod rustrt { /// A record specifying a time value in seconds and nanoseconds. #[auto_encode] #[auto_decode] +#[deriving(Eq)] pub struct Timespec { sec: i64, nsec: i32 } /* @@ -51,27 +52,20 @@ pub struct Timespec { sec: i64, nsec: i32 } * nsec: 800_000_000_i32 }`. */ pub impl Timespec { - static pure fn new(sec: i64, nsec: i32) -> Timespec { + fn new(sec: i64, nsec: i32) -> Timespec { fail_unless!(nsec >= 0 && nsec < NSEC_PER_SEC); Timespec { sec: sec, nsec: nsec } } } -impl Eq for Timespec { - pure fn eq(&self, other: &Timespec) -> bool { - self.sec == other.sec && self.nsec == other.nsec - } - pure fn ne(&self, other: &Timespec) -> bool { !self.eq(other) } -} - impl Ord for Timespec { - pure fn lt(&self, other: &Timespec) -> bool { + fn lt(&self, other: &Timespec) -> bool { self.sec < other.sec || (self.sec == other.sec && self.nsec < other.nsec) } - pure fn le(&self, other: &Timespec) -> bool { !other.lt(self) } - pure fn ge(&self, other: &Timespec) -> bool { !self.lt(other) } - pure fn gt(&self, other: &Timespec) -> bool { !self.le(other) } + fn le(&self, other: &Timespec) -> bool { !other.lt(self) } + fn ge(&self, other: &Timespec) -> bool { !self.lt(other) } + fn gt(&self, other: &Timespec) -> bool { !self.le(other) } } /** @@ -117,6 +111,7 @@ pub fn tzset() { #[auto_encode] #[auto_decode] +#[deriving(Eq)] pub struct Tm { tm_sec: i32, // seconds after the minute ~[0-60] tm_min: i32, // minutes after the hour ~[0-59] @@ -132,25 +127,7 @@ pub struct Tm { tm_nsec: i32, // nanoseconds } -impl Eq for Tm { - pure fn eq(&self, other: &Tm) -> bool { - self.tm_sec == (*other).tm_sec && - self.tm_min == (*other).tm_min && - self.tm_hour == (*other).tm_hour && - self.tm_mday == (*other).tm_mday && - self.tm_mon == (*other).tm_mon && - self.tm_year == (*other).tm_year && - self.tm_wday == (*other).tm_wday && - self.tm_yday == (*other).tm_yday && - self.tm_isdst == (*other).tm_isdst && - self.tm_gmtoff == (*other).tm_gmtoff && - self.tm_zone == (*other).tm_zone && - self.tm_nsec == (*other).tm_nsec - } - pure fn ne(&self, other: &Tm) -> bool { !self.eq(other) } -} - -pub pure fn empty_tm() -> Tm { +pub fn empty_tm() -> Tm { Tm { tm_sec: 0_i32, tm_min: 0_i32, @@ -198,14 +175,14 @@ pub fn now() -> Tm { } /// Parses the time from the string according to the format string. -pub pure fn strptime(s: &str, format: &str) -> Result { +pub fn strptime(s: &str, format: &str) -> Result { // unsafe only because do_strptime is annoying to make pure // (it does IO with a str_reader) unsafe {do_strptime(s, format)} } /// Formats the time according to the format string. -pub pure fn strftime(format: &str, tm: &Tm) -> ~str { +pub fn strftime(format: &str, tm: &Tm) -> ~str { // unsafe only because do_strftime is annoying to make pure // (it does IO with a str_reader) unsafe { do_strftime(format, tm) } @@ -239,10 +216,10 @@ pub impl Tm { * Return a string of the current time in the form * "Thu Jan 1 00:00:00 1970". */ - pure fn ctime(&self) -> ~str { self.strftime(~"%c") } + fn ctime(&self) -> ~str { self.strftime(~"%c") } /// Formats the time according to the format string. - pure fn strftime(&self, format: &str) -> ~str { + fn strftime(&self, format: &str) -> ~str { strftime(format, self) } @@ -252,7 +229,7 @@ pub impl Tm { * local: "Thu, 22 Mar 2012 07:53:18 PST" * utc: "Thu, 22 Mar 2012 14:53:18 UTC" */ - pure fn rfc822(&self) -> ~str { + fn rfc822(&self) -> ~str { if self.tm_gmtoff == 0_i32 { self.strftime(~"%a, %d %b %Y %T GMT") } else { @@ -266,7 +243,7 @@ pub impl Tm { * local: "Thu, 22 Mar 2012 07:53:18 -0700" * utc: "Thu, 22 Mar 2012 14:53:18 -0000" */ - pure fn rfc822z(&self) -> ~str { + fn rfc822z(&self) -> ~str { self.strftime(~"%a, %d %b %Y %T %z") } @@ -276,7 +253,7 @@ pub impl Tm { * local: "2012-02-22T07:53:18-07:00" * utc: "2012-02-22T14:53:18Z" */ - pure fn rfc3339(&self) -> ~str { + fn rfc3339(&self) -> ~str { if self.tm_gmtoff == 0_i32 { self.strftime(~"%Y-%m-%dT%H:%M:%SZ") } else { @@ -819,8 +796,8 @@ priv fn do_strftime(format: &str, tm: &Tm) -> ~str { 'M' => fmt!("%02d", tm.tm_min as int), 'm' => fmt!("%02d", tm.tm_mon as int + 1), 'n' => ~"\n", - 'P' => if tm.tm_hour as int < 12 { ~"am" } else { ~"pm" }, - 'p' => if tm.tm_hour as int < 12 { ~"AM" } else { ~"PM" }, + 'P' => if (tm.tm_hour as int) < 12 { ~"am" } else { ~"pm" }, + 'p' => if (tm.tm_hour as int) < 12 { ~"AM" } else { ~"PM" }, 'R' => { fmt!("%s:%s", parse_type('H', tm), @@ -900,8 +877,8 @@ mod tests { use core::vec; pub fn test_get_time() { - const some_recent_date: i64 = 1325376000i64; // 2012-01-01T00:00:00Z - const some_future_date: i64 = 1577836800i64; // 2020-01-01T00:00:00Z + static some_recent_date: i64 = 1325376000i64; // 2012-01-01T00:00:00Z + static some_future_date: i64 = 1577836800i64; // 2020-01-01T00:00:00Z let tv1 = get_time(); debug!("tv1=%? sec + %? nsec", tv1.sec as uint, tv1.nsec as uint); diff --git a/src/libstd/treemap.rs b/src/libstd/treemap.rs index f4d58568ae7d6..fccf58ddb6f74 100644 --- a/src/libstd/treemap.rs +++ b/src/libstd/treemap.rs @@ -36,40 +36,36 @@ pub struct TreeMap { } impl Eq for TreeMap { - pure fn eq(&self, other: &TreeMap) -> bool { + fn eq(&self, other: &TreeMap) -> bool { if self.len() != other.len() { false } else { let mut x = self.iter(); let mut y = other.iter(); for self.len().times { - unsafe { // unsafe as a purity workaround - if map_next(&mut x).unwrap() != - map_next(&mut y).unwrap() { - return false - } + if map_next(&mut x).unwrap() != + map_next(&mut y).unwrap() { + return false } } true } } - pure fn ne(&self, other: &TreeMap) -> bool { !self.eq(other) } + fn ne(&self, other: &TreeMap) -> bool { !self.eq(other) } } // Lexicographical comparison -pure fn lt(a: &TreeMap, +fn lt(a: &TreeMap, b: &TreeMap) -> bool { let mut x = a.iter(); let mut y = b.iter(); let (a_len, b_len) = (a.len(), b.len()); for uint::min(a_len, b_len).times { - unsafe { // purity workaround - let (key_a,_) = map_next(&mut x).unwrap(); - let (key_b,_) = map_next(&mut y).unwrap(); - if *key_a < *key_b { return true; } - if *key_a > *key_b { return false; } - } + let (key_a,_) = map_next(&mut x).unwrap(); + let (key_b,_) = map_next(&mut y).unwrap(); + if *key_a < *key_b { return true; } + if *key_a > *key_b { return false; } }; a_len < b_len @@ -77,21 +73,21 @@ pure fn lt(a: &TreeMap, impl Ord for TreeMap { #[inline(always)] - pure fn lt(&self, other: &TreeMap) -> bool { lt(self, other) } + fn lt(&self, other: &TreeMap) -> bool { lt(self, other) } #[inline(always)] - pure fn le(&self, other: &TreeMap) -> bool { !lt(other, self) } + fn le(&self, other: &TreeMap) -> bool { !lt(other, self) } #[inline(always)] - pure fn ge(&self, other: &TreeMap) -> bool { !lt(self, other) } + fn ge(&self, other: &TreeMap) -> bool { !lt(self, other) } #[inline(always)] - pure fn gt(&self, other: &TreeMap) -> bool { lt(other, self) } + fn gt(&self, other: &TreeMap) -> bool { lt(other, self) } } impl<'self, K: TotalOrd, V> BaseIter<(&'self K, &'self V)> for TreeMap { /// Visit all key-value pairs in order - pure fn each(&self, f: &fn(&(&'self K, &'self V)) -> bool) { + fn each(&self, f: &fn(&(&'self K, &'self V)) -> bool) { each(&self.root, f) } - pure fn size_hint(&self) -> Option { Some(self.len()) } + fn size_hint(&self) -> Option { Some(self.len()) } } impl<'self, K: TotalOrd, V> @@ -99,17 +95,17 @@ impl<'self, K: TotalOrd, V> for TreeMap { /// Visit all key-value pairs in reverse order - pure fn each_reverse(&self, f: &fn(&(&'self K, &'self V)) -> bool) { + fn each_reverse(&self, f: &fn(&(&'self K, &'self V)) -> bool) { each_reverse(&self.root, f); } } impl Container for TreeMap { /// Return the number of elements in the map - pure fn len(&const self) -> uint { self.length } + fn len(&const self) -> uint { self.length } /// Return true if the map contains no elements - pure fn is_empty(&const self) -> bool { self.root.is_none() } + fn is_empty(&const self) -> bool { self.root.is_none() } } impl Mutable for TreeMap { @@ -122,15 +118,15 @@ impl Mutable for TreeMap { impl Map for TreeMap { /// Return true if the map contains a value for the specified key - pure fn contains_key(&self, key: &K) -> bool { + fn contains_key(&self, key: &K) -> bool { self.find(key).is_some() } /// Visit all keys in order - pure fn each_key(&self, f: &fn(&K) -> bool) { self.each(|&(k, _)| f(k)) } + fn each_key(&self, f: &fn(&K) -> bool) { self.each(|&(k, _)| f(k)) } /// Visit all values in order - pure fn each_value(&self, f: &fn(&V) -> bool) { + fn each_value(&self, f: &fn(&V) -> bool) { self.each(|&(_, v)| f(v)) } @@ -139,8 +135,8 @@ impl Map for TreeMap { mutate_values(&mut self.root, f); } - /// Return the value corresponding to the key in the map - pure fn find(&self, key: &K) -> Option<&'self V> { + /// Return a reference to the value corresponding to the key + fn find(&self, key: &K) -> Option<&'self V> { let mut current: &'self Option<~TreeNode> = &self.root; loop { match *current { @@ -156,6 +152,12 @@ impl Map for TreeMap { } } + /// Return a mutable reference to the value corresponding to the key + #[inline(always)] + fn find_mut(&mut self, key: &K) -> Option<&'self mut V> { + find_mut(&mut self.root, key) + } + /// Insert a key-value pair into the map. An existing value for a /// key is replaced by the new value. Return true if the key did /// not already exist in the map. @@ -176,21 +178,21 @@ impl Map for TreeMap { pub impl TreeMap { /// Create an empty TreeMap - static pure fn new() -> TreeMap { TreeMap{root: None, length: 0} } + fn new() -> TreeMap { TreeMap{root: None, length: 0} } /// Visit all keys in reverse order - pure fn each_key_reverse(&self, f: &fn(&K) -> bool) { + fn each_key_reverse(&self, f: &fn(&K) -> bool) { self.each_reverse(|&(k, _)| f(k)) } /// Visit all values in reverse order - pure fn each_value_reverse(&self, f: &fn(&V) -> bool) { + fn each_value_reverse(&self, f: &fn(&V) -> bool) { self.each_reverse(|&(_, v)| f(v)) } /// Get a lazy iterator over the key-value pairs in the map. /// Requires that it be frozen (immutable). - pure fn iter(&self) -> TreeMapIterator/&self { + fn iter(&self) -> TreeMapIterator<'self, K, V> { TreeMapIterator{stack: ~[], node: &self.root} } } @@ -204,8 +206,8 @@ pub struct TreeMapIterator { /// Advance the iterator to the next node (in order) and return a /// tuple with a reference to the key and value. If there are no /// more nodes, return `None`. -pub fn map_next(iter: &mut TreeMapIterator/&r) - -> Option<(&'r K, &'r V)> { +pub fn map_next<'r, K, V>(iter: &mut TreeMapIterator<'r, K, V>) + -> Option<(&'r K, &'r V)> { while !iter.stack.is_empty() || iter.node.is_some() { match *iter.node { Some(ref x) => { @@ -223,8 +225,8 @@ pub fn map_next(iter: &mut TreeMapIterator/&r) } /// Advance the iterator through the map -pub fn map_advance(iter: &mut TreeMapIterator/&r, - f: &fn((&'r K, &'r V)) -> bool) { +pub fn map_advance<'r, K, V>(iter: &mut TreeMapIterator<'r, K, V>, + f: &fn((&'r K, &'r V)) -> bool) { loop { match map_next(iter) { Some(x) => { @@ -242,45 +244,45 @@ pub struct TreeSet { impl BaseIter for TreeSet { /// Visit all values in order #[inline(always)] - pure fn each(&self, f: &fn(&T) -> bool) { self.map.each_key(f) } + fn each(&self, f: &fn(&T) -> bool) { self.map.each_key(f) } #[inline(always)] - pure fn size_hint(&self) -> Option { Some(self.len()) } + fn size_hint(&self) -> Option { Some(self.len()) } } impl ReverseIter for TreeSet { /// Visit all values in reverse order #[inline(always)] - pure fn each_reverse(&self, f: &fn(&T) -> bool) { + fn each_reverse(&self, f: &fn(&T) -> bool) { self.map.each_key_reverse(f) } } impl Eq for TreeSet { #[inline(always)] - pure fn eq(&self, other: &TreeSet) -> bool { self.map == other.map } + fn eq(&self, other: &TreeSet) -> bool { self.map == other.map } #[inline(always)] - pure fn ne(&self, other: &TreeSet) -> bool { self.map != other.map } + fn ne(&self, other: &TreeSet) -> bool { self.map != other.map } } impl Ord for TreeSet { #[inline(always)] - pure fn lt(&self, other: &TreeSet) -> bool { self.map < other.map } + fn lt(&self, other: &TreeSet) -> bool { self.map < other.map } #[inline(always)] - pure fn le(&self, other: &TreeSet) -> bool { self.map <= other.map } + fn le(&self, other: &TreeSet) -> bool { self.map <= other.map } #[inline(always)] - pure fn ge(&self, other: &TreeSet) -> bool { self.map >= other.map } + fn ge(&self, other: &TreeSet) -> bool { self.map >= other.map } #[inline(always)] - pure fn gt(&self, other: &TreeSet) -> bool { self.map > other.map } + fn gt(&self, other: &TreeSet) -> bool { self.map > other.map } } impl Container for TreeSet { /// Return the number of elements in the set #[inline(always)] - pure fn len(&const self) -> uint { self.map.len() } + fn len(&const self) -> uint { self.map.len() } /// Return true if the set contains no elements #[inline(always)] - pure fn is_empty(&const self) -> bool { self.map.is_empty() } + fn is_empty(&const self) -> bool { self.map.is_empty() } } impl Mutable for TreeSet { @@ -292,7 +294,7 @@ impl Mutable for TreeSet { impl Set for TreeSet { /// Return true if the set contains a value #[inline(always)] - pure fn contains(&self, value: &T) -> bool { + fn contains(&self, value: &T) -> bool { self.map.contains_key(value) } @@ -308,20 +310,18 @@ impl Set for TreeSet { /// Return true if the set has no elements in common with `other`. /// This is equivalent to checking for an empty intersection. - pure fn is_disjoint(&self, other: &TreeSet) -> bool { + fn is_disjoint(&self, other: &TreeSet) -> bool { let mut x = self.iter(); let mut y = other.iter(); - unsafe { // purity workaround - let mut a = set_next(&mut x); - let mut b = set_next(&mut y); - while a.is_some() && b.is_some() { - let a1 = a.unwrap(); - let b1 = b.unwrap(); - match a1.cmp(b1) { - Less => a = set_next(&mut x), - Greater => b = set_next(&mut y), - Equal => return false - } + let mut a = set_next(&mut x); + let mut b = set_next(&mut y); + while a.is_some() && b.is_some() { + let a1 = a.unwrap(); + let b1 = b.unwrap(); + match a1.cmp(b1) { + Less => a = set_next(&mut x), + Greater => b = set_next(&mut y), + Equal => return false } } true @@ -329,204 +329,194 @@ impl Set for TreeSet { /// Return true if the set is a subset of another #[inline(always)] - pure fn is_subset(&self, other: &TreeSet) -> bool { + fn is_subset(&self, other: &TreeSet) -> bool { other.is_superset(self) } /// Return true if the set is a superset of another - pure fn is_superset(&self, other: &TreeSet) -> bool { + fn is_superset(&self, other: &TreeSet) -> bool { let mut x = self.iter(); let mut y = other.iter(); - unsafe { // purity workaround - let mut a = set_next(&mut x); - let mut b = set_next(&mut y); - while b.is_some() { - if a.is_none() { - return false - } - - let a1 = a.unwrap(); - let b1 = b.unwrap(); + let mut a = set_next(&mut x); + let mut b = set_next(&mut y); + while b.is_some() { + if a.is_none() { + return false + } - match a1.cmp(b1) { - Less => (), - Greater => return false, - Equal => b = set_next(&mut y), - } + let a1 = a.unwrap(); + let b1 = b.unwrap(); - a = set_next(&mut x); + match a1.cmp(b1) { + Less => (), + Greater => return false, + Equal => b = set_next(&mut y), } + + a = set_next(&mut x); } true } /// Visit the values (in-order) representing the difference - pure fn difference(&self, other: &TreeSet, f: &fn(&T) -> bool) { + fn difference(&self, other: &TreeSet, f: &fn(&T) -> bool) { let mut x = self.iter(); let mut y = other.iter(); - unsafe { // purity workaround - let mut a = set_next(&mut x); - let mut b = set_next(&mut y); + let mut a = set_next(&mut x); + let mut b = set_next(&mut y); - while a.is_some() { - if b.is_none() { - return do a.while_some() |a1| { - if f(a1) { set_next(&mut x) } else { None } - } + while a.is_some() { + if b.is_none() { + return do a.while_some() |a1| { + if f(a1) { set_next(&mut x) } else { None } } + } - let a1 = a.unwrap(); - let b1 = b.unwrap(); + let a1 = a.unwrap(); + let b1 = b.unwrap(); - let cmp = a1.cmp(b1); + let cmp = a1.cmp(b1); - if cmp == Less { - if !f(a1) { return } - a = set_next(&mut x); - } else { - if cmp == Equal { a = set_next(&mut x) } - b = set_next(&mut y); - } + if cmp == Less { + if !f(a1) { return } + a = set_next(&mut x); + } else { + if cmp == Equal { a = set_next(&mut x) } + b = set_next(&mut y); } } } /// Visit the values (in-order) representing the symmetric difference - pure fn symmetric_difference(&self, other: &TreeSet, + fn symmetric_difference(&self, other: &TreeSet, f: &fn(&T) -> bool) { let mut x = self.iter(); let mut y = other.iter(); - unsafe { // purity workaround - let mut a = set_next(&mut x); - let mut b = set_next(&mut y); + let mut a = set_next(&mut x); + let mut b = set_next(&mut y); - while a.is_some() { - if b.is_none() { - return do a.while_some() |a1| { - if f(a1) { set_next(&mut x) } else { None } - } + while a.is_some() { + if b.is_none() { + return do a.while_some() |a1| { + if f(a1) { set_next(&mut x) } else { None } } + } - let a1 = a.unwrap(); - let b1 = b.unwrap(); + let a1 = a.unwrap(); + let b1 = b.unwrap(); - let cmp = a1.cmp(b1); + let cmp = a1.cmp(b1); - if cmp == Less { - if !f(a1) { return } - a = set_next(&mut x); + if cmp == Less { + if !f(a1) { return } + a = set_next(&mut x); + } else { + if cmp == Greater { + if !f(b1) { return } } else { - if cmp == Greater { - if !f(b1) { return } - } else { - a = set_next(&mut x); - } - b = set_next(&mut y); + a = set_next(&mut x); } + b = set_next(&mut y); } - do b.while_some |b1| { - if f(b1) { set_next(&mut y) } else { None } - } + } + do b.while_some |b1| { + if f(b1) { set_next(&mut y) } else { None } } } /// Visit the values (in-order) representing the intersection - pure fn intersection(&self, other: &TreeSet, f: &fn(&T) -> bool) { + fn intersection(&self, other: &TreeSet, f: &fn(&T) -> bool) { let mut x = self.iter(); let mut y = other.iter(); - unsafe { // purity workaround - let mut a = set_next(&mut x); - let mut b = set_next(&mut y); + let mut a = set_next(&mut x); + let mut b = set_next(&mut y); - while a.is_some() && b.is_some() { - let a1 = a.unwrap(); - let b1 = b.unwrap(); + while a.is_some() && b.is_some() { + let a1 = a.unwrap(); + let b1 = b.unwrap(); - let cmp = a1.cmp(b1); + let cmp = a1.cmp(b1); - if cmp == Less { - a = set_next(&mut x); - } else { - if cmp == Equal { - if !f(a1) { return } - } - b = set_next(&mut y); + if cmp == Less { + a = set_next(&mut x); + } else { + if cmp == Equal { + if !f(a1) { return } } + b = set_next(&mut y); } } } /// Visit the values (in-order) representing the union - pure fn union(&self, other: &TreeSet, f: &fn(&T) -> bool) { + fn union(&self, other: &TreeSet, f: &fn(&T) -> bool) { let mut x = self.iter(); let mut y = other.iter(); - unsafe { // purity workaround - let mut a = set_next(&mut x); - let mut b = set_next(&mut y); + let mut a = set_next(&mut x); + let mut b = set_next(&mut y); - while a.is_some() { - if b.is_none() { - return do a.while_some() |a1| { - if f(a1) { set_next(&mut x) } else { None } - } + while a.is_some() { + if b.is_none() { + return do a.while_some() |a1| { + if f(a1) { set_next(&mut x) } else { None } } + } - let a1 = a.unwrap(); - let b1 = b.unwrap(); + let a1 = a.unwrap(); + let b1 = b.unwrap(); - let cmp = a1.cmp(b1); + let cmp = a1.cmp(b1); - if cmp == Greater { - if !f(b1) { return } + if cmp == Greater { + if !f(b1) { return } + b = set_next(&mut y); + } else { + if !f(a1) { return } + if cmp == Equal { b = set_next(&mut y); - } else { - if !f(a1) { return } - if cmp == Equal { - b = set_next(&mut y); - } - a = set_next(&mut x); } - } - do b.while_some |b1| { - if f(b1) { set_next(&mut y) } else { None } + a = set_next(&mut x); } } + do b.while_some |b1| { + if f(b1) { set_next(&mut y) } else { None } + } } } pub impl TreeSet { /// Create an empty TreeSet #[inline(always)] - static pure fn new() -> TreeSet { TreeSet{map: TreeMap::new()} } + fn new() -> TreeSet { TreeSet{map: TreeMap::new()} } /// Get a lazy iterator over the values in the set. /// Requires that it be frozen (immutable). #[inline(always)] - pure fn iter(&self) -> TreeSetIterator/&self { + fn iter(&self) -> TreeSetIterator<'self, T> { TreeSetIterator{iter: self.map.iter()} } } /// Lazy forward iterator over a set -pub struct TreeSetIterator { - priv iter: TreeMapIterator/&self +pub struct TreeSetIterator<'self, T> { + priv iter: TreeMapIterator<'self, T, ()> } /// Advance the iterator to the next node (in order). If this iterator is /// finished, does nothing. #[inline(always)] -pub fn set_next(iter: &mut TreeSetIterator/&r) -> Option<&'r T> { +pub fn set_next<'r, T>(iter: &mut TreeSetIterator<'r, T>) -> Option<&'r T> { do map_next(&mut iter.iter).map |&(value, _)| { value } } /// Advance the iterator through the set #[inline(always)] -pub fn set_advance(iter: &mut TreeSetIterator/&r, - f: &fn(&'r T) -> bool) { +pub fn set_advance<'r, T>(iter: &mut TreeSetIterator<'r, T>, + f: &fn(&'r T) -> bool) { do map_advance(&mut iter.iter) |(k, _)| { f(k) } } @@ -542,12 +532,12 @@ struct TreeNode { pub impl TreeNode { #[inline(always)] - static pure fn new(key: K, value: V) -> TreeNode { + fn new(key: K, value: V) -> TreeNode { TreeNode{key: key, value: value, left: None, right: None, level: 1} } } -pure fn each(node: &'r Option<~TreeNode>, +fn each(node: &'r Option<~TreeNode>, f: &fn(&(&'r K, &'r V)) -> bool) { for node.each |x| { each(&x.left, f); @@ -555,7 +545,7 @@ pure fn each(node: &'r Option<~TreeNode>, } } -pure fn each_reverse(node: &'r Option<~TreeNode>, +fn each_reverse(node: &'r Option<~TreeNode>, f: &fn(&(&'r K, &'r V)) -> bool) { for node.each |x| { each_reverse(&x.right, f); @@ -600,8 +590,20 @@ fn split(node: &mut ~TreeNode) { } } -fn insert(node: &mut Option<~TreeNode>, key: K, - value: V) -> bool { +fn find_mut(node: &'r mut Option<~TreeNode>, key: &K) -> Option<&'r mut V> { + match *node { + Some(ref mut x) => { + match key.cmp(&x.key) { + Less => find_mut(&mut x.left, key), + Greater => find_mut(&mut x.right, key), + Equal => Some(&mut x.value), + } + } + None => None + } +} + +fn insert(node: &mut Option<~TreeNode>, key: K, value: V) -> bool { match *node { Some(ref mut save) => { match key.cmp(&save.key) { @@ -732,6 +734,19 @@ mod test_treemap { fail_unless!(m.find(&2) == None); } + #[test] + fn test_find_mut() { + let mut m = TreeMap::new(); + fail_unless!(m.insert(1, 12)); + fail_unless!(m.insert(2, 8)); + fail_unless!(m.insert(5, 14)); + let new = 100; + match m.find_mut(&5) { + None => fail!(), Some(x) => *x = new + } + assert_eq!(m.find(&5), Some(&new)); + } + #[test] fn insert_replace() { let mut m = TreeMap::new(); diff --git a/src/libstd/unicode.rs b/src/libstd/unicode.rs index b3581e2690c8a..4fdd4e286da1a 100644 --- a/src/libstd/unicode.rs +++ b/src/libstd/unicode.rs @@ -15,147 +15,147 @@ pub mod icu { pub type UProperty = int; pub type UChar32 = char; - pub const TRUE : u8 = 1u8; - pub const FALSE : u8 = 1u8; - - 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; - - 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; - - 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; - - 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; - - 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; - - 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; - - 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; - - 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; - - 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; - - 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; - - 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; - - 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; - - 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; - - 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; - - 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; - - 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; - - 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; - - 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; - - 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; - - 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; - - pub const UCHAR_WORD_BREAK : UProperty = 0x1014; - pub const UCHAR_INT_LIMIT : UProperty = 0x1015; - - pub const UCHAR_GENERAL_CATEGORY_MASK : UProperty = 0x2000; - pub const UCHAR_MASK_START : UProperty = 0x2000; + pub static TRUE : u8 = 1u8; + pub static FALSE : u8 = 1u8; + + pub static UCHAR_ALPHABETIC : UProperty = 0; + pub static UCHAR_BINARY_START : UProperty = 0; // = UCHAR_ALPHABETIC + pub static UCHAR_ASCII_HEX_DIGIT : UProperty = 1; + pub static UCHAR_BIDI_CONTROL : UProperty = 2; + + pub static UCHAR_BIDI_MIRRORED : UProperty = 3; + pub static UCHAR_DASH : UProperty = 4; + pub static UCHAR_DEFAULT_IGNORABLE_CODE_POINT : UProperty = 5; + pub static UCHAR_DEPRECATED : UProperty = 6; + + pub static UCHAR_DIACRITIC : UProperty = 7; + pub static UCHAR_EXTENDER : UProperty = 8; + pub static UCHAR_FULL_COMPOSITION_EXCLUSION : UProperty = 9; + pub static UCHAR_GRAPHEME_BASE : UProperty = 10; + + pub static UCHAR_GRAPHEME_EXTEND : UProperty = 11; + pub static UCHAR_GRAPHEME_LINK : UProperty = 12; + pub static UCHAR_HEX_DIGIT : UProperty = 13; + pub static UCHAR_HYPHEN : UProperty = 14; + + pub static UCHAR_ID_CONTINUE : UProperty = 15; + pub static UCHAR_ID_START : UProperty = 16; + pub static UCHAR_IDEOGRAPHIC : UProperty = 17; + pub static UCHAR_IDS_BINARY_OPERATOR : UProperty = 18; + + pub static UCHAR_IDS_TRINARY_OPERATOR : UProperty = 19; + pub static UCHAR_JOIN_CONTROL : UProperty = 20; + pub static UCHAR_LOGICAL_ORDER_EXCEPTION : UProperty = 21; + pub static UCHAR_LOWERCASE : UProperty = 22; + + pub static UCHAR_MATH : UProperty = 23; + pub static UCHAR_NONCHARACTER_CODE_POINT : UProperty = 24; + pub static UCHAR_QUOTATION_MARK : UProperty = 25; + pub static UCHAR_RADICAL : UProperty = 26; + + pub static UCHAR_SOFT_DOTTED : UProperty = 27; + pub static UCHAR_TERMINAL_PUNCTUATION : UProperty = 28; + pub static UCHAR_UNIFIED_IDEOGRAPH : UProperty = 29; + pub static UCHAR_UPPERCASE : UProperty = 30; + + pub static UCHAR_WHITE_SPACE : UProperty = 31; + pub static UCHAR_XID_CONTINUE : UProperty = 32; + pub static UCHAR_XID_START : UProperty = 33; + pub static UCHAR_CASE_SENSITIVE : UProperty = 34; + + pub static UCHAR_S_TERM : UProperty = 35; + pub static UCHAR_VARIATION_SELECTOR : UProperty = 36; + pub static UCHAR_NFD_INERT : UProperty = 37; + pub static UCHAR_NFKD_INERT : UProperty = 38; + + pub static UCHAR_NFC_INERT : UProperty = 39; + pub static UCHAR_NFKC_INERT : UProperty = 40; + pub static UCHAR_SEGMENT_STARTER : UProperty = 41; + pub static UCHAR_PATTERN_SYNTAX : UProperty = 42; + + pub static UCHAR_PATTERN_WHITE_SPACE : UProperty = 43; + pub static UCHAR_POSIX_ALNUM : UProperty = 44; + pub static UCHAR_POSIX_BLANK : UProperty = 45; + pub static UCHAR_POSIX_GRAPH : UProperty = 46; + + pub static UCHAR_POSIX_PRINT : UProperty = 47; + pub static UCHAR_POSIX_XDIGIT : UProperty = 48; + pub static UCHAR_CASED : UProperty = 49; + pub static UCHAR_CASE_IGNORABLE : UProperty = 50; + + pub static UCHAR_CHANGES_WHEN_LOWERCASED : UProperty = 51; + pub static UCHAR_CHANGES_WHEN_UPPERCASED : UProperty = 52; + pub static UCHAR_CHANGES_WHEN_TITLECASED : UProperty = 53; + pub static UCHAR_CHANGES_WHEN_CASEFOLDED : UProperty = 54; + + pub static UCHAR_CHANGES_WHEN_CASEMAPPED : UProperty = 55; + pub static UCHAR_CHANGES_WHEN_NFKC_CASEFOLDED : UProperty = 56; + pub static UCHAR_BINARY_LIMIT : UProperty = 57; + pub static UCHAR_BIDI_CLASS : UProperty = 0x1000; + + pub static UCHAR_INT_START : UProperty = 0x1000; // UCHAR_BIDI_CLASS + pub static UCHAR_BLOCK : UProperty = 0x1001; + pub static UCHAR_CANONICAL_COMBINING_CLASS : UProperty = 0x1002; + pub static UCHAR_DECOMPOSITION_TYPE : UProperty = 0x1003; + + pub static UCHAR_EAST_ASIAN_WIDTH : UProperty = 0x1004; + pub static UCHAR_GENERAL_CATEGORY : UProperty = 0x1005; + pub static UCHAR_JOINING_GROUP : UProperty = 0x1006; + pub static UCHAR_JOINING_TYPE : UProperty = 0x1007; + + pub static UCHAR_LINE_BREAK : UProperty = 0x1008; + pub static UCHAR_NUMERIC_TYPE : UProperty = 0x1009; + pub static UCHAR_SCRIPT : UProperty = 0x100A; + pub static UCHAR_HANGUL_SYLLABLE_TYPE : UProperty = 0x100B; + + pub static UCHAR_NFD_QUICK_CHECK : UProperty = 0x100C; + pub static UCHAR_NFKD_QUICK_CHECK : UProperty = 0x100D; + pub static UCHAR_NFC_QUICK_CHECK : UProperty = 0x100E; + pub static UCHAR_NFKC_QUICK_CHECK : UProperty = 0x100F; + + pub static UCHAR_LEAD_CANONICAL_COMBINING_CLASS : UProperty = 0x1010; + pub static UCHAR_TRAIL_CANONICAL_COMBINING_CLASS : UProperty = 0x1011; + pub static UCHAR_GRAPHEME_CLUSTER_BREAK : UProperty = 0x1012; + pub static UCHAR_SENTENCE_BREAK : UProperty = 0x1013; + + pub static UCHAR_WORD_BREAK : UProperty = 0x1014; + pub static UCHAR_INT_LIMIT : UProperty = 0x1015; + + pub static UCHAR_GENERAL_CATEGORY_MASK : UProperty = 0x2000; + pub static UCHAR_MASK_START : UProperty = 0x2000; // = UCHAR_GENERAL_CATEGORY_MASK - pub const UCHAR_MASK_LIMIT : UProperty = 0x2001; + pub static UCHAR_MASK_LIMIT : UProperty = 0x2001; - pub const UCHAR_NUMERIC_VALUE : UProperty = 0x3000; - pub const UCHAR_DOUBLE_START : UProperty = 0x3000; + pub static UCHAR_NUMERIC_VALUE : UProperty = 0x3000; + pub static UCHAR_DOUBLE_START : UProperty = 0x3000; // = UCHAR_NUMERIC_VALUE - pub const UCHAR_DOUBLE_LIMIT : UProperty = 0x3001; + pub static UCHAR_DOUBLE_LIMIT : UProperty = 0x3001; - 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; + pub static UCHAR_AGE : UProperty = 0x4000; + pub static UCHAR_STRING_START : UProperty = 0x4000; // = UCHAR_AGE + pub static UCHAR_BIDI_MIRRORING_GLYPH : UProperty = 0x4001; + pub static UCHAR_CASE_FOLDING : UProperty = 0x4002; - 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; + pub static UCHAR_ISO_COMMENT : UProperty = 0x4003; + pub static UCHAR_LOWERCASE_MAPPING : UProperty = 0x4004; + pub static UCHAR_NAME : UProperty = 0x4005; + pub static UCHAR_SIMPLE_CASE_FOLDING : UProperty = 0x4006; - 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; + pub static UCHAR_SIMPLE_LOWERCASE_MAPPING : UProperty = 0x4007; + pub static UCHAR_SIMPLE_TITLECASE_MAPPING : UProperty = 0x4008; + pub static UCHAR_SIMPLE_UPPERCASE_MAPPING : UProperty = 0x4009; + pub static UCHAR_TITLECASE_MAPPING : UProperty = 0x400A; - pub const UCHAR_UNICODE_1_NAME : UProperty = 0x400B; - pub const UCHAR_UPPERCASE_MAPPING : UProperty = 0x400C; - pub const UCHAR_STRING_LIMIT : UProperty = 0x400D; + pub static UCHAR_UNICODE_1_NAME : UProperty = 0x400B; + pub static UCHAR_UPPERCASE_MAPPING : UProperty = 0x400C; + pub static UCHAR_STRING_LIMIT : UProperty = 0x400D; - pub const UCHAR_SCRIPT_EXTENSIONS : UProperty = 0x7000; - pub const UCHAR_OTHER_PROPERTY_START : UProperty = 0x7000; + pub static UCHAR_SCRIPT_EXTENSIONS : UProperty = 0x7000; + pub static UCHAR_OTHER_PROPERTY_START : UProperty = 0x7000; // = UCHAR_SCRIPT_EXTENSIONS; - pub const UCHAR_OTHER_PROPERTY_LIMIT : UProperty = 0x7001; + pub static UCHAR_OTHER_PROPERTY_LIMIT : UProperty = 0x7001; - pub const UCHAR_INVALID_CODE : UProperty = -1; + pub static UCHAR_INVALID_CODE : UProperty = -1; pub mod libicu { #[link_name = "icuuc"] @@ -173,12 +173,12 @@ pub mod icu { } } -pub pure fn is_XID_start(c: char) -> bool { +pub fn is_XID_start(c: char) -> bool { return icu::libicu::u_hasBinaryProperty(c, icu::UCHAR_XID_START) == icu::TRUE; } -pub pure fn is_XID_continue(c: char) -> bool { +pub fn is_XID_continue(c: char) -> bool { return icu::libicu::u_hasBinaryProperty(c, icu::UCHAR_XID_START) == icu::TRUE; } @@ -188,7 +188,7 @@ Function: is_digit Returns true if a character is a digit. */ -pub pure fn is_digit(c: char) -> bool { +pub fn is_digit(c: char) -> bool { return icu::libicu::u_isdigit(c) == icu::TRUE; } @@ -197,7 +197,7 @@ Function: is_lower Returns true if a character is a lowercase letter. */ -pub pure fn is_lower(c: char) -> bool { +pub fn is_lower(c: char) -> bool { return icu::libicu::u_islower(c) == icu::TRUE; } @@ -206,7 +206,7 @@ Function: is_space Returns true if a character is space. */ -pub pure fn is_space(c: char) -> bool { +pub fn is_space(c: char) -> bool { return icu::libicu::u_isspace(c) == icu::TRUE; } @@ -215,7 +215,7 @@ Function: is_upper Returns true if a character is an uppercase letter. */ -pub pure fn is_upper(c: char) -> bool { +pub fn is_upper(c: char) -> bool { return icu::libicu::u_isupper(c) == icu::TRUE; } diff --git a/src/libstd/uv.rs b/src/libstd/uv.rs index aaddc9b6836f3..e055b40705773 100644 --- a/src/libstd/uv.rs +++ b/src/libstd/uv.rs @@ -33,6 +33,6 @@ * facilities. */ -pub use ll = core::unstable::uvll; +pub use ll = super::uv_ll; pub use iotask = uv_iotask; pub use global_loop = uv_global_loop; diff --git a/src/libcore/unstable/uvll.rs b/src/libstd/uv_ll.rs similarity index 96% rename from src/libcore/unstable/uvll.rs rename to src/libstd/uv_ll.rs index 80f04cf4ac0c1..57d769d707e67 100644 --- a/src/libcore/unstable/uvll.rs +++ b/src/libstd/uv_ll.rs @@ -32,10 +32,10 @@ #[allow(non_camel_case_types)]; // C types -use libc::size_t; -use libc::c_void; -use prelude::*; -use ptr::to_unsafe_ptr; +use core::libc::size_t; +use core::libc::c_void; +use core::prelude::*; +use core::ptr::to_unsafe_ptr; pub type uv_handle_t = c_void; pub type uv_loop_t = c_void; @@ -357,7 +357,7 @@ pub struct uv_getaddrinfo_t { pub mod uv_ll_struct_stubgen { - use ptr; + use core::ptr; use super::{ uv_async_t, @@ -930,8 +930,6 @@ pub unsafe fn tcp_connect(connect_ptr: *uv_connect_t, addr_ptr: *sockaddr_in, after_connect_cb: *u8) -> libc::c_int { - debug!("b4 foreign tcp_connect--addr port: %u cb: %u", - (*addr_ptr).sin_port as uint, after_connect_cb as uint); return rustrt::rust_uv_tcp_connect(connect_ptr, tcp_handle_ptr, after_connect_cb, addr_ptr); } @@ -1021,22 +1019,8 @@ pub unsafe fn async_send(async_handle: *uv_async_t) { pub unsafe fn buf_init(input: *u8, len: uint) -> uv_buf_t { let out_buf = uv_buf_t { base: ptr::null(), len: 0 as libc::size_t }; let out_buf_ptr = ptr::addr_of(&out_buf); - debug!("buf_init - input %u len %u out_buf: %u", - input as uint, - len as uint, - out_buf_ptr as uint); - // yuck :/ rustrt::rust_uv_buf_init(out_buf_ptr, input, len as size_t); - //let result = rustrt::rust_uv_buf_init_2(input, len as size_t); - debug!("after rust_uv_buf_init"); - let res_base = get_base_from_buf(out_buf); - let res_len = get_len_from_buf(out_buf); - //let res_base = get_base_from_buf(result); - debug!("buf_init - result %u len %u", - res_base as uint, - res_len as uint); return out_buf; - //return result; } pub unsafe fn ip4_addr(ip: &str, port: int) -> sockaddr_in { @@ -1078,8 +1062,6 @@ pub unsafe fn ip6_name(src: &sockaddr_in6) -> ~str { 0u8,0u8,0u8,0u8,0u8,0u8]; do vec::as_imm_buf(dst) |dst_buf, size| { let src_unsafe_ptr = to_unsafe_ptr(src); - debug!("val of src *sockaddr_in6: %? sockaddr_in6: %?", - src_unsafe_ptr, src); let result = rustrt::rust_uv_ip6_name(src_unsafe_ptr, dst_buf, size as libc::size_t); match result { @@ -1240,9 +1222,9 @@ pub unsafe fn addrinfo_as_sockaddr_in6(input: *addrinfo) -> *sockaddr_in6 { #[cfg(test)] pub mod test { - use prelude::*; + use core::prelude::*; + use core::comm::{SharedChan, stream, GenericChan, GenericPort}; use super::*; - use comm::{SharedChan, stream, GenericChan, GenericPort}; enum tcp_read_data { tcp_read_eof, @@ -1265,7 +1247,7 @@ pub mod test { suggested_size: libc::size_t) -> uv_buf_t { unsafe { - debug!("on_alloc_cb!"); + debug!(~"on_alloc_cb!"); let char_ptr = malloc_buf_base_of(suggested_size); debug!("on_alloc_cb h: %? char_ptr: %u sugsize: %u", handle, @@ -1298,15 +1280,15 @@ pub mod test { } else if (nread == -1) { // err .. possibly EOF - debug!("read: eof!"); + debug!(~"read: eof!"); } else { // nread == 0 .. do nothing, just free buf as below - debug!("read: do nothing!"); + debug!(~"read: do nothing!"); } // when we're done free_base_of_buf(buf); - debug!("CLIENT exiting on_read_cb"); + debug!(~"CLIENT exiting on_read_cb"); } } @@ -1321,8 +1303,7 @@ pub mod test { "CLIENT on_write_complete_cb: tcp:%d write_handle:%d", stream as int, write_req as int); let result = read_start(stream, on_alloc_cb, on_read_cb); - debug!( - "CLIENT ending on_write_complete_cb .. status: %d", + debug!("CLIENT ending on_write_complete_cb .. status: %d", result as int); } } @@ -1335,7 +1316,7 @@ pub mod test { let stream = get_stream_handle_from_connect_req(connect_req_ptr); if (status == 0i32) { - debug!("on_connect_cb: in status=0 if.."); + debug!(~"on_connect_cb: in status=0 if.."); let client_data = get_data_for_req( connect_req_ptr as *libc::c_void) as *request_wrapper; @@ -1353,10 +1334,10 @@ pub mod test { let test_loop = get_loop_for_uv_handle( stream as *libc::c_void); let err_msg = get_last_err_info(test_loop); - debug!("%?", err_msg); + debug!(err_msg); fail_unless!(false); } - debug!("finishing on_connect_cb"); + debug!(~"finishing on_connect_cb"); } } @@ -1396,9 +1377,9 @@ pub mod test { let tcp_init_result = tcp_init( test_loop as *libc::c_void, tcp_handle_ptr); if (tcp_init_result == 0i32) { - debug!("sucessful tcp_init_result"); + debug!(~"sucessful tcp_init_result"); - debug!("building addr..."); + debug!(~"building addr..."); let addr = ip4_addr(ip, port); // FIXME ref #2064 let addr_ptr = ptr::addr_of(&addr); @@ -1420,17 +1401,17 @@ pub mod test { set_data_for_uv_handle( tcp_handle_ptr as *libc::c_void, ptr::addr_of(&client_data) as *libc::c_void); - debug!("before run tcp req loop"); + debug!(~"before run tcp req loop"); run(test_loop); - debug!("after run tcp req loop"); + debug!(~"after run tcp req loop"); } else { - debug!("tcp_connect() failure"); + debug!(~"tcp_connect() failure"); fail_unless!(false); } } else { - debug!("tcp_init() failure"); + debug!(~"tcp_init() failure"); fail_unless!(false); } loop_delete(test_loop); @@ -1446,8 +1427,7 @@ pub mod test { extern fn client_stream_after_close_cb(handle: *libc::c_void) { unsafe { - debug!( - "SERVER: closed client stream, now closing server stream"); + debug!(~"SERVER: closed client stream, now closing server stream"); let client_data = get_data_for_uv_handle( handle) as *tcp_server_data; @@ -1460,7 +1440,7 @@ pub mod test { unsafe { let client_stream_ptr = get_stream_handle_from_write_req(req); - debug!("SERVER: resp sent... closing client stream"); + debug!(~"SERVER: resp sent... closing client stream"); close(client_stream_ptr as *libc::c_void, client_stream_after_close_cb) } @@ -1491,8 +1471,8 @@ pub mod test { let server_kill_msg = copy (*client_data).server_kill_msg; let write_req = (*client_data).server_write_req; if str::contains(request_str, server_kill_msg) { - debug!("SERVER: client req contains kill_msg!"); - debug!("SERVER: sending response to client"); + debug!(~"SERVER: client req contains kill_msg!"); + debug!(~"SERVER: sending response to client"); read_stop(client_stream_ptr); let server_chan = (*client_data).server_chan.clone(); server_chan.send(request_str); @@ -1504,28 +1484,28 @@ pub mod test { debug!("SERVER: resp write result: %d", write_result as int); if (write_result != 0i32) { - debug!("bad result for server resp write()"); - debug!("%s", get_last_err_info( + debug!(~"bad result for server resp write()"); + debug!(get_last_err_info( get_loop_for_uv_handle(client_stream_ptr as *libc::c_void))); fail_unless!(false); } } else { - debug!("SERVER: client req !contain kill_msg!"); + debug!(~"SERVER: client req !contain kill_msg!"); } } else if (nread == -1) { // err .. possibly EOF - debug!("read: eof!"); + debug!(~"read: eof!"); } else { // nread == 0 .. do nothing, just free buf as below - debug!("read: do nothing!"); + debug!(~"read: do nothing!"); } // when we're done free_base_of_buf(buf); - debug!("SERVER exiting on_read_cb"); + debug!(~"SERVER exiting on_read_cb"); } } @@ -1533,7 +1513,7 @@ pub mod test { *uv_stream_t, status: libc::c_int) { unsafe { - debug!("client connecting!"); + debug!(~"client connecting!"); let test_loop = get_loop_for_uv_handle( server_stream_ptr as *libc::c_void); if status != 0i32 { @@ -1551,7 +1531,7 @@ pub mod test { client_stream_ptr as *libc::c_void, server_data as *libc::c_void); if (client_init_result == 0i32) { - debug!("successfully initialized client stream"); + debug!(~"successfully initialized client stream"); let accept_result = accept(server_stream_ptr as *libc::c_void, client_stream_ptr as @@ -1563,7 +1543,7 @@ pub mod test { on_alloc_cb, on_server_read_cb); if (read_result == 0i32) { - debug!("successful server read start"); + debug!(~"successful server read start"); } else { debug!("server_connection_cb: bad read:%d", @@ -1674,7 +1654,7 @@ pub mod test { let bind_result = tcp_bind(tcp_server_ptr, server_addr_ptr); if (bind_result == 0i32) { - debug!("successful uv_tcp_bind, listening"); + debug!(~"successful uv_tcp_bind, listening"); // uv_listen() let listen_result = listen(tcp_server_ptr as @@ -1694,7 +1674,7 @@ pub mod test { async_send(continue_async_handle_ptr); // uv_run() run(test_loop); - debug!("server uv::run() has returned"); + debug!(~"server uv::run() has returned"); } else { debug!("uv_async_init failure: %d", @@ -1751,9 +1731,9 @@ pub mod test { }; // block until the server up is.. possibly a race? - debug!("before receiving on server continue_port"); + debug!(~"before receiving on server continue_port"); continue_port.recv(); - debug!("received on continue port, set up tcp client"); + debug!(~"received on continue port, set up tcp client"); let kill_server_msg_copy = copy kill_server_msg; do task::spawn_sched(task::ManualThreads(1u)) { @@ -1808,7 +1788,7 @@ pub mod test { let output = fmt!( "STRUCT_SIZE FAILURE: %s -- actual: %u expected: %u", t_name, rust_size, foreign_size as uint); - debug!("%s", output); + debug!(output); } fail_unless!(sizes_match); } diff --git a/src/libstd/workcache.rs b/src/libstd/workcache.rs index 68a6f8effaa77..f477a8c9f910b 100644 --- a/src/libstd/workcache.rs +++ b/src/libstd/workcache.rs @@ -96,7 +96,7 @@ use core::mutable::Mut; * */ -#[deriving_eq] +#[deriving(Eq)] #[auto_encode] #[auto_decode] struct WorkKey { @@ -106,7 +106,7 @@ struct WorkKey { impl to_bytes::IterBytes for WorkKey { #[inline(always)] - pure fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) { + fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) { let mut flag = true; self.kind.iter_bytes(lsb0, |bytes| {flag = f(bytes); flag}); if !flag { return; } @@ -115,24 +115,24 @@ impl to_bytes::IterBytes for WorkKey { } impl cmp::Ord for WorkKey { - pure fn lt(&self, other: &WorkKey) -> bool { + fn lt(&self, other: &WorkKey) -> bool { self.kind < other.kind || (self.kind == other.kind && self.name < other.name) } - pure fn le(&self, other: &WorkKey) -> bool { + fn le(&self, other: &WorkKey) -> bool { self.lt(other) || self.eq(other) } - pure fn ge(&self, other: &WorkKey) -> bool { + fn ge(&self, other: &WorkKey) -> bool { self.gt(other) || self.eq(other) } - pure fn gt(&self, other: &WorkKey) -> bool { + fn gt(&self, other: &WorkKey) -> bool { ! self.le(other) } } pub impl WorkKey { - static fn new(kind: &str, name: &str) -> WorkKey { + fn new(kind: &str, name: &str) -> WorkKey { WorkKey { kind: kind.to_owned(), name: name.to_owned() } } } @@ -151,7 +151,7 @@ impl Encodable for WorkMap { } impl Decodable for WorkMap { - static fn decode(&self, d: &D) -> WorkMap { + fn decode(d: &D) -> WorkMap { let v : ~[(WorkKey,~str)] = Decodable::decode(d); let mut w = LinearMap::new(); for v.each |&(k, v)| { @@ -234,9 +234,8 @@ fn json_encode>(t: &T) -> ~str { } } -fn json_decode>( // FIXME(#5121) - s: &str) -> T -{ +// FIXME(#5121) +fn json_decode>>(s: &str) -> T { do io::with_str_reader(s) |rdr| { let j = result::unwrap(json::from_reader(rdr)); Decodable::decode(&json::Decoder(j)) @@ -258,7 +257,7 @@ fn digest_file(path: &Path) -> ~str { pub impl Context { - static fn new(db: @Mut, + fn new(db: @Mut, lg: @Mut, cfg: @json::Object) -> Context { Context{db: db, logger: lg, cfg: cfg, freshness: LinearMap::new()} @@ -266,7 +265,7 @@ pub impl Context { fn prep + - Decodable>( // FIXME(#5121) + Decodable>>( // FIXME(#5121) @self, fn_name:&str, blk: &fn(@Mut)->Work) -> Work { @@ -284,7 +283,7 @@ trait TPrep { fn all_fresh(&self, cat:&str, map:&WorkMap) -> bool; fn exec + - Decodable>( // FIXME(#5121) + Decodable>>( // FIXME(#5121) &self, blk: ~fn(&Exec) -> T) -> Work; } @@ -325,7 +324,7 @@ impl TPrep for @Mut { fn exec + - Decodable>( // FIXME(#5121) + Decodable>>( // FIXME(#5121) &self, blk: ~fn(&Exec) -> T) -> Work { let mut bo = Some(blk); @@ -366,8 +365,8 @@ impl TPrep for @Mut { pub impl + - Decodable> Work { // FIXME(#5121) - static fn new(p: @Mut, e: Either>) -> Work { + Decodable>> Work { // FIXME(#5121) + fn new(p: @Mut, e: Either>) -> Work { Work { prep: p, res: Some(e) } } } @@ -375,7 +374,7 @@ pub impl + - Decodable>( // FIXME(#5121) + Decodable>>( // FIXME(#5121) w: Work) -> T { let mut ww = w; let mut s = None; diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index 22ec88cd45625..bef88e58a1795 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -33,13 +33,13 @@ macro_rules! interner_key ( // table and a SyntaxContext to track renaming and // macro expansion per Flatt et al., "Macros // That Work Together" -#[deriving_eq] +#[deriving(Eq)] pub struct ident { repr: Name } // a SyntaxContext represents a chain of macro-expandings // and renamings. Each macro expansion corresponds to // a fresh uint -#[deriving_eq] +#[deriving(Eq)] pub enum SyntaxContext { MT, Mark (Mrk,~SyntaxContext), @@ -75,7 +75,7 @@ impl Encodable for ident { } impl Decodable for ident { - static fn decode(d: &D) -> ident { + fn decode(d: &D) -> ident { let intr = match unsafe { task::local_data::local_data_get(interner_key!()) } { @@ -88,7 +88,7 @@ impl Decodable for ident { } impl to_bytes::IterBytes for ident { - pure fn iter_bytes(&self, +lsb0: bool, f: to_bytes::Cb) { + fn iter_bytes(&self, +lsb0: bool, f: to_bytes::Cb) { self.repr.iter_bytes(lsb0, f) } } @@ -98,7 +98,7 @@ pub type fn_ident = Option; #[auto_encode] #[auto_decode] -#[deriving_eq] +#[deriving(Eq)] pub struct Lifetime { id: node_id, span: span, @@ -111,7 +111,7 @@ pub struct Lifetime { // of supporting information. #[auto_encode] #[auto_decode] -#[deriving_eq] +#[deriving(Eq)] pub struct path { span: span, global: bool, @@ -126,18 +126,18 @@ pub type node_id = int; #[auto_encode] #[auto_decode] -#[deriving_eq] +#[deriving(Eq)] pub struct def_id { crate: crate_num, node: node_id, } -pub const local_crate: crate_num = 0; -pub const crate_node_id: node_id = 0; +pub static local_crate: crate_num = 0; +pub static crate_node_id: node_id = 0; #[auto_encode] #[auto_decode] -#[deriving_eq] +#[deriving(Eq)] // The AST represents all type param bounds as types. // typeck::collect::compute_bounds matches these against // the "special" built-in traits (see middle::lang_items) and @@ -149,7 +149,7 @@ pub enum TyParamBound { #[auto_encode] #[auto_decode] -#[deriving_eq] +#[deriving(Eq)] pub struct TyParam { ident: ident, id: node_id, @@ -158,7 +158,7 @@ pub struct TyParam { #[auto_encode] #[auto_decode] -#[deriving_eq] +#[deriving(Eq)] pub struct Generics { lifetimes: OptVec, ty_params: OptVec @@ -178,7 +178,7 @@ pub impl Generics { #[auto_encode] #[auto_decode] -#[deriving_eq] +#[deriving(Eq)] pub enum def { def_fn(def_id, purity), def_static_method(/* method */ def_id, @@ -216,7 +216,7 @@ pub type crate = spanned; #[auto_encode] #[auto_decode] -#[deriving_eq] +#[deriving(Eq)] pub struct crate_ { module: _mod, attrs: ~[attribute], @@ -227,7 +227,7 @@ pub type meta_item = spanned; #[auto_encode] #[auto_decode] -#[deriving_eq] +#[deriving(Eq)] pub enum meta_item_ { meta_word(@~str), meta_list(@~str, ~[@meta_item]), @@ -238,7 +238,7 @@ pub type blk = spanned; #[auto_encode] #[auto_decode] -#[deriving_eq] +#[deriving(Eq)] pub struct blk_ { view_items: ~[@view_item], stmts: ~[@stmt], @@ -249,7 +249,7 @@ pub struct blk_ { #[auto_encode] #[auto_decode] -#[deriving_eq] +#[deriving(Eq)] pub struct pat { id: node_id, node: pat_, @@ -258,7 +258,7 @@ pub struct pat { #[auto_encode] #[auto_decode] -#[deriving_eq] +#[deriving(Eq)] pub struct field_pat { ident: ident, pat: @pat, @@ -266,7 +266,7 @@ pub struct field_pat { #[auto_encode] #[auto_decode] -#[deriving_eq] +#[deriving(Eq)] pub enum binding_mode { bind_by_copy, bind_by_ref(mutability), @@ -274,7 +274,7 @@ pub enum binding_mode { } impl to_bytes::IterBytes for binding_mode { - pure fn iter_bytes(&self, +lsb0: bool, f: to_bytes::Cb) { + fn iter_bytes(&self, +lsb0: bool, f: to_bytes::Cb) { match *self { bind_by_copy => 0u8.iter_bytes(lsb0, f), @@ -289,7 +289,7 @@ impl to_bytes::IterBytes for binding_mode { #[auto_encode] #[auto_decode] -#[deriving_eq] +#[deriving(Eq)] pub enum pat_ { pat_wild, // A pat_ident may either be a new bound variable, @@ -316,30 +316,30 @@ pub enum pat_ { #[auto_encode] #[auto_decode] -#[deriving_eq] +#[deriving(Eq)] pub enum mutability { m_mutbl, m_imm, m_const, } impl to_bytes::IterBytes for mutability { - pure fn iter_bytes(&self, +lsb0: bool, f: to_bytes::Cb) { + fn iter_bytes(&self, +lsb0: bool, f: to_bytes::Cb) { (*self as u8).iter_bytes(lsb0, f) } } #[auto_encode] #[auto_decode] -#[deriving_eq] +#[deriving(Eq)] pub enum Abi { RustAbi } impl to_bytes::IterBytes for Abi { - pure fn iter_bytes(&self, +lsb0: bool, f: to_bytes::Cb) { + fn iter_bytes(&self, +lsb0: bool, f: to_bytes::Cb) { (*self as uint).iter_bytes(lsb0, f) } } impl ToStr for Abi { - pure fn to_str(&self) -> ~str { + fn to_str(&self) -> ~str { match *self { RustAbi => ~"\"rust\"" } @@ -348,7 +348,7 @@ impl ToStr for Abi { #[auto_encode] #[auto_decode] -#[deriving_eq] +#[deriving(Eq)] pub enum Sigil { BorrowedSigil, OwnedSigil, @@ -356,13 +356,13 @@ pub enum Sigil { } impl to_bytes::IterBytes for Sigil { - pure fn iter_bytes(&self, +lsb0: bool, f: to_bytes::Cb) { + fn iter_bytes(&self, +lsb0: bool, f: to_bytes::Cb) { (*self as uint).iter_bytes(lsb0, f) } } impl ToStr for Sigil { - pure fn to_str(&self) -> ~str { + fn to_str(&self) -> ~str { match *self { BorrowedSigil => ~"&", OwnedSigil => ~"~", @@ -373,7 +373,7 @@ impl ToStr for Sigil { #[auto_encode] #[auto_decode] -#[deriving_eq] +#[deriving(Eq)] pub enum vstore { // FIXME (#3469): Change uint to @expr (actually only constant exprs) vstore_fixed(Option), // [1,2,3,4] @@ -384,7 +384,7 @@ pub enum vstore { #[auto_encode] #[auto_decode] -#[deriving_eq] +#[deriving(Eq)] pub enum expr_vstore { expr_vstore_fixed(Option), // [1,2,3,4] expr_vstore_uniq, // ~[1,2,3,4] @@ -396,7 +396,7 @@ pub enum expr_vstore { #[auto_encode] #[auto_decode] -#[deriving_eq] +#[deriving(Eq)] pub enum binop { add, subtract, @@ -420,7 +420,7 @@ pub enum binop { #[auto_encode] #[auto_decode] -#[deriving_eq] +#[deriving(Eq)] pub enum unop { box(mutability), uniq(mutability), @@ -433,14 +433,14 @@ pub enum unop { // using ty::resolved_T(...). #[auto_encode] #[auto_decode] -#[deriving_eq] +#[deriving(Eq)] pub enum inferable { expl(T), infer(node_id) } impl to_bytes::IterBytes for inferable { - pure fn iter_bytes(&self, +lsb0: bool, f: to_bytes::Cb) { + fn iter_bytes(&self, +lsb0: bool, f: to_bytes::Cb) { match *self { expl(ref t) => to_bytes::iter_bytes_2(&0u8, t, lsb0, f), @@ -454,11 +454,11 @@ impl to_bytes::IterBytes for inferable { // "resolved" mode: the real modes. #[auto_encode] #[auto_decode] -#[deriving_eq] +#[deriving(Eq)] pub enum rmode { by_ref, by_copy } impl to_bytes::IterBytes for rmode { - pure fn iter_bytes(&self, +lsb0: bool, f: to_bytes::Cb) { + fn iter_bytes(&self, +lsb0: bool, f: to_bytes::Cb) { (*self as u8).iter_bytes(lsb0, f) } } @@ -470,7 +470,7 @@ pub type stmt = spanned; #[auto_encode] #[auto_decode] -#[deriving_eq] +#[deriving(Eq)] pub enum stmt_ { stmt_decl(@decl, node_id), @@ -488,7 +488,7 @@ pub enum stmt_ { // a refinement on pat. #[auto_encode] #[auto_decode] -#[deriving_eq] +#[deriving(Eq)] pub struct local_ { is_mutbl: bool, ty: @Ty, @@ -503,12 +503,12 @@ pub type decl = spanned; #[auto_encode] #[auto_decode] -#[deriving_eq] +#[deriving(Eq)] pub enum decl_ { decl_local(~[@local]), decl_item(@item), } #[auto_encode] #[auto_decode] -#[deriving_eq] +#[deriving(Eq)] pub struct arm { pats: ~[@pat], guard: Option<@expr>, @@ -517,7 +517,7 @@ pub struct arm { #[auto_encode] #[auto_decode] -#[deriving_eq] +#[deriving(Eq)] pub struct field_ { mutbl: mutability, ident: ident, @@ -528,12 +528,12 @@ pub type field = spanned; #[auto_encode] #[auto_decode] -#[deriving_eq] +#[deriving(Eq)] pub enum blk_check_mode { default_blk, unsafe_blk, } #[auto_encode] #[auto_decode] -#[deriving_eq] +#[deriving(Eq)] pub struct expr { id: node_id, // Extra node ID is only used for index, assign_op, unary, binary, method @@ -545,13 +545,13 @@ pub struct expr { #[auto_encode] #[auto_decode] -#[deriving_eq] +#[deriving(Eq)] pub enum log_level { error, debug, log_other } // 0 = error, 1 = debug, 2 = log_other #[auto_encode] #[auto_decode] -#[deriving_eq] +#[deriving(Eq)] pub enum CallSugar { NoSugar, DoSugar, @@ -560,7 +560,7 @@ pub enum CallSugar { #[auto_encode] #[auto_decode] -#[deriving_eq] +#[deriving(Eq)] pub enum expr_ { expr_vstore(@expr, expr_vstore), expr_vec(~[@expr], mutability), @@ -634,7 +634,7 @@ pub enum expr_ { // #[auto_encode] #[auto_decode] -#[deriving_eq] +#[deriving(Eq)] #[doc="For macro invocations; parsing is delegated to the macro"] pub enum token_tree { // a single token @@ -709,7 +709,7 @@ pub type matcher = spanned; #[auto_encode] #[auto_decode] -#[deriving_eq] +#[deriving(Eq)] pub enum matcher_ { // match one token match_tok(::parse::token::Token), @@ -724,7 +724,7 @@ pub type mac = spanned; #[auto_encode] #[auto_decode] -#[deriving_eq] +#[deriving(Eq)] pub enum mac_ { mac_invoc_tt(@path,~[token_tree]), // new macro-invocation } @@ -733,7 +733,7 @@ pub type lit = spanned; #[auto_encode] #[auto_decode] -#[deriving_eq] +#[deriving(Eq)] pub enum lit_ { lit_str(@~str), lit_int(i64, int_ty), @@ -749,7 +749,7 @@ pub enum lit_ { // type structure in middle/ty.rs as well. #[auto_encode] #[auto_decode] -#[deriving_eq] +#[deriving(Eq)] pub struct mt { ty: @Ty, mutbl: mutability, @@ -757,7 +757,7 @@ pub struct mt { #[auto_encode] #[auto_decode] -#[deriving_eq] +#[deriving(Eq)] pub struct ty_field_ { ident: ident, mt: mt, @@ -767,7 +767,7 @@ pub type ty_field = spanned; #[auto_encode] #[auto_decode] -#[deriving_eq] +#[deriving(Eq)] pub struct ty_method { ident: ident, attrs: ~[attribute], @@ -781,7 +781,7 @@ pub struct ty_method { #[auto_encode] #[auto_decode] -#[deriving_eq] +#[deriving(Eq)] // A trait method is either required (meaning it doesn't have an // implementation, just a signature) or provided (meaning it has a default // implementation). @@ -792,51 +792,51 @@ pub enum trait_method { #[auto_encode] #[auto_decode] -#[deriving_eq] +#[deriving(Eq)] pub enum int_ty { ty_i, ty_char, ty_i8, ty_i16, ty_i32, ty_i64, } impl ToStr for int_ty { - pure fn to_str(&self) -> ~str { + fn to_str(&self) -> ~str { ::ast_util::int_ty_to_str(*self) } } impl to_bytes::IterBytes for int_ty { - pure fn iter_bytes(&self, +lsb0: bool, f: to_bytes::Cb) { + fn iter_bytes(&self, +lsb0: bool, f: to_bytes::Cb) { (*self as u8).iter_bytes(lsb0, f) } } #[auto_encode] #[auto_decode] -#[deriving_eq] +#[deriving(Eq)] pub enum uint_ty { ty_u, ty_u8, ty_u16, ty_u32, ty_u64, } impl ToStr for uint_ty { - pure fn to_str(&self) -> ~str { + fn to_str(&self) -> ~str { ::ast_util::uint_ty_to_str(*self) } } impl to_bytes::IterBytes for uint_ty { - pure fn iter_bytes(&self, +lsb0: bool, f: to_bytes::Cb) { + fn iter_bytes(&self, +lsb0: bool, f: to_bytes::Cb) { (*self as u8).iter_bytes(lsb0, f) } } #[auto_encode] #[auto_decode] -#[deriving_eq] +#[deriving(Eq)] pub enum float_ty { ty_f, ty_f32, ty_f64, } impl ToStr for float_ty { - pure fn to_str(&self) -> ~str { + fn to_str(&self) -> ~str { ::ast_util::float_ty_to_str(*self) } } impl to_bytes::IterBytes for float_ty { - pure fn iter_bytes(&self, +lsb0: bool, f: to_bytes::Cb) { + fn iter_bytes(&self, +lsb0: bool, f: to_bytes::Cb) { (*self as u8).iter_bytes(lsb0, f) } } @@ -844,7 +844,7 @@ impl to_bytes::IterBytes for float_ty { // NB Eq method appears below. #[auto_encode] #[auto_decode] -#[deriving_eq] +#[deriving(Eq)] pub struct Ty { id: node_id, node: ty_, @@ -854,7 +854,7 @@ pub struct Ty { // Not represented directly in the AST, referred to by name through a ty_path. #[auto_encode] #[auto_decode] -#[deriving_eq] +#[deriving(Eq)] pub enum prim_ty { ty_int(int_ty), ty_uint(uint_ty), @@ -865,14 +865,14 @@ pub enum prim_ty { #[auto_encode] #[auto_decode] -#[deriving_eq] +#[deriving(Eq)] pub enum Onceness { Once, Many } impl ToStr for Onceness { - pure fn to_str(&self) -> ~str { + fn to_str(&self) -> ~str { match *self { Once => ~"once", Many => ~"many" @@ -881,14 +881,14 @@ impl ToStr for Onceness { } impl to_bytes::IterBytes for Onceness { - pure fn iter_bytes(&self, +lsb0: bool, f: to_bytes::Cb) { + fn iter_bytes(&self, +lsb0: bool, f: to_bytes::Cb) { (*self as uint).iter_bytes(lsb0, f); } } #[auto_encode] #[auto_decode] -#[deriving_eq] +#[deriving(Eq)] pub struct TyClosure { sigil: Sigil, region: Option<@Lifetime>, @@ -899,7 +899,7 @@ pub struct TyClosure { #[auto_encode] #[auto_decode] -#[deriving_eq] +#[deriving(Eq)] pub struct TyBareFn { purity: purity, abi: Abi, @@ -908,7 +908,7 @@ pub struct TyBareFn { #[auto_encode] #[auto_decode] -#[deriving_eq] +#[deriving(Eq)] pub enum ty_ { ty_nil, ty_bot, /* bottom type */ @@ -930,14 +930,14 @@ pub enum ty_ { } impl to_bytes::IterBytes for Ty { - pure fn iter_bytes(&self, +lsb0: bool, f: to_bytes::Cb) { + fn iter_bytes(&self, +lsb0: bool, f: to_bytes::Cb) { to_bytes::iter_bytes_2(&self.span.lo, &self.span.hi, lsb0, f); } } #[auto_encode] #[auto_decode] -#[deriving_eq] +#[deriving(Eq)] pub struct arg { mode: mode, is_mutbl: bool, @@ -948,7 +948,7 @@ pub struct arg { #[auto_encode] #[auto_decode] -#[deriving_eq] +#[deriving(Eq)] pub struct fn_decl { inputs: ~[arg], output: @Ty, @@ -957,7 +957,7 @@ pub struct fn_decl { #[auto_encode] #[auto_decode] -#[deriving_eq] +#[deriving(Eq)] pub enum purity { pure_fn, // declared with "pure fn" unsafe_fn, // declared with "unsafe fn" @@ -966,7 +966,7 @@ pub enum purity { } impl ToStr for purity { - pure fn to_str(&self) -> ~str { + fn to_str(&self) -> ~str { match *self { impure_fn => ~"impure", unsafe_fn => ~"unsafe", @@ -977,14 +977,14 @@ impl ToStr for purity { } impl to_bytes::IterBytes for purity { - pure fn iter_bytes(&self, +lsb0: bool, f: to_bytes::Cb) { + fn iter_bytes(&self, +lsb0: bool, f: to_bytes::Cb) { (*self as u8).iter_bytes(lsb0, f) } } #[auto_encode] #[auto_decode] -#[deriving_eq] +#[deriving(Eq)] pub enum ret_style { noreturn, // functions with return type _|_ that always // raise an error or exit (i.e. never return to the caller) @@ -992,14 +992,14 @@ pub enum ret_style { } impl to_bytes::IterBytes for ret_style { - pure fn iter_bytes(&self, +lsb0: bool, f: to_bytes::Cb) { + fn iter_bytes(&self, +lsb0: bool, f: to_bytes::Cb) { (*self as u8).iter_bytes(lsb0, f) } } #[auto_encode] #[auto_decode] -#[deriving_eq] +#[deriving(Eq)] pub enum self_ty_ { sty_static, // no self sty_by_ref, // `` @@ -1022,7 +1022,7 @@ pub type self_ty = spanned; #[auto_encode] #[auto_decode] -#[deriving_eq] +#[deriving(Eq)] pub struct method { ident: ident, attrs: ~[attribute], @@ -1039,7 +1039,7 @@ pub struct method { #[auto_encode] #[auto_decode] -#[deriving_eq] +#[deriving(Eq)] pub struct _mod { view_items: ~[@view_item], items: ~[@item], @@ -1047,7 +1047,7 @@ pub struct _mod { #[auto_encode] #[auto_decode] -#[deriving_eq] +#[deriving(Eq)] pub enum foreign_abi { foreign_abi_rust_intrinsic, foreign_abi_cdecl, @@ -1057,12 +1057,12 @@ pub enum foreign_abi { // Foreign mods can be named or anonymous #[auto_encode] #[auto_decode] -#[deriving_eq] +#[deriving(Eq)] pub enum foreign_mod_sort { named, anonymous } #[auto_encode] #[auto_decode] -#[deriving_eq] +#[deriving(Eq)] pub struct foreign_mod { sort: foreign_mod_sort, abi: ident, @@ -1072,7 +1072,7 @@ pub struct foreign_mod { #[auto_encode] #[auto_decode] -#[deriving_eq] +#[deriving(Eq)] pub struct variant_arg { ty: @Ty, id: node_id, @@ -1080,7 +1080,7 @@ pub struct variant_arg { #[auto_encode] #[auto_decode] -#[deriving_eq] +#[deriving(Eq)] pub enum variant_kind { tuple_variant_kind(~[variant_arg]), struct_variant_kind(@struct_def), @@ -1089,7 +1089,7 @@ pub enum variant_kind { #[auto_encode] #[auto_decode] -#[deriving_eq] +#[deriving(Eq)] pub struct enum_def { variants: ~[variant], common: Option<@struct_def>, @@ -1097,7 +1097,7 @@ pub struct enum_def { #[auto_encode] #[auto_decode] -#[deriving_eq] +#[deriving(Eq)] pub struct variant_ { name: ident, attrs: ~[attribute], @@ -1111,7 +1111,7 @@ pub type variant = spanned; #[auto_encode] #[auto_decode] -#[deriving_eq] +#[deriving(Eq)] pub struct path_list_ident_ { name: ident, id: node_id, @@ -1121,14 +1121,14 @@ pub type path_list_ident = spanned; #[auto_encode] #[auto_decode] -#[deriving_eq] +#[deriving(Eq)] pub enum namespace { module_ns, type_value_ns } pub type view_path = spanned; #[auto_encode] #[auto_decode] -#[deriving_eq] +#[deriving(Eq)] pub enum view_path_ { // quux = foo::bar::baz @@ -1147,7 +1147,7 @@ pub enum view_path_ { #[auto_encode] #[auto_decode] -#[deriving_eq] +#[deriving(Eq)] pub struct view_item { node: view_item_, attrs: ~[attribute], @@ -1157,7 +1157,7 @@ pub struct view_item { #[auto_encode] #[auto_decode] -#[deriving_eq] +#[deriving(Eq)] pub enum view_item_ { view_item_extern_mod(ident, ~[@meta_item], node_id), view_item_use(~[@view_path]), @@ -1171,13 +1171,13 @@ pub type attribute = spanned; // distinguished for pretty-printing. #[auto_encode] #[auto_decode] -#[deriving_eq] +#[deriving(Eq)] pub enum attr_style { attr_outer, attr_inner, } // doc-comments are promoted to attributes that have is_sugared_doc = true #[auto_encode] #[auto_decode] -#[deriving_eq] +#[deriving(Eq)] pub struct attribute_ { style: attr_style, value: @meta_item, @@ -1193,7 +1193,7 @@ pub struct attribute_ { */ #[auto_encode] #[auto_decode] -#[deriving_eq] +#[deriving(Eq)] pub struct trait_ref { path: @path, ref_id: node_id, @@ -1201,12 +1201,12 @@ pub struct trait_ref { #[auto_encode] #[auto_decode] -#[deriving_eq] +#[deriving(Eq)] pub enum visibility { public, private, inherited } #[auto_encode] #[auto_decode] -#[deriving_eq] +#[deriving(Eq)] pub struct struct_field_ { kind: struct_field_kind, id: node_id, @@ -1217,7 +1217,7 @@ pub type struct_field = spanned; #[auto_encode] #[auto_decode] -#[deriving_eq] +#[deriving(Eq)] pub enum struct_field_kind { named_field(ident, struct_mutability, visibility), unnamed_field // element of a tuple-like struct @@ -1225,7 +1225,7 @@ pub enum struct_field_kind { #[auto_encode] #[auto_decode] -#[deriving_eq] +#[deriving(Eq)] pub struct struct_def { fields: ~[@struct_field], /* fields */ /* (not including ctor or dtor) */ @@ -1242,7 +1242,7 @@ pub struct struct_def { */ #[auto_encode] #[auto_decode] -#[deriving_eq] +#[deriving(Eq)] pub struct item { ident: ident, attrs: ~[attribute], @@ -1254,7 +1254,7 @@ pub struct item { #[auto_encode] #[auto_decode] -#[deriving_eq] +#[deriving(Eq)] pub enum item_ { item_const(@Ty, @expr), item_fn(fn_decl, purity, Generics, blk), @@ -1274,11 +1274,11 @@ pub enum item_ { #[auto_encode] #[auto_decode] -#[deriving_eq] +#[deriving(Eq)] pub enum struct_mutability { struct_mutable, struct_immutable } impl to_bytes::IterBytes for struct_mutability { - pure fn iter_bytes(&self, +lsb0: bool, f: to_bytes::Cb) { + fn iter_bytes(&self, +lsb0: bool, f: to_bytes::Cb) { (*self as u8).iter_bytes(lsb0, f) } } @@ -1287,7 +1287,7 @@ pub type struct_dtor = spanned; #[auto_encode] #[auto_decode] -#[deriving_eq] +#[deriving(Eq)] pub struct struct_dtor_ { id: node_id, attrs: ~[attribute], @@ -1297,7 +1297,7 @@ pub struct struct_dtor_ { #[auto_encode] #[auto_decode] -#[deriving_eq] +#[deriving(Eq)] pub struct foreign_item { ident: ident, attrs: ~[attribute], @@ -1309,7 +1309,7 @@ pub struct foreign_item { #[auto_encode] #[auto_decode] -#[deriving_eq] +#[deriving(Eq)] pub enum foreign_item_ { foreign_item_fn(fn_decl, purity, Generics), foreign_item_const(@Ty) @@ -1320,7 +1320,7 @@ pub enum foreign_item_ { // that we trans. #[auto_encode] #[auto_decode] -#[deriving_eq] +#[deriving(Eq)] pub enum inlined_item { ii_item(@item), ii_method(def_id /* impl id */, @method), diff --git a/src/libsyntax/ast_map.rs b/src/libsyntax/ast_map.rs index 9371055556ef5..8989bb88cd7f4 100644 --- a/src/libsyntax/ast_map.rs +++ b/src/libsyntax/ast_map.rs @@ -33,7 +33,7 @@ pub enum path_elt { } impl cmp::Eq for path_elt { - pure fn eq(&self, other: &path_elt) -> bool { + fn eq(&self, other: &path_elt) -> bool { match (*self) { path_mod(e0a) => { match (*other) { @@ -49,7 +49,7 @@ impl cmp::Eq for path_elt { } } } - pure fn ne(&self, other: &path_elt) -> bool { !(*self).eq(other) } + fn ne(&self, other: &path_elt) -> bool { !(*self).eq(other) } } pub type path = ~[path_elt]; diff --git a/src/libsyntax/ast_util.rs b/src/libsyntax/ast_util.rs index 35b188a248fd4..764393e0feb6e 100644 --- a/src/libsyntax/ast_util.rs +++ b/src/libsyntax/ast_util.rs @@ -24,22 +24,21 @@ use core::str; use core::to_bytes; use core::vec; -pub pure fn path_name_i(idents: &[ident], intr: @token::ident_interner) - -> ~str { +pub 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| copy *intr.get(*i)), ~"::") } -pub pure fn path_to_ident(p: @path) -> ident { copy *p.idents.last() } +pub fn path_to_ident(p: @path) -> ident { copy *p.idents.last() } -pub pure fn local_def(id: node_id) -> def_id { +pub fn local_def(id: node_id) -> def_id { ast::def_id { crate: local_crate, node: id } } -pub pure fn is_local(did: ast::def_id) -> bool { did.crate == local_crate } +pub fn is_local(did: ast::def_id) -> bool { did.crate == local_crate } -pub pure fn stmt_id(s: stmt) -> node_id { +pub fn stmt_id(s: stmt) -> node_id { match s.node { stmt_decl(_, id) => id, stmt_expr(_, id) => id, @@ -57,7 +56,7 @@ pub fn variant_def_ids(d: def) -> (def_id, def_id) { } } -pub pure fn def_id_of_def(d: def) -> def_id { +pub fn def_id_of_def(d: def) -> def_id { match d { def_fn(id, _) | def_static_method(id, _, _) | def_mod(id) | def_foreign_mod(id) | def_const(id) | @@ -75,7 +74,7 @@ pub pure fn def_id_of_def(d: def) -> def_id { } } -pub pure fn binop_to_str(op: binop) -> ~str { +pub fn binop_to_str(op: binop) -> ~str { match op { add => return ~"+", subtract => return ~"-", @@ -98,7 +97,7 @@ pub pure fn binop_to_str(op: binop) -> ~str { } } -pub pure fn binop_to_method_name(op: binop) -> Option<~str> { +pub fn binop_to_method_name(op: binop) -> Option<~str> { match op { add => return Some(~"add"), subtract => return Some(~"sub"), @@ -120,7 +119,7 @@ pub pure fn binop_to_method_name(op: binop) -> Option<~str> { } } -pub pure fn lazy_binop(b: binop) -> bool { +pub fn lazy_binop(b: binop) -> bool { match b { and => true, or => true, @@ -128,7 +127,7 @@ pub pure fn lazy_binop(b: binop) -> bool { } } -pub pure fn is_shift_binop(b: binop) -> bool { +pub fn is_shift_binop(b: binop) -> bool { match b { shl => true, shr => true, @@ -136,7 +135,7 @@ pub pure fn is_shift_binop(b: binop) -> bool { } } -pub pure fn unop_to_str(op: unop) -> ~str { +pub fn unop_to_str(op: unop) -> ~str { match op { box(mt) => if mt == m_mutbl { ~"@mut " } else { ~"@" }, uniq(mt) => if mt == m_mutbl { ~"~mut " } else { ~"~" }, @@ -146,11 +145,11 @@ pub pure fn unop_to_str(op: unop) -> ~str { } } -pub pure fn is_path(e: @expr) -> bool { +pub fn is_path(e: @expr) -> bool { return match e.node { expr_path(_) => true, _ => false }; } -pub pure fn int_ty_to_str(t: int_ty) -> ~str { +pub fn int_ty_to_str(t: int_ty) -> ~str { match t { ty_char => ~"u8", // ??? ty_i => ~"", @@ -161,7 +160,7 @@ pub pure fn int_ty_to_str(t: int_ty) -> ~str { } } -pub pure fn int_ty_max(t: int_ty) -> u64 { +pub fn int_ty_max(t: int_ty) -> u64 { match t { ty_i8 => 0x80u64, ty_i16 => 0x8000u64, @@ -170,7 +169,7 @@ pub pure fn int_ty_max(t: int_ty) -> u64 { } } -pub pure fn uint_ty_to_str(t: uint_ty) -> ~str { +pub fn uint_ty_to_str(t: uint_ty) -> ~str { match t { ty_u => ~"u", ty_u8 => ~"u8", @@ -180,7 +179,7 @@ pub pure fn uint_ty_to_str(t: uint_ty) -> ~str { } } -pub pure fn uint_ty_max(t: uint_ty) -> u64 { +pub fn uint_ty_max(t: uint_ty) -> u64 { match t { ty_u8 => 0xffu64, ty_u16 => 0xffffu64, @@ -189,18 +188,18 @@ pub pure fn uint_ty_max(t: uint_ty) -> u64 { } } -pub pure fn float_ty_to_str(t: float_ty) -> ~str { +pub fn float_ty_to_str(t: float_ty) -> ~str { match t { ty_f => ~"f", ty_f32 => ~"f32", ty_f64 => ~"f64" } } -pub pure fn is_call_expr(e: @expr) -> bool { +pub fn is_call_expr(e: @expr) -> bool { match e.node { expr_call(_, _, _) => true, _ => false } } // This makes def_id hashable impl to_bytes::IterBytes for def_id { #[inline(always)] - pure fn iter_bytes(&self, +lsb0: bool, f: to_bytes::Cb) { + fn iter_bytes(&self, +lsb0: bool, f: to_bytes::Cb) { to_bytes::iter_bytes_2(&self.crate, &self.node, lsb0, f); } } @@ -238,14 +237,14 @@ pub fn ident_to_pat(id: node_id, s: span, +i: ident) -> @pat { span: s } } -pub pure fn is_unguarded(a: &arm) -> bool { +pub fn is_unguarded(a: &arm) -> bool { match a.guard { None => true, _ => false } } -pub pure fn unguarded_pat(a: &arm) -> Option<~[@pat]> { +pub fn unguarded_pat(a: &arm) -> Option<~[@pat]> { if is_unguarded(a) { Some(/* FIXME (#2543) */ copy a.pats) } else { None } } @@ -290,7 +289,7 @@ pub fn split_trait_methods(trait_methods: &[trait_method]) (reqd, provd) } -pub pure fn struct_field_visibility(field: ast::struct_field) -> visibility { +pub fn struct_field_visibility(field: ast::struct_field) -> visibility { match field.node.kind { ast::named_field(_, _, visibility) => visibility, ast::unnamed_field => ast::public @@ -509,7 +508,7 @@ pub fn compute_id_range_for_inlined_item(item: inlined_item) -> id_range { compute_id_range(|f| visit_ids_for_inlined_item(item, f)) } -pub pure fn is_item_impl(item: @ast::item) -> bool { +pub fn is_item_impl(item: @ast::item) -> bool { match item.node { item_impl(*) => true, _ => false @@ -582,7 +581,7 @@ pub fn variant_visibility_to_privacy(visibility: visibility, } } -#[deriving_eq] +#[deriving(Eq)] pub enum Privacy { Private, Public diff --git a/src/libsyntax/attr.rs b/src/libsyntax/attr.rs index a410d6cf8e3a2..b22d71afaed2d 100644 --- a/src/libsyntax/attr.rs +++ b/src/libsyntax/attr.rs @@ -89,11 +89,11 @@ pub fn desugar_doc_attr(attr: &ast::attribute) -> ast::attribute { /* Accessors */ -pub pure fn get_attr_name(attr: &ast::attribute) -> @~str { +pub fn get_attr_name(attr: &ast::attribute) -> @~str { get_meta_item_name(attr.node.value) } -pub pure fn get_meta_item_name(meta: @ast::meta_item) -> @~str { +pub fn get_meta_item_name(meta: @ast::meta_item) -> @~str { match meta.node { ast::meta_word(n) => n, ast::meta_name_value(n, _) => n, @@ -333,10 +333,10 @@ pub enum inline_attr { } impl cmp::Eq for inline_attr { - pure fn eq(&self, other: &inline_attr) -> bool { + fn eq(&self, other: &inline_attr) -> bool { ((*self) as uint) == ((*other) as uint) } - pure fn ne(&self, other: &inline_attr) -> bool { !(*self).eq(other) } + fn ne(&self, other: &inline_attr) -> bool { !(*self).eq(other) } } /// True if something like #[inline] is found in the list of attrs. diff --git a/src/libsyntax/codemap.rs b/src/libsyntax/codemap.rs index 538f0de8c842b..c082f4c083850 100644 --- a/src/libsyntax/codemap.rs +++ b/src/libsyntax/codemap.rs @@ -30,8 +30,8 @@ use core::uint; use std::serialize::{Encodable, Decodable, Encoder, Decoder}; pub trait Pos { - static pure fn from_uint(n: uint) -> Self; - pure fn to_uint(&self) -> uint; + fn from_uint(n: uint) -> Self; + fn to_uint(&self) -> uint; } /// A byte offset @@ -45,71 +45,71 @@ pub struct CharPos(uint); // have been unsuccessful impl Pos for BytePos { - static pure fn from_uint(n: uint) -> BytePos { BytePos(n) } - pure fn to_uint(&self) -> uint { **self } + fn from_uint(n: uint) -> BytePos { BytePos(n) } + fn to_uint(&self) -> uint { **self } } impl cmp::Eq for BytePos { - pure fn eq(&self, other: &BytePos) -> bool { **self == **other } - pure fn ne(&self, other: &BytePos) -> bool { !(*self).eq(other) } + fn eq(&self, other: &BytePos) -> bool { **self == **other } + fn ne(&self, other: &BytePos) -> bool { !(*self).eq(other) } } impl cmp::Ord for BytePos { - pure fn lt(&self, other: &BytePos) -> bool { **self < **other } - pure fn le(&self, other: &BytePos) -> bool { **self <= **other } - pure fn ge(&self, other: &BytePos) -> bool { **self >= **other } - pure fn gt(&self, other: &BytePos) -> bool { **self > **other } + fn lt(&self, other: &BytePos) -> bool { **self < **other } + fn le(&self, other: &BytePos) -> bool { **self <= **other } + fn ge(&self, other: &BytePos) -> bool { **self >= **other } + fn gt(&self, other: &BytePos) -> bool { **self > **other } } impl Add for BytePos { - pure fn add(&self, rhs: &BytePos) -> BytePos { + fn add(&self, rhs: &BytePos) -> BytePos { BytePos(**self + **rhs) } } impl Sub for BytePos { - pure fn sub(&self, rhs: &BytePos) -> BytePos { + fn sub(&self, rhs: &BytePos) -> BytePos { BytePos(**self - **rhs) } } impl to_bytes::IterBytes for BytePos { - pure fn iter_bytes(&self, +lsb0: bool, &&f: to_bytes::Cb) { + fn iter_bytes(&self, +lsb0: bool, &&f: to_bytes::Cb) { (**self).iter_bytes(lsb0, f) } } impl Pos for CharPos { - static pure fn from_uint(n: uint) -> CharPos { CharPos(n) } - pure fn to_uint(&self) -> uint { **self } + fn from_uint(n: uint) -> CharPos { CharPos(n) } + fn to_uint(&self) -> uint { **self } } impl cmp::Eq for CharPos { - pure fn eq(&self, other: &CharPos) -> bool { **self == **other } - pure fn ne(&self, other: &CharPos) -> bool { !(*self).eq(other) } + fn eq(&self, other: &CharPos) -> bool { **self == **other } + fn ne(&self, other: &CharPos) -> bool { !(*self).eq(other) } } impl cmp::Ord for CharPos { - pure fn lt(&self, other: &CharPos) -> bool { **self < **other } - pure fn le(&self, other: &CharPos) -> bool { **self <= **other } - pure fn ge(&self, other: &CharPos) -> bool { **self >= **other } - pure fn gt(&self, other: &CharPos) -> bool { **self > **other } + fn lt(&self, other: &CharPos) -> bool { **self < **other } + fn le(&self, other: &CharPos) -> bool { **self <= **other } + fn ge(&self, other: &CharPos) -> bool { **self >= **other } + fn gt(&self, other: &CharPos) -> bool { **self > **other } } impl to_bytes::IterBytes for CharPos { - pure fn iter_bytes(&self, +lsb0: bool, &&f: to_bytes::Cb) { + fn iter_bytes(&self, +lsb0: bool, &&f: to_bytes::Cb) { (**self).iter_bytes(lsb0, f) } } impl Add for CharPos { - pure fn add(&self, rhs: &CharPos) -> CharPos { + fn add(&self, rhs: &CharPos) -> CharPos { CharPos(**self + **rhs) } } impl Sub for CharPos { - pure fn sub(&self, rhs: &CharPos) -> CharPos { + fn sub(&self, rhs: &CharPos) -> CharPos { CharPos(**self - **rhs) } } @@ -128,14 +128,14 @@ pub struct span { #[auto_encode] #[auto_decode] -#[deriving_eq] +#[deriving(Eq)] pub struct spanned { node: T, span: span } impl cmp::Eq for span { - pure fn eq(&self, other: &span) -> bool { + fn eq(&self, other: &span) -> bool { return (*self).lo == (*other).lo && (*self).hi == (*other).hi; } - pure fn ne(&self, other: &span) -> bool { !(*self).eq(other) } + fn ne(&self, other: &span) -> bool { !(*self).eq(other) } } impl Encodable for span { @@ -144,30 +144,30 @@ impl Encodable for span { } impl Decodable for span { - static fn decode(_d: &D) -> span { + fn decode(_d: &D) -> span { dummy_sp() } } -pub pure fn spanned(+lo: BytePos, +hi: BytePos, +t: T) -> spanned { +pub fn spanned(+lo: BytePos, +hi: BytePos, +t: T) -> spanned { respan(mk_sp(lo, hi), t) } -pub pure fn respan(sp: span, +t: T) -> spanned { +pub fn respan(sp: span, +t: T) -> spanned { spanned {node: t, span: sp} } -pub pure fn dummy_spanned(+t: T) -> spanned { +pub fn dummy_spanned(+t: T) -> spanned { respan(dummy_sp(), t) } /* assuming that we're not in macro expansion */ -pub pure fn mk_sp(+lo: BytePos, +hi: BytePos) -> span { +pub fn mk_sp(+lo: BytePos, +hi: BytePos) -> span { span {lo: lo, hi: hi, expn_info: None} } // make this a const, once the compiler supports it -pub pure fn dummy_sp() -> span { return mk_sp(BytePos(0), BytePos(0)); } +pub fn dummy_sp() -> span { return mk_sp(BytePos(0), BytePos(0)); } @@ -208,7 +208,8 @@ pub enum ExpnInfo { pub type FileName = ~str; -pub struct FileLines { +pub struct FileLines +{ file: @FileMap, lines: ~[uint] } @@ -266,7 +267,7 @@ pub impl FileMap { Some(e) => e, None => str::len(*self.src) }; - str::slice(*self.src, begin, end) + str::slice(*self.src, begin, end).to_owned() } } @@ -285,7 +286,7 @@ pub struct CodeMap { } pub impl CodeMap { - static pub fn new() -> CodeMap { + pub fn new() -> CodeMap { CodeMap { files: @mut ~[], } @@ -396,7 +397,7 @@ pub impl CodeMap { let end = self.lookup_byte_offset(sp.hi); fail_unless!(begin.fm.start_pos == end.fm.start_pos); return str::slice(*begin.fm.src, - begin.pos.to_uint(), end.pos.to_uint()); + begin.pos.to_uint(), end.pos.to_uint()).to_owned(); } pub fn get_filemap(&self, filename: ~str) -> @FileMap { @@ -509,17 +510,16 @@ priv impl CodeMap { #[cfg(test)] mod test { use super::*; - use util::testing::check_equal; #[test] fn t1 () { let cm = CodeMap::new(); let fm = cm.new_filemap(~"blork.rs",@~"first line.\nsecond line"); fm.next_line(BytePos(0)); - check_equal(&fm.get_line(0),&~"first line."); + assert_eq!(&fm.get_line(0),&~"first line."); // TESTING BROKEN BEHAVIOR: fm.next_line(BytePos(10)); - check_equal(&fm.get_line(1),&~"."); + assert_eq!(&fm.get_line(1),&~"."); } #[test] diff --git a/src/libsyntax/diagnostic.rs b/src/libsyntax/diagnostic.rs index 93d28f31c8db4..eed36e16754f5 100644 --- a/src/libsyntax/diagnostic.rs +++ b/src/libsyntax/diagnostic.rs @@ -160,7 +160,7 @@ pub fn mk_handler(emitter: Option) -> @handler { @mut HandlerT { err_count: 0, emit: emit } as @handler } -#[deriving_eq] +#[deriving(Eq)] pub enum level { fatal, error, diff --git a/src/libsyntax/ext/auto_encode.rs b/src/libsyntax/ext/auto_encode.rs index 294174dc8f9b3..54ca5dc0d72f7 100644 --- a/src/libsyntax/ext/auto_encode.rs +++ b/src/libsyntax/ext/auto_encode.rs @@ -32,7 +32,7 @@ impl Encodable for Node { } impl Decodable for node_id { - static fn decode(d: &D) -> Node { + fn decode(d: &D) -> Node { do d.read_struct("Node", 1) { Node { id: d.read_field(~"x", 0, || decode(d)) @@ -66,7 +66,7 @@ would yield functions like: D: Decoder, T: Decodable > spanned: Decodable { - static fn decode(d: &D) -> spanned { + fn decode(d: &D) -> spanned { do d.read_rec { { node: d.read_field(~"node", 0, || decode(d)), @@ -1202,10 +1202,9 @@ fn mk_enum_deser_body( mod test { use std::serialize::Encodable; use std::serialize::Encoder; - use util::testing::*; // just adding the ones I want to test, for now: - #[deriving_eq] + #[deriving(Eq)] pub enum call { CallToEmitEnum(~str), CallToEmitEnumVariant(~str, uint, uint), @@ -1321,7 +1320,7 @@ mod test { } #[test] fn encode_enum_test () { - check_equal (to_call_log(Book(34,44)), + assert_eq!(to_call_log(Book(34,44)), ~[CallToEmitEnum (~"Written"), CallToEmitEnumVariant (~"Book",0,2), CallToEmitEnumVariantArg (0), diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs index 652bc541a1f2e..d93a997213da2 100644 --- a/src/libsyntax/ext/base.rs +++ b/src/libsyntax/ext/base.rs @@ -1,4 +1,4 @@ -// Copyright 2012 The Rust Project Developers. See the COPYRIGHT +// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // @@ -153,13 +153,13 @@ pub fn syntax_expander_table() -> SyntaxEnv { ext::deriving::expand_meta_deriving))); syntax_expanders.insert(@~"deriving_eq", @SE(ItemDecorator( - ext::deriving::expand_deriving_eq))); + ext::deriving::eq::expand_deriving_obsolete))); syntax_expanders.insert(@~"deriving_iter_bytes", @SE(ItemDecorator( - ext::deriving::expand_deriving_iter_bytes))); + ext::deriving::iter_bytes::expand_deriving_obsolete))); syntax_expanders.insert(@~"deriving_clone", @SE(ItemDecorator( - ext::deriving::expand_deriving_clone))); + ext::deriving::clone::expand_deriving_obsolete))); // Quasi-quoting expanders syntax_expanders.insert(@~"quote_tokens", @@ -231,7 +231,7 @@ pub trait ext_ctxt { fn span_bug(@mut self, sp: span, msg: &str) -> !; fn bug(@mut self, msg: &str) -> !; fn next_id(@mut self) -> ast::node_id; - pure fn trace_macros(@mut self) -> bool; + fn trace_macros(@mut self) -> bool; fn set_trace_macros(@mut self, x: bool); /* for unhygienic identifier transformation */ fn str_of(@mut self, id: ast::ident) -> ~str; @@ -310,7 +310,7 @@ pub fn mk_ctxt(parse_sess: @mut parse::ParseSess, +cfg: ast::crate_cfg) fn next_id(@mut self) -> ast::node_id { return parse::next_node_id(self.parse_sess); } - pure fn trace_macros(@mut self) -> bool { + fn trace_macros(@mut self) -> bool { self.trace_mac } fn set_trace_macros(@mut self, x: bool) { @@ -439,7 +439,7 @@ pub enum MapChain { impl MapChain{ // Constructor. I don't think we need a zero-arg one. - static fn new(+init: ~LinearMap) -> @mut MapChain { + fn new(+init: ~LinearMap) -> @mut MapChain { @mut BaseMapChain(init) } @@ -464,7 +464,7 @@ impl MapChain{ // traits just don't work anywhere...? //pub impl Map for MapChain { - pure fn contains_key (&self, key: &K) -> bool { + fn contains_key (&self, key: &K) -> bool { match *self { BaseMapChain (ref map) => map.contains_key(key), ConsMapChain (ref map,ref rest) => @@ -475,11 +475,11 @@ impl MapChain{ // should each_key and each_value operate on shadowed // names? I think not. // delaying implementing this.... - pure fn each_key (&self, _f: &fn (&K)->bool) { + fn each_key (&self, _f: &fn (&K)->bool) { fail!(~"unimplemented 2013-02-15T10:01"); } - pure fn each_value (&self, _f: &fn (&V) -> bool) { + fn each_value (&self, _f: &fn (&V) -> bool) { fail!(~"unimplemented 2013-02-15T10:02"); } @@ -509,7 +509,6 @@ impl MapChain{ #[cfg(test)] mod test { use super::MapChain; - use util::testing::check_equal; use core::hashmap::linear::LinearMap; #[test] fn testenv () { @@ -517,23 +516,23 @@ mod test { a.insert (@~"abc",@15); let m = MapChain::new(~a); m.insert (@~"def",@16); - // FIXME: #4492 (ICE) check_equal(m.find(&@~"abc"),Some(@15)); - // .... check_equal(m.find(&@~"def"),Some(@16)); - check_equal(*(m.find(&@~"abc").get()),15); - check_equal(*(m.find(&@~"def").get()),16); + // FIXME: #4492 (ICE) assert_eq!(m.find(&@~"abc"),Some(@15)); + // .... assert_eq!(m.find(&@~"def"),Some(@16)); + assert_eq!(*(m.find(&@~"abc").get()),15); + assert_eq!(*(m.find(&@~"def").get()),16); let n = m.push_frame(); // old bindings are still present: - check_equal(*(n.find(&@~"abc").get()),15); - check_equal(*(n.find(&@~"def").get()),16); + assert_eq!(*(n.find(&@~"abc").get()),15); + assert_eq!(*(n.find(&@~"def").get()),16); n.insert (@~"def",@17); // n shows the new binding - check_equal(*(n.find(&@~"abc").get()),15); - check_equal(*(n.find(&@~"def").get()),17); + assert_eq!(*(n.find(&@~"abc").get()),15); + assert_eq!(*(n.find(&@~"def").get()),17); // ... but m still has the old ones - // FIXME: #4492: check_equal(m.find(&@~"abc"),Some(@15)); - // FIXME: #4492: check_equal(m.find(&@~"def"),Some(@16)); - check_equal(*(m.find(&@~"abc").get()),15); - check_equal(*(m.find(&@~"def").get()),16); + // FIXME: #4492: assert_eq!(m.find(&@~"abc"),Some(@15)); + // FIXME: #4492: assert_eq!(m.find(&@~"def"),Some(@16)); + assert_eq!(*(m.find(&@~"abc").get()),15); + assert_eq!(*(m.find(&@~"def").get()),16); } } diff --git a/src/libsyntax/ext/build.rs b/src/libsyntax/ext/build.rs index 18c7cd3f86138..c2f4cbf3db246 100644 --- a/src/libsyntax/ext/build.rs +++ b/src/libsyntax/ext/build.rs @@ -108,6 +108,9 @@ pub fn mk_access(cx: @ext_ctxt, sp: span, +p: ~[ast::ident], m: ast::ident) pub 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)); } +pub fn mk_mut_addr_of(cx: @ext_ctxt, sp: span, e: @ast::expr) -> @ast::expr { + return mk_expr(cx, sp, ast::expr_addr_of(ast::m_mutbl, e)); +} pub 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, ast::NoSugar)) diff --git a/src/libsyntax/ext/deriving.rs b/src/libsyntax/ext/deriving.rs deleted file mode 100644 index a6165e50c8545..0000000000000 --- a/src/libsyntax/ext/deriving.rs +++ /dev/null @@ -1,1267 +0,0 @@ -// Copyright 2012 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -/// The compiler code necessary to implement the #[deriving_eq] and -/// #[deriving_iter_bytes] extensions. - -use core::prelude::*; - -use ast; -use ast::{TraitTyParamBound, Ty, and, bind_by_ref, binop, deref, enum_def}; -use ast::{enum_variant_kind, expr, expr_match, ident, impure_fn, item, item_}; -use ast::{item_enum, item_impl, item_struct, Generics}; -use ast::{m_imm, meta_item, method}; -use ast::{named_field, or, pat, pat_ident, pat_wild, public, pure_fn}; -use ast::{stmt, struct_def, struct_variant_kind}; -use ast::{sty_by_ref, sty_region, tuple_variant_kind, ty_nil, TyParam}; -use ast::{TyParamBound, ty_path, ty_rptr, unnamed_field, variant}; -use ext::base::ext_ctxt; -use ext::build; -use codemap::{span, spanned}; -use parse::token::special_idents::clownshoes_extensions; -use ast_util; -use opt_vec; - -use core::uint; - -enum Junction { - Conjunction, - Disjunction, -} - -pub impl Junction { - fn to_binop(self) -> binop { - match self { - Conjunction => and, - Disjunction => or, - } - } -} - -type ExpandDerivingStructDefFn = &'self fn(@ext_ctxt, - span, - x: &struct_def, - ident, - y: &Generics) -> @item; -type ExpandDerivingEnumDefFn = &'self fn(@ext_ctxt, - span, - x: &enum_def, - ident, - y: &Generics) -> @item; - -pub fn expand_meta_deriving(cx: @ext_ctxt, - _span: span, - mitem: @meta_item, - in_items: ~[@item]) - -> ~[@item] { - use ast::{meta_list, meta_name_value, meta_word}; - - match mitem.node { - meta_name_value(_, l) => { - cx.span_err(l.span, ~"unexpected value in `deriving`"); - in_items - } - meta_word(_) | meta_list(_, []) => { - cx.span_warn(mitem.span, ~"empty trait list in `deriving`"); - in_items - } - meta_list(_, titems) => { - do titems.foldr(in_items) |&titem, in_items| { - match titem.node { - meta_name_value(tname, _) | - meta_list(tname, _) | - meta_word(tname) => { - match *tname { - ~"Clone" => expand_deriving_clone(cx, - titem.span, titem, in_items), - ~"Eq" => expand_deriving_eq(cx, titem.span, - titem, in_items), - ~"IterBytes" => expand_deriving_iter_bytes(cx, - titem.span, titem, in_items), - tname => { - cx.span_err(titem.span, fmt!("unknown \ - `deriving` trait: `%s`", tname)); - in_items - } - } - } - } - } - } - } -} - -pub fn expand_deriving_eq(cx: @ext_ctxt, - span: span, - _mitem: @meta_item, - in_items: ~[@item]) - -> ~[@item] { - expand_deriving(cx, - span, - in_items, - expand_deriving_eq_struct_def, - expand_deriving_eq_enum_def) -} - -pub fn expand_deriving_iter_bytes(cx: @ext_ctxt, - span: span, - _mitem: @meta_item, - in_items: ~[@item]) - -> ~[@item] { - expand_deriving(cx, - span, - in_items, - expand_deriving_iter_bytes_struct_def, - expand_deriving_iter_bytes_enum_def) -} - -pub fn expand_deriving_clone(cx: @ext_ctxt, - span: span, - _: @meta_item, - in_items: ~[@item]) - -> ~[@item] { - expand_deriving(cx, - span, - in_items, - expand_deriving_clone_struct_def, - expand_deriving_clone_enum_def) -} - -fn expand_deriving(cx: @ext_ctxt, - span: span, - in_items: ~[@item], - expand_deriving_struct_def: ExpandDerivingStructDefFn, - expand_deriving_enum_def: ExpandDerivingEnumDefFn) - -> ~[@item] { - let mut result = ~[]; - for in_items.each |item| { - result.push(copy *item); - match item.node { - item_struct(struct_def, ref generics) => { - result.push(expand_deriving_struct_def(cx, - span, - struct_def, - item.ident, - generics)); - } - item_enum(ref enum_definition, ref generics) => { - result.push(expand_deriving_enum_def(cx, - span, - enum_definition, - item.ident, - generics)); - } - _ => () - } - } - result -} - -fn create_impl_item(cx: @ext_ctxt, span: span, +item: item_) -> @item { - @ast::item { - ident: clownshoes_extensions, - attrs: ~[], - id: cx.next_id(), - node: item, - vis: public, - span: span, - } -} - -/// Creates a method from the given expression, the signature of which -/// conforms to the `eq` or `ne` method. -fn create_eq_method(cx: @ext_ctxt, - span: span, - method_ident: ident, - type_ident: ident, - generics: &Generics, - body: @expr) - -> @method { - // Create the type of the `other` parameter. - let arg_path_type = create_self_type_with_params(cx, - span, - type_ident, - generics); - let arg_type = ty_rptr( - None, - ast::mt { ty: arg_path_type, mutbl: m_imm } - ); - let arg_type = @ast::Ty { - id: cx.next_id(), - node: arg_type, - span: span, - }; - - // Create the `other` parameter. - let other_ident = cx.ident_of(~"__other"); - let arg = build::mk_arg(cx, span, other_ident, arg_type); - - // Create the type of the return value. - let bool_ident = cx.ident_of(~"bool"); - let output_type = build::mk_raw_path(span, ~[ bool_ident ]); - let output_type = ty_path(output_type, cx.next_id()); - let output_type = @ast::Ty { - id: cx.next_id(), - node: output_type, - span: span, - }; - - // Create the function declaration. - let fn_decl = build::mk_fn_decl(~[ arg ], output_type); - - // Create the body block. - let body_block = build::mk_simple_block(cx, span, body); - - // Create the method. - let self_ty = spanned { node: sty_region(None, m_imm), span: span }; - @ast::method { - ident: method_ident, - attrs: ~[], - generics: ast_util::empty_generics(), - self_ty: self_ty, - purity: impure_fn, - decl: fn_decl, - body: body_block, - id: cx.next_id(), - span: span, - self_id: cx.next_id(), - vis: public - } -} - -fn create_self_type_with_params(cx: @ext_ctxt, - span: span, - type_ident: ident, - generics: &Generics) - -> @Ty { - // Create the type parameters on the `self` path. - let mut self_ty_params = ~[]; - for generics.ty_params.each |ty_param| { - let self_ty_param = build::mk_simple_ty_path(cx, - span, - ty_param.ident); - self_ty_params.push(self_ty_param); - } - - // Create the type of `self`. - let self_type = build::mk_raw_path_(span, - ~[ type_ident ], - self_ty_params); - let self_type = ty_path(self_type, cx.next_id()); - @ast::Ty { id: cx.next_id(), node: self_type, span: span } -} - -fn create_derived_impl(cx: @ext_ctxt, - span: span, - type_ident: ident, - generics: &Generics, - methods: &[@method], - trait_path: &[ident]) - -> @item { - /*! - * - * Given that we are deriving a trait `Tr` for a type `T<'a, ..., - * 'z, A, ..., Z>`, creates an impl like: - * - * impl<'a, ..., 'z, A:Tr, ..., Z: Tr> Tr for T { ... } - * - * FIXME(#5090): Remove code duplication between this and the - * code in auto_encode.rs - */ - - // Copy the lifetimes - let impl_lifetimes = generics.lifetimes.map(|l| { - build::mk_lifetime(cx, l.span, l.ident) - }); - - // Create the type parameters. - let impl_ty_params = generics.ty_params.map(|ty_param| { - let bound = build::mk_ty_path_global(cx, - span, - trait_path.map(|x| *x)); - let bounds = @opt_vec::with(TraitTyParamBound(bound)); - build::mk_ty_param(cx, ty_param.ident, bounds) - }); - - // Create the reference to the trait. - let trait_path = ast::path { - span: span, - global: true, - idents: trait_path.map(|x| *x), - rp: None, - types: ~[] - }; - let trait_path = @trait_path; - let trait_ref = ast::trait_ref { - path: trait_path, - ref_id: cx.next_id() - }; - let trait_ref = @trait_ref; - - // Create the type of `self`. - let self_type = create_self_type_with_params(cx, - span, - type_ident, - generics); - - // Create the impl item. - let impl_item = item_impl(Generics {lifetimes: impl_lifetimes, - ty_params: impl_ty_params}, - Some(trait_ref), - self_type, - methods.map(|x| *x)); - return create_impl_item(cx, span, impl_item); -} - -fn create_derived_eq_impl(cx: @ext_ctxt, - span: span, - type_ident: ident, - generics: &Generics, - eq_method: @method, - ne_method: @method) - -> @item { - let methods = [ eq_method, ne_method ]; - let trait_path = [ - cx.ident_of(~"core"), - cx.ident_of(~"cmp"), - cx.ident_of(~"Eq") - ]; - create_derived_impl(cx, span, type_ident, generics, methods, trait_path) -} - -fn create_derived_iter_bytes_impl(cx: @ext_ctxt, - span: span, - type_ident: ident, - generics: &Generics, - method: @method) - -> @item { - let methods = [ method ]; - let trait_path = [ - cx.ident_of(~"core"), - cx.ident_of(~"to_bytes"), - cx.ident_of(~"IterBytes") - ]; - create_derived_impl(cx, span, type_ident, generics, methods, trait_path) -} - -fn create_derived_clone_impl(cx: @ext_ctxt, - span: span, - type_ident: ident, - generics: &Generics, - method: @method) - -> @item { - let methods = [ method ]; - let trait_path = [ - cx.ident_of(~"core"), - cx.ident_of(~"clone"), - cx.ident_of(~"Clone"), - ]; - create_derived_impl(cx, span, type_ident, generics, methods, trait_path) -} - -// Creates a method from the given set of statements conforming to the -// signature of the `iter_bytes` method. -fn create_iter_bytes_method(cx: @ext_ctxt, - span: span, - +statements: ~[@stmt]) - -> @method { - // Create the `lsb0` parameter. - let bool_ident = cx.ident_of(~"bool"); - let lsb0_arg_type = build::mk_simple_ty_path(cx, span, bool_ident); - let lsb0_ident = cx.ident_of(~"__lsb0"); - let lsb0_arg = build::mk_arg(cx, span, lsb0_ident, lsb0_arg_type); - - // Create the `f` parameter. - let core_ident = cx.ident_of(~"core"); - let to_bytes_ident = cx.ident_of(~"to_bytes"); - let cb_ident = cx.ident_of(~"Cb"); - let core_to_bytes_cb_ident = ~[ core_ident, to_bytes_ident, cb_ident ]; - let f_arg_type = build::mk_ty_path(cx, span, core_to_bytes_cb_ident); - let f_ident = cx.ident_of(~"__f"); - let f_arg = build::mk_arg(cx, span, f_ident, f_arg_type); - - // Create the type of the return value. - let output_type = @ast::Ty { id: cx.next_id(), node: ty_nil, span: span }; - - // Create the function declaration. - let inputs = ~[ lsb0_arg, f_arg ]; - let fn_decl = build::mk_fn_decl(inputs, output_type); - - // Create the body block. - let body_block = build::mk_block_(cx, span, statements); - - // Create the method. - let self_ty = spanned { node: sty_region(None, m_imm), span: span }; - let method_ident = cx.ident_of(~"iter_bytes"); - @ast::method { - ident: method_ident, - attrs: ~[], - generics: ast_util::empty_generics(), - self_ty: self_ty, - purity: impure_fn, - decl: fn_decl, - body: body_block, - id: cx.next_id(), - span: span, - self_id: cx.next_id(), - vis: public - } -} - -// Creates a method from the given expression conforming to the signature of -// the `clone` method. -fn create_clone_method(cx: @ext_ctxt, - span: span, - +type_ident: ast::ident, - generics: &Generics, - expr: @ast::expr) - -> @method { - // Create the type parameters of the return value. - let mut output_ty_params = ~[]; - for generics.ty_params.each |ty_param| { - let path = build::mk_ty_path(cx, span, ~[ ty_param.ident ]); - output_ty_params.push(path); - } - - // Create the type of the return value. - let output_type_path = build::mk_raw_path_(span, - ~[ type_ident ], - output_ty_params); - let output_type = ast::ty_path(output_type_path, cx.next_id()); - let output_type = @ast::Ty { - id: cx.next_id(), - node: output_type, - span: span - }; - - // Create the function declaration. - let fn_decl = build::mk_fn_decl(~[], output_type); - - // Create the body block. - let body_block = build::mk_simple_block(cx, span, expr); - - // Create the self type and method identifier. - let self_ty = spanned { node: sty_region(None, m_imm), span: span }; - let method_ident = cx.ident_of(~"clone"); - - // Create the method. - @ast::method { - ident: method_ident, - attrs: ~[], - generics: ast_util::empty_generics(), - self_ty: self_ty, - purity: impure_fn, - decl: fn_decl, - body: body_block, - id: cx.next_id(), - span: span, - self_id: cx.next_id(), - vis: public, - } -} - -fn create_subpatterns(cx: @ext_ctxt, - span: span, - prefix: ~str, - n: uint) - -> ~[@pat] { - let mut subpats = ~[]; - for uint::range(0, n) |_i| { - // Create the subidentifier. - let index = subpats.len().to_str(); - let ident = cx.ident_of(prefix + index); - - // Create the subpattern. - let subpath = build::mk_raw_path(span, ~[ ident ]); - let subpat = pat_ident(bind_by_ref(m_imm), subpath, None); - let subpat = build::mk_pat(cx, span, subpat); - subpats.push(subpat); - } - return subpats; -} - -fn is_struct_tuple(struct_def: &struct_def) -> bool { - struct_def.fields.len() > 0 && struct_def.fields.all(|f| { - match f.node.kind { - named_field(*) => false, - unnamed_field => true - } - }) -} - -fn create_enum_variant_pattern(cx: @ext_ctxt, - span: span, - variant: &variant, - prefix: ~str) - -> @pat { - let variant_ident = variant.node.name; - match variant.node.kind { - tuple_variant_kind(ref variant_args) => { - if variant_args.len() == 0 { - return build::mk_pat_ident_with_binding_mode( - cx, span, variant_ident, ast::bind_infer); - } - - let matching_path = build::mk_raw_path(span, ~[ variant_ident ]); - let subpats = create_subpatterns(cx, - span, - prefix, - variant_args.len()); - - return build::mk_pat_enum(cx, span, matching_path, subpats); - } - struct_variant_kind(struct_def) => { - let matching_path = build::mk_raw_path(span, ~[ variant_ident ]); - let subpats = create_subpatterns(cx, - span, - prefix, - struct_def.fields.len()); - - let field_pats = do struct_def.fields.mapi |i, struct_field| { - let ident = match struct_field.node.kind { - named_field(ident, _, _) => ident, - unnamed_field => { - cx.span_bug(span, ~"unexpected unnamed field"); - } - }; - ast::field_pat { ident: ident, pat: subpats[i] } - }; - - build::mk_pat_struct(cx, span, matching_path, field_pats) - } - enum_variant_kind(*) => { - cx.span_unimpl(span, ~"enum variants for `deriving`"); - } - } -} - -fn call_substructure_eq_method(cx: @ext_ctxt, - span: span, - self_field: @expr, - other_field_ref: @expr, - method_ident: ident, - junction: Junction, - chain_expr: &mut Option<@expr>) { - // Call the substructure method. - let self_method = build::mk_access_(cx, span, self_field, method_ident); - let self_call = build::mk_call_(cx, - span, - self_method, - ~[ other_field_ref ]); - - // Connect to the outer expression if necessary. - *chain_expr = match *chain_expr { - None => Some(self_call), - Some(copy old_outer_expr) => { - let binop = junction.to_binop(); - let chain_expr = build::mk_binary(cx, - span, - binop, - old_outer_expr, - self_call); - Some(chain_expr) - } - }; -} - -fn finish_eq_chain_expr(cx: @ext_ctxt, - span: span, - chain_expr: Option<@expr>, - junction: Junction) - -> @expr { - match chain_expr { - None => { - match junction { - Conjunction => build::mk_bool(cx, span, true), - Disjunction => build::mk_bool(cx, span, false), - } - } - Some(ref outer_expr) => *outer_expr, - } -} - -fn call_substructure_iter_bytes_method(cx: @ext_ctxt, - span: span, - self_field: @expr) - -> @stmt { - // Gather up the parameters we want to chain along. - let lsb0_ident = cx.ident_of(~"__lsb0"); - let f_ident = cx.ident_of(~"__f"); - let lsb0_expr = build::mk_path(cx, span, ~[ lsb0_ident ]); - let f_expr = build::mk_path(cx, span, ~[ f_ident ]); - - // Call the substructure method. - let iter_bytes_ident = cx.ident_of(~"iter_bytes"); - let self_method = build::mk_access_(cx, - span, - self_field, - iter_bytes_ident); - let self_call = build::mk_call_(cx, - span, - self_method, - ~[ lsb0_expr, f_expr ]); - - // Create a statement out of this expression. - build::mk_stmt(cx, span, self_call) -} - -fn call_substructure_clone_method(cx: @ext_ctxt, - span: span, - self_field: @expr) - -> @expr { - // Call the substructure method. - let clone_ident = cx.ident_of(~"clone"); - let self_method = build::mk_access_(cx, span, self_field, clone_ident); - build::mk_call_(cx, span, self_method, ~[]) -} - -fn variant_arg_count(cx: @ext_ctxt, span: span, variant: &variant) -> uint { - match variant.node.kind { - tuple_variant_kind(ref args) => args.len(), - struct_variant_kind(ref struct_def) => struct_def.fields.len(), - enum_variant_kind(*) => { - cx.span_bug(span, ~"variant_arg_count: enum variants deprecated") - } - } -} - -fn expand_deriving_eq_struct_def(cx: @ext_ctxt, - span: span, - struct_def: &struct_def, - type_ident: ident, - generics: &Generics) - -> @item { - // Create the methods. - let eq_ident = cx.ident_of(~"eq"); - let ne_ident = cx.ident_of(~"ne"); - - let derive_struct_fn = if is_struct_tuple(struct_def) { - expand_deriving_eq_struct_tuple_method - } else { - expand_deriving_eq_struct_method - }; - - let eq_method = derive_struct_fn(cx, - span, - struct_def, - eq_ident, - type_ident, - generics, - Conjunction); - let ne_method = derive_struct_fn(cx, - span, - struct_def, - ne_ident, - type_ident, - generics, - Disjunction); - - // Create the implementation. - return create_derived_eq_impl(cx, - span, - type_ident, - generics, - eq_method, - ne_method); -} - -fn expand_deriving_eq_enum_def(cx: @ext_ctxt, - span: span, - enum_definition: &enum_def, - type_ident: ident, - generics: &Generics) - -> @item { - // Create the methods. - let eq_ident = cx.ident_of(~"eq"); - let ne_ident = cx.ident_of(~"ne"); - let eq_method = expand_deriving_eq_enum_method(cx, - span, - enum_definition, - eq_ident, - type_ident, - generics, - Conjunction); - let ne_method = expand_deriving_eq_enum_method(cx, - span, - enum_definition, - ne_ident, - type_ident, - generics, - Disjunction); - - // Create the implementation. - return create_derived_eq_impl(cx, - span, - type_ident, - generics, - eq_method, - ne_method); -} - -fn expand_deriving_iter_bytes_struct_def(cx: @ext_ctxt, - span: span, - struct_def: &struct_def, - type_ident: ident, - generics: &Generics) - -> @item { - // Create the method. - let method = expand_deriving_iter_bytes_struct_method(cx, - span, - struct_def); - - // Create the implementation. - return create_derived_iter_bytes_impl(cx, - span, - type_ident, - generics, - method); -} - -fn expand_deriving_iter_bytes_enum_def(cx: @ext_ctxt, - span: span, - enum_definition: &enum_def, - type_ident: ident, - generics: &Generics) - -> @item { - // Create the method. - let method = expand_deriving_iter_bytes_enum_method(cx, - span, - enum_definition); - - // Create the implementation. - return create_derived_iter_bytes_impl(cx, - span, - type_ident, - generics, - method); -} - -fn expand_deriving_clone_struct_def(cx: @ext_ctxt, - span: span, - struct_def: &struct_def, - type_ident: ident, - generics: &Generics) - -> @item { - // Create the method. - let method = if !is_struct_tuple(struct_def) { - expand_deriving_clone_struct_method(cx, - span, - struct_def, - type_ident, - generics) - } else { - expand_deriving_clone_tuple_struct_method(cx, - span, - struct_def, - type_ident, - generics) - }; - - // Create the implementation. - create_derived_clone_impl(cx, span, type_ident, generics, method) -} - -fn expand_deriving_clone_enum_def(cx: @ext_ctxt, - span: span, - enum_definition: &enum_def, - type_ident: ident, - generics: &Generics) - -> @item { - // Create the method. - let method = expand_deriving_clone_enum_method(cx, - span, - enum_definition, - type_ident, - generics); - - // Create the implementation. - create_derived_clone_impl(cx, span, type_ident, generics, method) -} - -fn expand_deriving_eq_struct_method(cx: @ext_ctxt, - span: span, - struct_def: &struct_def, - method_ident: ident, - type_ident: ident, - generics: &Generics, - junction: Junction) - -> @method { - let self_ident = cx.ident_of(~"self"); - let other_ident = cx.ident_of(~"__other"); - - // Create the body of the method. - let mut outer_expr = None; - for struct_def.fields.each |struct_field| { - match struct_field.node.kind { - named_field(ident, _, _) => { - // Create the accessor for the other field. - let other_field = build::mk_access(cx, - span, - ~[ other_ident ], - ident); - let other_field_ref = build::mk_addr_of(cx, - span, - other_field); - - // Create the accessor for this field. - let self_field = build::mk_access(cx, - span, - ~[ self_ident ], - ident); - - // Call the substructure method. - call_substructure_eq_method(cx, - span, - self_field, - other_field_ref, - method_ident, - junction, - &mut outer_expr); - } - unnamed_field => { - cx.span_unimpl(span, ~"unnamed fields with `deriving_eq`"); - } - } - } - - // Create the method itself. - let body = finish_eq_chain_expr(cx, span, outer_expr, junction); - return create_eq_method(cx, - span, - method_ident, - type_ident, - generics, - body); -} - -fn expand_deriving_iter_bytes_struct_method(cx: @ext_ctxt, - span: span, - struct_def: &struct_def) - -> @method { - let self_ident = cx.ident_of(~"self"); - - // Create the body of the method. - let mut statements = ~[]; - for struct_def.fields.each |struct_field| { - match struct_field.node.kind { - named_field(ident, _, _) => { - // Create the accessor for this field. - let self_field = build::mk_access(cx, - span, - ~[ self_ident ], - ident); - - // Call the substructure method. - let stmt = call_substructure_iter_bytes_method(cx, - span, - self_field); - statements.push(stmt); - } - unnamed_field => { - cx.span_unimpl(span, - ~"unnamed fields with `deriving_iter_bytes`"); - } - } - } - - // Create the method itself. - return create_iter_bytes_method(cx, span, statements); -} - -fn expand_deriving_clone_struct_method(cx: @ext_ctxt, - span: span, - struct_def: &struct_def, - type_ident: ident, - generics: &Generics) - -> @method { - let self_ident = cx.ident_of(~"self"); - - // Create the new fields. - let mut fields = ~[]; - for struct_def.fields.each |struct_field| { - match struct_field.node.kind { - named_field(ident, _, _) => { - // Create the accessor for this field. - let self_field = build::mk_access(cx, - span, - ~[ self_ident ], - ident); - - // Call the substructure method. - let call = call_substructure_clone_method(cx, - span, - self_field); - - let field = build::Field { ident: ident, ex: call }; - fields.push(field); - } - unnamed_field => { - cx.span_bug(span, - ~"unnamed fields in \ - expand_deriving_clone_struct_method"); - } - } - } - - // Create the struct literal. - let struct_literal = build::mk_struct_e(cx, - span, - ~[ type_ident ], - fields); - create_clone_method(cx, span, type_ident, generics, struct_literal) -} - -fn expand_deriving_clone_tuple_struct_method(cx: @ext_ctxt, - span: span, - struct_def: &struct_def, - type_ident: ident, - generics: &Generics) - -> @method { - // Create the pattern for the match. - let matching_path = build::mk_raw_path(span, ~[ type_ident ]); - let field_count = struct_def.fields.len(); - let subpats = create_subpatterns(cx, span, ~"__self", field_count); - let pat = build::mk_pat_enum(cx, span, matching_path, subpats); - - // Create the new fields. - let mut subcalls = ~[]; - for uint::range(0, struct_def.fields.len()) |i| { - // Create the expression for this field. - let field_ident = cx.ident_of(~"__self" + i.to_str()); - let field = build::mk_path(cx, span, ~[ field_ident ]); - - // Call the substructure method. - let subcall = call_substructure_clone_method(cx, span, field); - subcalls.push(subcall); - } - - // Create the call to the struct constructor. - let call = build::mk_call(cx, span, ~[ type_ident ], subcalls); - - // Create the pattern body. - let match_body_block = build::mk_simple_block(cx, span, call); - - // Create the arm. - let arm = ast::arm { - pats: ~[ pat ], - guard: None, - body: match_body_block - }; - - // Create the method body. - let self_match_expr = expand_enum_or_struct_match(cx, span, ~[ arm ]); - - // Create the method. - create_clone_method(cx, span, type_ident, generics, self_match_expr) -} - -fn expand_deriving_eq_enum_method(cx: @ext_ctxt, - span: span, - enum_definition: &enum_def, - method_ident: ident, - type_ident: ident, - generics: &Generics, - junction: Junction) - -> @method { - let self_ident = cx.ident_of(~"self"); - let other_ident = cx.ident_of(~"__other"); - - let is_eq; - match junction { - Conjunction => is_eq = true, - Disjunction => is_eq = false, - } - - // Create the arms of the self match in the method body. - let mut self_arms = ~[]; - for enum_definition.variants.each |self_variant| { - let mut other_arms = ~[]; - - // Create the matching pattern. - let matching_pat = create_enum_variant_pattern(cx, - span, - self_variant, - ~"__other"); - - // Create the matching pattern body. - let mut matching_body_expr = None; - for uint::range(0, variant_arg_count(cx, span, self_variant)) |i| { - // Create the expression for the other field. - let other_field_ident = cx.ident_of(~"__other" + i.to_str()); - let other_field = build::mk_path(cx, - span, - ~[ other_field_ident ]); - - // Create the expression for this field. - let self_field_ident = cx.ident_of(~"__self" + i.to_str()); - let self_field = build::mk_path(cx, span, ~[ self_field_ident ]); - - // Call the substructure method. - call_substructure_eq_method(cx, - span, - self_field, - other_field, - method_ident, - junction, - &mut matching_body_expr); - } - - let matching_body_expr = finish_eq_chain_expr(cx, - span, - matching_body_expr, - junction); - let matching_body_block = build::mk_simple_block(cx, - span, - matching_body_expr); - - // Create the matching arm. - let matching_arm = ast::arm { - pats: ~[ matching_pat ], - guard: None, - body: matching_body_block - }; - other_arms.push(matching_arm); - - // Maybe generate a non-matching case. If there is only one - // variant then there will always be a match. - if enum_definition.variants.len() > 1 { - // Create the nonmatching pattern. - let nonmatching_pat = @ast::pat { - id: cx.next_id(), - node: pat_wild, - span: span - }; - - // Create the nonmatching pattern body. - let nonmatching_expr = build::mk_bool(cx, span, !is_eq); - let nonmatching_body_block = - build::mk_simple_block(cx, - span, - nonmatching_expr); - - // Create the nonmatching arm. - let nonmatching_arm = ast::arm { - pats: ~[ nonmatching_pat ], - guard: None, - body: nonmatching_body_block, - }; - other_arms.push(nonmatching_arm); - } - - // Create the self pattern. - let self_pat = create_enum_variant_pattern(cx, - span, - self_variant, - ~"__self"); - - // Create the self pattern body. - let other_expr = build::mk_path(cx, span, ~[ other_ident ]); - let other_expr = build::mk_unary(cx, span, deref, other_expr); - let other_match_expr = expr_match(other_expr, other_arms); - let other_match_expr = build::mk_expr(cx, - span, - other_match_expr); - let other_match_body_block = build::mk_simple_block(cx, - span, - other_match_expr); - - // Create the self arm. - let self_arm = ast::arm { - pats: ~[ self_pat ], - guard: None, - body: other_match_body_block, - }; - self_arms.push(self_arm); - } - - // Create the method body. - let self_expr = build::mk_path(cx, span, ~[ self_ident ]); - let self_expr = build::mk_unary(cx, span, deref, self_expr); - let self_match_expr = expr_match(self_expr, self_arms); - let self_match_expr = build::mk_expr(cx, span, self_match_expr); - - // Create the method. - return create_eq_method(cx, - span, - method_ident, - type_ident, - generics, - self_match_expr); -} - -fn expand_deriving_eq_struct_tuple_method(cx: @ext_ctxt, - span: span, - struct_def: &struct_def, - method_ident: ident, - type_ident: ident, - generics: &Generics, - junction: Junction) - -> @method { - let self_str = ~"self"; - let other_str = ~"__other"; - let type_path = build::mk_raw_path(span, ~[type_ident]); - let fields = copy struct_def.fields; - - // Create comparison expression, comparing each of the fields - let mut match_body = None; - for fields.eachi |i, _| { - let other_field_ident = cx.ident_of(other_str + i.to_str()); - let other_field = build::mk_path(cx, span, ~[ other_field_ident ]); - - let self_field_ident = cx.ident_of(self_str + i.to_str()); - let self_field = build::mk_path(cx, span, ~[ self_field_ident ]); - - call_substructure_eq_method(cx, span, self_field, other_field, - method_ident, junction, &mut match_body); - } - let match_body = finish_eq_chain_expr(cx, span, match_body, junction); - - // Create arm for the '__other' match, containing the comparison expr - let other_subpats = create_subpatterns(cx, span, other_str, fields.len()); - let other_arm = ast::arm { - pats: ~[ build::mk_pat_enum(cx, span, type_path, other_subpats) ], - guard: None, - body: build::mk_simple_block(cx, span, match_body), - }; - - // Create the match on '__other' - let other_expr = build::mk_path(cx, span, ~[ cx.ident_of(other_str) ]); - let other_expr = build::mk_unary(cx, span, deref, other_expr); - let other_match_expr = expr_match(other_expr, ~[other_arm]); - let other_match_expr = build::mk_expr(cx, span, other_match_expr); - - // Create arm for the 'self' match, which contains the '__other' match - let self_subpats = create_subpatterns(cx, span, self_str, fields.len()); - let self_arm = ast::arm { - pats: ~[build::mk_pat_enum(cx, span, type_path, self_subpats)], - guard: None, - body: build::mk_simple_block(cx, span, other_match_expr), - }; - - // Create the match on 'self' - let self_expr = build::mk_path(cx, span, ~[ cx.ident_of(self_str) ]); - let self_expr = build::mk_unary(cx, span, deref, self_expr); - let self_match_expr = expr_match(self_expr, ~[self_arm]); - let self_match_expr = build::mk_expr(cx, span, self_match_expr); - - create_eq_method(cx, span, method_ident, - type_ident, generics, self_match_expr) -} - -fn expand_enum_or_struct_match(cx: @ext_ctxt, - span: span, - arms: ~[ ast::arm ]) - -> @expr { - let self_ident = cx.ident_of(~"self"); - let self_expr = build::mk_path(cx, span, ~[ self_ident ]); - let self_expr = build::mk_unary(cx, span, deref, self_expr); - let self_match_expr = expr_match(self_expr, arms); - build::mk_expr(cx, span, self_match_expr) -} - -fn expand_deriving_iter_bytes_enum_method(cx: @ext_ctxt, - span: span, - enum_definition: &enum_def) - -> @method { - // Create the arms of the match in the method body. - let arms = do enum_definition.variants.mapi |i, variant| { - // Create the matching pattern. - let pat = create_enum_variant_pattern(cx, span, variant, ~"__self"); - - // Determine the discriminant. We will feed this value to the byte - // iteration function. - let discriminant; - match variant.node.disr_expr { - Some(copy disr_expr) => discriminant = disr_expr, - None => discriminant = build::mk_uint(cx, span, i), - } - - // Feed the discriminant to the byte iteration function. - let mut stmts = ~[]; - let discrim_stmt = call_substructure_iter_bytes_method(cx, - span, - discriminant); - stmts.push(discrim_stmt); - - // Feed each argument in this variant to the byte iteration function - // as well. - for uint::range(0, variant_arg_count(cx, span, variant)) |j| { - // Create the expression for this field. - let field_ident = cx.ident_of(~"__self" + j.to_str()); - let field = build::mk_path(cx, span, ~[ field_ident ]); - - // Call the substructure method. - let stmt = call_substructure_iter_bytes_method(cx, span, field); - stmts.push(stmt); - } - - // Create the pattern body. - let match_body_block = build::mk_block_(cx, span, stmts); - - // Create the arm. - ast::arm { - pats: ~[ pat ], - guard: None, - body: match_body_block, - } - }; - - // Create the method body. - let self_match_expr = expand_enum_or_struct_match(cx, span, arms); - let self_match_stmt = build::mk_stmt(cx, span, self_match_expr); - - // Create the method. - create_iter_bytes_method(cx, span, ~[ self_match_stmt ]) -} - -fn expand_deriving_clone_enum_method(cx: @ext_ctxt, - span: span, - enum_definition: &enum_def, - type_ident: ident, - generics: &Generics) - -> @method { - // Create the arms of the match in the method body. - let arms = do enum_definition.variants.map |variant| { - // Create the matching pattern. - let pat = create_enum_variant_pattern(cx, span, variant, ~"__self"); - - // Iterate over the variant arguments, creating the subcalls. - let mut subcalls = ~[]; - for uint::range(0, variant_arg_count(cx, span, variant)) |j| { - // Create the expression for this field. - let field_ident = cx.ident_of(~"__self" + j.to_str()); - let field = build::mk_path(cx, span, ~[ field_ident ]); - - // Call the substructure method. - let subcall = call_substructure_clone_method(cx, span, field); - subcalls.push(subcall); - } - - // Create the call to the enum variant (if necessary). - let call = if subcalls.len() > 0 { - build::mk_call(cx, span, ~[ variant.node.name ], subcalls) - } else { - build::mk_path(cx, span, ~[ variant.node.name ]) - }; - - // Create the pattern body. - let match_body_block = build::mk_simple_block(cx, span, call); - - // Create the arm. - ast::arm { pats: ~[ pat ], guard: None, body: match_body_block } - }; - - // Create the method body. - let self_match_expr = expand_enum_or_struct_match(cx, span, arms); - - // Create the method. - create_clone_method(cx, span, type_ident, generics, self_match_expr) -} - diff --git a/src/libsyntax/ext/deriving/clone.rs b/src/libsyntax/ext/deriving/clone.rs new file mode 100644 index 0000000000000..4ab83cb5f1e42 --- /dev/null +++ b/src/libsyntax/ext/deriving/clone.rs @@ -0,0 +1,298 @@ +// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +use core::prelude::*; + +use ast; +use ast::{TraitTyParamBound, Ty, and, bind_by_ref, binop, deref, enum_def}; +use ast::{enum_variant_kind, expr, expr_match, ident, impure_fn, item, item_}; +use ast::{item_enum, item_impl, item_struct, Generics}; +use ast::{m_imm, meta_item, method}; +use ast::{named_field, or, pat, pat_ident, pat_wild, public, pure_fn}; +use ast::{stmt, struct_def, struct_variant_kind}; +use ast::{sty_by_ref, sty_region, tuple_variant_kind, ty_nil, TyParam}; +use ast::{TyParamBound, ty_path, ty_rptr, unnamed_field, variant}; +use ext::base::ext_ctxt; +use ext::build; +use ext::deriving::*; +use codemap::{span, spanned}; +use ast_util; + +use core::uint; + +pub fn expand_deriving_clone(cx: @ext_ctxt, + span: span, + _: @meta_item, + in_items: ~[@item]) + -> ~[@item] { + expand_deriving(cx, + span, + in_items, + expand_deriving_clone_struct_def, + expand_deriving_clone_enum_def) +} + +pub fn expand_deriving_obsolete(cx: @ext_ctxt, + span: span, + _mitem: @meta_item, + in_items: ~[@item]) + -> ~[@item] { + cx.span_err(span, ~"`#[deriving_clone]` is obsolete; use `#[deriving(Clone)]` instead"); + in_items +} + +fn create_derived_clone_impl(cx: @ext_ctxt, + span: span, + type_ident: ident, + generics: &Generics, + method: @method) + -> @item { + let methods = [ method ]; + let trait_path = [ + cx.ident_of(~"core"), + cx.ident_of(~"clone"), + cx.ident_of(~"Clone"), + ]; + create_derived_impl(cx, span, type_ident, generics, methods, trait_path) +} +// Creates a method from the given expression conforming to the signature of +// the `clone` method. +fn create_clone_method(cx: @ext_ctxt, + span: span, + +type_ident: ast::ident, + generics: &Generics, + expr: @ast::expr) + -> @method { + // Create the type parameters of the return value. + let mut output_ty_params = ~[]; + for generics.ty_params.each |ty_param| { + let path = build::mk_ty_path(cx, span, ~[ ty_param.ident ]); + output_ty_params.push(path); + } + + // Create the type of the return value. + let output_type_path = build::mk_raw_path_(span, + ~[ type_ident ], + output_ty_params); + let output_type = ast::ty_path(output_type_path, cx.next_id()); + let output_type = @ast::Ty { + id: cx.next_id(), + node: output_type, + span: span + }; + + // Create the function declaration. + let fn_decl = build::mk_fn_decl(~[], output_type); + + // Create the body block. + let body_block = build::mk_simple_block(cx, span, expr); + + // Create the self type and method identifier. + let self_ty = spanned { node: sty_region(None, m_imm), span: span }; + let method_ident = cx.ident_of(~"clone"); + + // Create the method. + @ast::method { + ident: method_ident, + attrs: ~[], + generics: ast_util::empty_generics(), + self_ty: self_ty, + purity: impure_fn, + decl: fn_decl, + body: body_block, + id: cx.next_id(), + span: span, + self_id: cx.next_id(), + vis: public, + } +} + +fn call_substructure_clone_method(cx: @ext_ctxt, + span: span, + self_field: @expr) + -> @expr { + // Call the substructure method. + let clone_ident = cx.ident_of(~"clone"); + let self_method = build::mk_access_(cx, span, self_field, clone_ident); + build::mk_call_(cx, span, self_method, ~[]) +} + +fn expand_deriving_clone_struct_def(cx: @ext_ctxt, + span: span, + struct_def: &struct_def, + type_ident: ident, + generics: &Generics) + -> @item { + // Create the method. + let method = if !is_struct_tuple(struct_def) { + expand_deriving_clone_struct_method(cx, + span, + struct_def, + type_ident, + generics) + } else { + expand_deriving_clone_tuple_struct_method(cx, + span, + struct_def, + type_ident, + generics) + }; + + // Create the implementation. + create_derived_clone_impl(cx, span, type_ident, generics, method) +} + +fn expand_deriving_clone_enum_def(cx: @ext_ctxt, + span: span, + enum_definition: &enum_def, + type_ident: ident, + generics: &Generics) + -> @item { + // Create the method. + let method = expand_deriving_clone_enum_method(cx, + span, + enum_definition, + type_ident, + generics); + + // Create the implementation. + create_derived_clone_impl(cx, span, type_ident, generics, method) +} + +fn expand_deriving_clone_struct_method(cx: @ext_ctxt, + span: span, + struct_def: &struct_def, + type_ident: ident, + generics: &Generics) + -> @method { + let self_ident = cx.ident_of(~"self"); + + // Create the new fields. + let mut fields = ~[]; + for struct_def.fields.each |struct_field| { + match struct_field.node.kind { + named_field(ident, _, _) => { + // Create the accessor for this field. + let self_field = build::mk_access(cx, + span, + ~[ self_ident ], + ident); + + // Call the substructure method. + let call = call_substructure_clone_method(cx, + span, + self_field); + + let field = build::Field { ident: ident, ex: call }; + fields.push(field); + } + unnamed_field => { + cx.span_bug(span, + ~"unnamed fields in \ + expand_deriving_clone_struct_method"); + } + } + } + + // Create the struct literal. + let struct_literal = build::mk_struct_e(cx, + span, + ~[ type_ident ], + fields); + create_clone_method(cx, span, type_ident, generics, struct_literal) +} + +fn expand_deriving_clone_tuple_struct_method(cx: @ext_ctxt, + span: span, + struct_def: &struct_def, + type_ident: ident, + generics: &Generics) + -> @method { + // Create the pattern for the match. + let matching_path = build::mk_raw_path(span, ~[ type_ident ]); + let field_count = struct_def.fields.len(); + let subpats = create_subpatterns(cx, span, ~"__self", field_count); + let pat = build::mk_pat_enum(cx, span, matching_path, subpats); + + // Create the new fields. + let mut subcalls = ~[]; + for uint::range(0, struct_def.fields.len()) |i| { + // Create the expression for this field. + let field_ident = cx.ident_of(~"__self" + i.to_str()); + let field = build::mk_path(cx, span, ~[ field_ident ]); + + // Call the substructure method. + let subcall = call_substructure_clone_method(cx, span, field); + subcalls.push(subcall); + } + + // Create the call to the struct constructor. + let call = build::mk_call(cx, span, ~[ type_ident ], subcalls); + + // Create the pattern body. + let match_body_block = build::mk_simple_block(cx, span, call); + + // Create the arm. + let arm = ast::arm { + pats: ~[ pat ], + guard: None, + body: match_body_block + }; + + // Create the method body. + let self_match_expr = expand_enum_or_struct_match(cx, span, ~[ arm ]); + + // Create the method. + create_clone_method(cx, span, type_ident, generics, self_match_expr) +} + +fn expand_deriving_clone_enum_method(cx: @ext_ctxt, + span: span, + enum_definition: &enum_def, + type_ident: ident, + generics: &Generics) + -> @method { + // Create the arms of the match in the method body. + let arms = do enum_definition.variants.map |variant| { + // Create the matching pattern. + let pat = create_enum_variant_pattern(cx, span, variant, ~"__self"); + + // Iterate over the variant arguments, creating the subcalls. + let mut subcalls = ~[]; + for uint::range(0, variant_arg_count(cx, span, variant)) |j| { + // Create the expression for this field. + let field_ident = cx.ident_of(~"__self" + j.to_str()); + let field = build::mk_path(cx, span, ~[ field_ident ]); + + // Call the substructure method. + let subcall = call_substructure_clone_method(cx, span, field); + subcalls.push(subcall); + } + + // Create the call to the enum variant (if necessary). + let call = if subcalls.len() > 0 { + build::mk_call(cx, span, ~[ variant.node.name ], subcalls) + } else { + build::mk_path(cx, span, ~[ variant.node.name ]) + }; + + // Create the pattern body. + let match_body_block = build::mk_simple_block(cx, span, call); + + // Create the arm. + ast::arm { pats: ~[ pat ], guard: None, body: match_body_block } + }; + + // Create the method body. + let self_match_expr = expand_enum_or_struct_match(cx, span, arms); + + // Create the method. + create_clone_method(cx, span, type_ident, generics, self_match_expr) +} diff --git a/src/libsyntax/ext/deriving/eq.rs b/src/libsyntax/ext/deriving/eq.rs new file mode 100644 index 0000000000000..5e94134f70afe --- /dev/null +++ b/src/libsyntax/ext/deriving/eq.rs @@ -0,0 +1,507 @@ +// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +use core::prelude::*; + +use ast; +use ast::{TraitTyParamBound, Ty, and, bind_by_ref, binop, deref, enum_def}; +use ast::{enum_variant_kind, expr, expr_match, ident, impure_fn, item, item_}; +use ast::{item_enum, item_impl, item_struct, Generics}; +use ast::{m_imm, meta_item, method}; +use ast::{named_field, or, pat, pat_ident, pat_wild, public, pure_fn}; +use ast::{stmt, struct_def, struct_variant_kind}; +use ast::{sty_by_ref, sty_region, tuple_variant_kind, ty_nil, TyParam}; +use ast::{TyParamBound, ty_path, ty_rptr, unnamed_field, variant}; +use ext::base::ext_ctxt; +use ext::build; +use ext::deriving::*; +use codemap::{span, spanned}; +use ast_util; + +use core::uint; + +enum Junction { + Conjunction, + Disjunction, +} + +pub impl Junction { + fn to_binop(self) -> binop { + match self { + Conjunction => and, + Disjunction => or, + } + } +} + +pub fn expand_deriving_eq(cx: @ext_ctxt, + span: span, + _mitem: @meta_item, + in_items: ~[@item]) + -> ~[@item] { + expand_deriving(cx, + span, + in_items, + expand_deriving_eq_struct_def, + expand_deriving_eq_enum_def) +} + +pub fn expand_deriving_obsolete(cx: @ext_ctxt, + span: span, + _mitem: @meta_item, + in_items: ~[@item]) + -> ~[@item] { + cx.span_err(span, ~"`#[deriving_eq]` is obsolete; use `#[deriving(Eq)]` instead"); + in_items +} + +/// Creates a method from the given expression, the signature of which +/// conforms to the `eq` or `ne` method. +fn create_eq_method(cx: @ext_ctxt, + span: span, + method_ident: ident, + type_ident: ident, + generics: &Generics, + body: @expr) + -> @method { + // Create the type of the `other` parameter. + let arg_path_type = create_self_type_with_params(cx, + span, + type_ident, + generics); + let arg_type = ty_rptr( + None, + ast::mt { ty: arg_path_type, mutbl: m_imm } + ); + let arg_type = @ast::Ty { + id: cx.next_id(), + node: arg_type, + span: span, + }; + + // Create the `other` parameter. + let other_ident = cx.ident_of(~"__other"); + let arg = build::mk_arg(cx, span, other_ident, arg_type); + + // Create the type of the return value. + let bool_ident = cx.ident_of(~"bool"); + let output_type = build::mk_raw_path(span, ~[ bool_ident ]); + let output_type = ty_path(output_type, cx.next_id()); + let output_type = @ast::Ty { + id: cx.next_id(), + node: output_type, + span: span, + }; + + // Create the function declaration. + let fn_decl = build::mk_fn_decl(~[ arg ], output_type); + + // Create the body block. + let body_block = build::mk_simple_block(cx, span, body); + + // Create the method. + let self_ty = spanned { node: sty_region(None, m_imm), span: span }; + @ast::method { + ident: method_ident, + attrs: ~[], + generics: ast_util::empty_generics(), + self_ty: self_ty, + purity: impure_fn, + decl: fn_decl, + body: body_block, + id: cx.next_id(), + span: span, + self_id: cx.next_id(), + vis: public + } +} + +fn create_derived_eq_impl(cx: @ext_ctxt, + span: span, + type_ident: ident, + generics: &Generics, + eq_method: @method, + ne_method: @method) + -> @item { + let methods = [ eq_method, ne_method ]; + let trait_path = [ + cx.ident_of(~"core"), + cx.ident_of(~"cmp"), + cx.ident_of(~"Eq") + ]; + create_derived_impl(cx, span, type_ident, generics, methods, trait_path) +} + +fn call_substructure_eq_method(cx: @ext_ctxt, + span: span, + self_field: @expr, + other_field_ref: @expr, + method_ident: ident, + junction: Junction, + chain_expr: &mut Option<@expr>) { + // Call the substructure method. + let self_method = build::mk_access_(cx, span, self_field, method_ident); + let self_call = build::mk_call_(cx, + span, + self_method, + ~[ other_field_ref ]); + + // Connect to the outer expression if necessary. + *chain_expr = match *chain_expr { + None => Some(self_call), + Some(copy old_outer_expr) => { + let binop = junction.to_binop(); + let chain_expr = build::mk_binary(cx, + span, + binop, + old_outer_expr, + self_call); + Some(chain_expr) + } + }; +} + +fn finish_eq_chain_expr(cx: @ext_ctxt, + span: span, + chain_expr: Option<@expr>, + junction: Junction) + -> @expr { + match chain_expr { + None => { + match junction { + Conjunction => build::mk_bool(cx, span, true), + Disjunction => build::mk_bool(cx, span, false), + } + } + Some(ref outer_expr) => *outer_expr, + } +} + +fn expand_deriving_eq_struct_def(cx: @ext_ctxt, + span: span, + struct_def: &struct_def, + type_ident: ident, + generics: &Generics) + -> @item { + // Create the methods. + let eq_ident = cx.ident_of(~"eq"); + let ne_ident = cx.ident_of(~"ne"); + + let derive_struct_fn = if is_struct_tuple(struct_def) { + expand_deriving_eq_struct_tuple_method + } else { + expand_deriving_eq_struct_method + }; + + let eq_method = derive_struct_fn(cx, + span, + struct_def, + eq_ident, + type_ident, + generics, + Conjunction); + let ne_method = derive_struct_fn(cx, + span, + struct_def, + ne_ident, + type_ident, + generics, + Disjunction); + + // Create the implementation. + return create_derived_eq_impl(cx, + span, + type_ident, + generics, + eq_method, + ne_method); +} + +fn expand_deriving_eq_enum_def(cx: @ext_ctxt, + span: span, + enum_definition: &enum_def, + type_ident: ident, + generics: &Generics) + -> @item { + // Create the methods. + let eq_ident = cx.ident_of(~"eq"); + let ne_ident = cx.ident_of(~"ne"); + let eq_method = expand_deriving_eq_enum_method(cx, + span, + enum_definition, + eq_ident, + type_ident, + generics, + Conjunction); + let ne_method = expand_deriving_eq_enum_method(cx, + span, + enum_definition, + ne_ident, + type_ident, + generics, + Disjunction); + + // Create the implementation. + return create_derived_eq_impl(cx, + span, + type_ident, + generics, + eq_method, + ne_method); +} + +fn expand_deriving_eq_struct_method(cx: @ext_ctxt, + span: span, + struct_def: &struct_def, + method_ident: ident, + type_ident: ident, + generics: &Generics, + junction: Junction) + -> @method { + let self_ident = cx.ident_of(~"self"); + let other_ident = cx.ident_of(~"__other"); + + // Create the body of the method. + let mut outer_expr = None; + for struct_def.fields.each |struct_field| { + match struct_field.node.kind { + named_field(ident, _, _) => { + // Create the accessor for the other field. + let other_field = build::mk_access(cx, + span, + ~[ other_ident ], + ident); + let other_field_ref = build::mk_addr_of(cx, + span, + other_field); + + // Create the accessor for this field. + let self_field = build::mk_access(cx, + span, + ~[ self_ident ], + ident); + + // Call the substructure method. + call_substructure_eq_method(cx, + span, + self_field, + other_field_ref, + method_ident, + junction, + &mut outer_expr); + } + unnamed_field => { + cx.span_unimpl(span, ~"unnamed fields with `deriving_eq`"); + } + } + } + + // Create the method itself. + let body = finish_eq_chain_expr(cx, span, outer_expr, junction); + return create_eq_method(cx, + span, + method_ident, + type_ident, + generics, + body); +} + +fn expand_deriving_eq_enum_method(cx: @ext_ctxt, + span: span, + enum_definition: &enum_def, + method_ident: ident, + type_ident: ident, + generics: &Generics, + junction: Junction) + -> @method { + let self_ident = cx.ident_of(~"self"); + let other_ident = cx.ident_of(~"__other"); + + let is_eq; + match junction { + Conjunction => is_eq = true, + Disjunction => is_eq = false, + } + + // Create the arms of the self match in the method body. + let mut self_arms = ~[]; + for enum_definition.variants.each |self_variant| { + let mut other_arms = ~[]; + + // Create the matching pattern. + let matching_pat = create_enum_variant_pattern(cx, + span, + self_variant, + ~"__other"); + + // Create the matching pattern body. + let mut matching_body_expr = None; + for uint::range(0, variant_arg_count(cx, span, self_variant)) |i| { + // Create the expression for the other field. + let other_field_ident = cx.ident_of(~"__other" + i.to_str()); + let other_field = build::mk_path(cx, + span, + ~[ other_field_ident ]); + + // Create the expression for this field. + let self_field_ident = cx.ident_of(~"__self" + i.to_str()); + let self_field = build::mk_path(cx, span, ~[ self_field_ident ]); + + // Call the substructure method. + call_substructure_eq_method(cx, + span, + self_field, + other_field, + method_ident, + junction, + &mut matching_body_expr); + } + + let matching_body_expr = finish_eq_chain_expr(cx, + span, + matching_body_expr, + junction); + let matching_body_block = build::mk_simple_block(cx, + span, + matching_body_expr); + + // Create the matching arm. + let matching_arm = ast::arm { + pats: ~[ matching_pat ], + guard: None, + body: matching_body_block + }; + other_arms.push(matching_arm); + + // Maybe generate a non-matching case. If there is only one + // variant then there will always be a match. + if enum_definition.variants.len() > 1 { + // Create the nonmatching pattern. + let nonmatching_pat = @ast::pat { + id: cx.next_id(), + node: pat_wild, + span: span + }; + + // Create the nonmatching pattern body. + let nonmatching_expr = build::mk_bool(cx, span, !is_eq); + let nonmatching_body_block = + build::mk_simple_block(cx, + span, + nonmatching_expr); + + // Create the nonmatching arm. + let nonmatching_arm = ast::arm { + pats: ~[ nonmatching_pat ], + guard: None, + body: nonmatching_body_block, + }; + other_arms.push(nonmatching_arm); + } + + // Create the self pattern. + let self_pat = create_enum_variant_pattern(cx, + span, + self_variant, + ~"__self"); + + // Create the self pattern body. + let other_expr = build::mk_path(cx, span, ~[ other_ident ]); + let other_expr = build::mk_unary(cx, span, deref, other_expr); + let other_match_expr = expr_match(other_expr, other_arms); + let other_match_expr = build::mk_expr(cx, + span, + other_match_expr); + let other_match_body_block = build::mk_simple_block(cx, + span, + other_match_expr); + + // Create the self arm. + let self_arm = ast::arm { + pats: ~[ self_pat ], + guard: None, + body: other_match_body_block, + }; + self_arms.push(self_arm); + } + + // Create the method body. + let self_expr = build::mk_path(cx, span, ~[ self_ident ]); + let self_expr = build::mk_unary(cx, span, deref, self_expr); + let self_match_expr = expr_match(self_expr, self_arms); + let self_match_expr = build::mk_expr(cx, span, self_match_expr); + + // Create the method. + return create_eq_method(cx, + span, + method_ident, + type_ident, + generics, + self_match_expr); +} + +fn expand_deriving_eq_struct_tuple_method(cx: @ext_ctxt, + span: span, + struct_def: &struct_def, + method_ident: ident, + type_ident: ident, + generics: &Generics, + junction: Junction) + -> @method { + let self_str = ~"self"; + let other_str = ~"__other"; + let type_path = build::mk_raw_path(span, ~[type_ident]); + let fields = copy struct_def.fields; + + // Create comparison expression, comparing each of the fields + let mut match_body = None; + for fields.eachi |i, _| { + let other_field_ident = cx.ident_of(other_str + i.to_str()); + let other_field = build::mk_path(cx, span, ~[ other_field_ident ]); + + let self_field_ident = cx.ident_of(self_str + i.to_str()); + let self_field = build::mk_path(cx, span, ~[ self_field_ident ]); + + call_substructure_eq_method(cx, span, self_field, other_field, + method_ident, junction, &mut match_body); + } + let match_body = finish_eq_chain_expr(cx, span, match_body, junction); + + // Create arm for the '__other' match, containing the comparison expr + let other_subpats = create_subpatterns(cx, span, other_str, fields.len()); + let other_arm = ast::arm { + pats: ~[ build::mk_pat_enum(cx, span, type_path, other_subpats) ], + guard: None, + body: build::mk_simple_block(cx, span, match_body), + }; + + // Create the match on '__other' + let other_expr = build::mk_path(cx, span, ~[ cx.ident_of(other_str) ]); + let other_expr = build::mk_unary(cx, span, deref, other_expr); + let other_match_expr = expr_match(other_expr, ~[other_arm]); + let other_match_expr = build::mk_expr(cx, span, other_match_expr); + + // Create arm for the 'self' match, which contains the '__other' match + let self_subpats = create_subpatterns(cx, span, self_str, fields.len()); + let self_arm = ast::arm { + pats: ~[build::mk_pat_enum(cx, span, type_path, self_subpats)], + guard: None, + body: build::mk_simple_block(cx, span, other_match_expr), + }; + + // Create the match on 'self' + let self_expr = build::mk_path(cx, span, ~[ cx.ident_of(self_str) ]); + let self_expr = build::mk_unary(cx, span, deref, self_expr); + let self_match_expr = expr_match(self_expr, ~[self_arm]); + let self_match_expr = build::mk_expr(cx, span, self_match_expr); + + create_eq_method(cx, span, method_ident, + type_ident, generics, self_match_expr) +} diff --git a/src/libsyntax/ext/deriving/iter_bytes.rs b/src/libsyntax/ext/deriving/iter_bytes.rs new file mode 100644 index 0000000000000..75d7b396c7e15 --- /dev/null +++ b/src/libsyntax/ext/deriving/iter_bytes.rs @@ -0,0 +1,266 @@ +// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +use core::prelude::*; + +use ast; +use ast::{TraitTyParamBound, Ty, and, bind_by_ref, binop, deref, enum_def}; +use ast::{enum_variant_kind, expr, expr_match, ident, impure_fn, item, item_}; +use ast::{item_enum, item_impl, item_struct, Generics}; +use ast::{m_imm, meta_item, method}; +use ast::{named_field, or, pat, pat_ident, pat_wild, public, pure_fn}; +use ast::{stmt, struct_def, struct_variant_kind}; +use ast::{sty_by_ref, sty_region, tuple_variant_kind, ty_nil, TyParam}; +use ast::{TyParamBound, ty_path, ty_rptr, unnamed_field, variant}; +use ext::base::ext_ctxt; +use ext::build; +use ext::deriving::*; +use codemap::{span, spanned}; +use ast_util; + +use core::uint; + +pub fn expand_deriving_iter_bytes(cx: @ext_ctxt, + span: span, + _mitem: @meta_item, + in_items: ~[@item]) + -> ~[@item] { + expand_deriving(cx, + span, + in_items, + expand_deriving_iter_bytes_struct_def, + expand_deriving_iter_bytes_enum_def) +} + +pub fn expand_deriving_obsolete(cx: @ext_ctxt, + span: span, + _mitem: @meta_item, + in_items: ~[@item]) + -> ~[@item] { + cx.span_err(span, ~"`#[deriving_iter_bytes]` is obsolete; use `#[deriving(IterBytes)]` \ + instead"); + in_items +} + +fn create_derived_iter_bytes_impl(cx: @ext_ctxt, + span: span, + type_ident: ident, + generics: &Generics, + method: @method) + -> @item { + let methods = [ method ]; + let trait_path = [ + cx.ident_of(~"core"), + cx.ident_of(~"to_bytes"), + cx.ident_of(~"IterBytes") + ]; + create_derived_impl(cx, span, type_ident, generics, methods, trait_path) +} + +// Creates a method from the given set of statements conforming to the +// signature of the `iter_bytes` method. +fn create_iter_bytes_method(cx: @ext_ctxt, + span: span, + +statements: ~[@stmt]) + -> @method { + // Create the `lsb0` parameter. + let bool_ident = cx.ident_of(~"bool"); + let lsb0_arg_type = build::mk_simple_ty_path(cx, span, bool_ident); + let lsb0_ident = cx.ident_of(~"__lsb0"); + let lsb0_arg = build::mk_arg(cx, span, lsb0_ident, lsb0_arg_type); + + // Create the `f` parameter. + let core_ident = cx.ident_of(~"core"); + let to_bytes_ident = cx.ident_of(~"to_bytes"); + let cb_ident = cx.ident_of(~"Cb"); + let core_to_bytes_cb_ident = ~[ core_ident, to_bytes_ident, cb_ident ]; + let f_arg_type = build::mk_ty_path(cx, span, core_to_bytes_cb_ident); + let f_ident = cx.ident_of(~"__f"); + let f_arg = build::mk_arg(cx, span, f_ident, f_arg_type); + + // Create the type of the return value. + let output_type = @ast::Ty { id: cx.next_id(), node: ty_nil, span: span }; + + // Create the function declaration. + let inputs = ~[ lsb0_arg, f_arg ]; + let fn_decl = build::mk_fn_decl(inputs, output_type); + + // Create the body block. + let body_block = build::mk_block_(cx, span, statements); + + // Create the method. + let self_ty = spanned { node: sty_region(None, m_imm), span: span }; + let method_ident = cx.ident_of(~"iter_bytes"); + @ast::method { + ident: method_ident, + attrs: ~[], + generics: ast_util::empty_generics(), + self_ty: self_ty, + purity: impure_fn, + decl: fn_decl, + body: body_block, + id: cx.next_id(), + span: span, + self_id: cx.next_id(), + vis: public + } +} + +fn call_substructure_iter_bytes_method(cx: @ext_ctxt, + span: span, + self_field: @expr) + -> @stmt { + // Gather up the parameters we want to chain along. + let lsb0_ident = cx.ident_of(~"__lsb0"); + let f_ident = cx.ident_of(~"__f"); + let lsb0_expr = build::mk_path(cx, span, ~[ lsb0_ident ]); + let f_expr = build::mk_path(cx, span, ~[ f_ident ]); + + // Call the substructure method. + let iter_bytes_ident = cx.ident_of(~"iter_bytes"); + let self_method = build::mk_access_(cx, + span, + self_field, + iter_bytes_ident); + let self_call = build::mk_call_(cx, + span, + self_method, + ~[ lsb0_expr, f_expr ]); + + // Create a statement out of this expression. + build::mk_stmt(cx, span, self_call) +} + +fn expand_deriving_iter_bytes_struct_def(cx: @ext_ctxt, + span: span, + struct_def: &struct_def, + type_ident: ident, + generics: &Generics) + -> @item { + // Create the method. + let method = expand_deriving_iter_bytes_struct_method(cx, + span, + struct_def); + + // Create the implementation. + return create_derived_iter_bytes_impl(cx, + span, + type_ident, + generics, + method); +} + +fn expand_deriving_iter_bytes_enum_def(cx: @ext_ctxt, + span: span, + enum_definition: &enum_def, + type_ident: ident, + generics: &Generics) + -> @item { + // Create the method. + let method = expand_deriving_iter_bytes_enum_method(cx, + span, + enum_definition); + + // Create the implementation. + return create_derived_iter_bytes_impl(cx, + span, + type_ident, + generics, + method); +} + +fn expand_deriving_iter_bytes_struct_method(cx: @ext_ctxt, + span: span, + struct_def: &struct_def) + -> @method { + let self_ident = cx.ident_of(~"self"); + + // Create the body of the method. + let mut statements = ~[]; + for struct_def.fields.each |struct_field| { + match struct_field.node.kind { + named_field(ident, _, _) => { + // Create the accessor for this field. + let self_field = build::mk_access(cx, + span, + ~[ self_ident ], + ident); + + // Call the substructure method. + let stmt = call_substructure_iter_bytes_method(cx, + span, + self_field); + statements.push(stmt); + } + unnamed_field => { + cx.span_unimpl(span, + ~"unnamed fields with `deriving_iter_bytes`"); + } + } + } + + // Create the method itself. + return create_iter_bytes_method(cx, span, statements); +} + +fn expand_deriving_iter_bytes_enum_method(cx: @ext_ctxt, + span: span, + enum_definition: &enum_def) + -> @method { + // Create the arms of the match in the method body. + let arms = do enum_definition.variants.mapi |i, variant| { + // Create the matching pattern. + let pat = create_enum_variant_pattern(cx, span, variant, ~"__self"); + + // Determine the discriminant. We will feed this value to the byte + // iteration function. + let discriminant; + match variant.node.disr_expr { + Some(copy disr_expr) => discriminant = disr_expr, + None => discriminant = build::mk_uint(cx, span, i), + } + + // Feed the discriminant to the byte iteration function. + let mut stmts = ~[]; + let discrim_stmt = call_substructure_iter_bytes_method(cx, + span, + discriminant); + stmts.push(discrim_stmt); + + // Feed each argument in this variant to the byte iteration function + // as well. + for uint::range(0, variant_arg_count(cx, span, variant)) |j| { + // Create the expression for this field. + let field_ident = cx.ident_of(~"__self" + j.to_str()); + let field = build::mk_path(cx, span, ~[ field_ident ]); + + // Call the substructure method. + let stmt = call_substructure_iter_bytes_method(cx, span, field); + stmts.push(stmt); + } + + // Create the pattern body. + let match_body_block = build::mk_block_(cx, span, stmts); + + // Create the arm. + ast::arm { + pats: ~[ pat ], + guard: None, + body: match_body_block, + } + }; + + // Create the method body. + let self_match_expr = expand_enum_or_struct_match(cx, span, arms); + let self_match_stmt = build::mk_stmt(cx, span, self_match_expr); + + // Create the method. + create_iter_bytes_method(cx, span, ~[ self_match_stmt ]) +} diff --git a/src/libsyntax/ext/deriving/mod.rs b/src/libsyntax/ext/deriving/mod.rs new file mode 100644 index 0000000000000..57fddd623d474 --- /dev/null +++ b/src/libsyntax/ext/deriving/mod.rs @@ -0,0 +1,309 @@ +// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +/// The compiler code necessary to implement the #[deriving(Eq)] and +/// #[deriving(IterBytes)] extensions. + +use core::prelude::*; + +use ast; +use ast::{TraitTyParamBound, Ty, and, bind_by_ref, binop, deref, enum_def}; +use ast::{enum_variant_kind, expr, expr_match, ident, impure_fn, item, item_}; +use ast::{item_enum, item_impl, item_struct, Generics}; +use ast::{m_imm, meta_item, method}; +use ast::{named_field, or, pat, pat_ident, pat_wild, public, pure_fn}; +use ast::{stmt, struct_def, struct_variant_kind}; +use ast::{sty_by_ref, sty_region, tuple_variant_kind, ty_nil, TyParam}; +use ast::{TyParamBound, ty_path, ty_rptr, unnamed_field, variant}; +use ext::base::ext_ctxt; +use ext::build; +use codemap::{span, spanned}; +use parse::token::special_idents::clownshoes_extensions; +use opt_vec; + +use core::uint; + +pub mod clone; +pub mod eq; +pub mod iter_bytes; + +type ExpandDerivingStructDefFn = &'self fn(@ext_ctxt, + span, + x: &struct_def, + ident, + y: &Generics) -> @item; +type ExpandDerivingEnumDefFn = &'self fn(@ext_ctxt, + span, + x: &enum_def, + ident, + y: &Generics) -> @item; + +pub fn expand_meta_deriving(cx: @ext_ctxt, + _span: span, + mitem: @meta_item, + in_items: ~[@item]) + -> ~[@item] { + use ast::{meta_list, meta_name_value, meta_word}; + + match mitem.node { + meta_name_value(_, l) => { + cx.span_err(l.span, ~"unexpected value in `deriving`"); + in_items + } + meta_word(_) | meta_list(_, []) => { + cx.span_warn(mitem.span, ~"empty trait list in `deriving`"); + in_items + } + meta_list(_, titems) => { + do titems.foldr(in_items) |&titem, in_items| { + match titem.node { + meta_name_value(tname, _) | + meta_list(tname, _) | + meta_word(tname) => { + match *tname { + ~"Clone" => clone::expand_deriving_clone(cx, + titem.span, titem, in_items), + ~"Eq" => eq::expand_deriving_eq(cx, titem.span, + titem, in_items), + ~"IterBytes" => iter_bytes::expand_deriving_iter_bytes(cx, + titem.span, titem, in_items), + tname => { + cx.span_err(titem.span, fmt!("unknown \ + `deriving` trait: `%s`", tname)); + in_items + } + } + } + } + } + } + } +} + +pub fn expand_deriving(cx: @ext_ctxt, + span: span, + in_items: ~[@item], + expand_deriving_struct_def: ExpandDerivingStructDefFn, + expand_deriving_enum_def: ExpandDerivingEnumDefFn) + -> ~[@item] { + let mut result = ~[]; + for in_items.each |item| { + result.push(copy *item); + match item.node { + item_struct(struct_def, ref generics) => { + result.push(expand_deriving_struct_def(cx, + span, + struct_def, + item.ident, + generics)); + } + item_enum(ref enum_definition, ref generics) => { + result.push(expand_deriving_enum_def(cx, + span, + enum_definition, + item.ident, + generics)); + } + _ => () + } + } + result +} + +fn create_impl_item(cx: @ext_ctxt, span: span, +item: item_) -> @item { + @ast::item { + ident: clownshoes_extensions, + attrs: ~[], + id: cx.next_id(), + node: item, + vis: public, + span: span, + } +} + +pub fn create_self_type_with_params(cx: @ext_ctxt, + span: span, + type_ident: ident, + generics: &Generics) + -> @Ty { + // Create the type parameters on the `self` path. + let mut self_ty_params = ~[]; + for generics.ty_params.each |ty_param| { + let self_ty_param = build::mk_simple_ty_path(cx, + span, + ty_param.ident); + self_ty_params.push(self_ty_param); + } + + // Create the type of `self`. + let self_type = build::mk_raw_path_(span, + ~[ type_ident ], + self_ty_params); + let self_type = ty_path(self_type, cx.next_id()); + @ast::Ty { id: cx.next_id(), node: self_type, span: span } +} + +pub fn create_derived_impl(cx: @ext_ctxt, + span: span, + type_ident: ident, + generics: &Generics, + methods: &[@method], + trait_path: &[ident]) + -> @item { + /*! + * + * Given that we are deriving a trait `Tr` for a type `T<'a, ..., + * 'z, A, ..., Z>`, creates an impl like: + * + * impl<'a, ..., 'z, A:Tr, ..., Z: Tr> Tr for T { ... } + * + * FIXME(#5090): Remove code duplication between this and the + * code in auto_encode.rs + */ + + // Copy the lifetimes + let impl_lifetimes = generics.lifetimes.map(|l| { + build::mk_lifetime(cx, l.span, l.ident) + }); + + // Create the type parameters. + let impl_ty_params = generics.ty_params.map(|ty_param| { + let bound = build::mk_ty_path_global(cx, + span, + trait_path.map(|x| *x)); + let bounds = @opt_vec::with(TraitTyParamBound(bound)); + build::mk_ty_param(cx, ty_param.ident, bounds) + }); + + // Create the reference to the trait. + let trait_path = ast::path { + span: span, + global: true, + idents: trait_path.map(|x| *x), + rp: None, + types: ~[] + }; + let trait_path = @trait_path; + let trait_ref = ast::trait_ref { + path: trait_path, + ref_id: cx.next_id() + }; + let trait_ref = @trait_ref; + + // Create the type of `self`. + let self_type = create_self_type_with_params(cx, + span, + type_ident, + generics); + + // Create the impl item. + let impl_item = item_impl(Generics {lifetimes: impl_lifetimes, + ty_params: impl_ty_params}, + Some(trait_ref), + self_type, + methods.map(|x| *x)); + return create_impl_item(cx, span, impl_item); +} + +pub fn create_subpatterns(cx: @ext_ctxt, + span: span, + prefix: ~str, + n: uint) + -> ~[@pat] { + let mut subpats = ~[]; + for uint::range(0, n) |_i| { + // Create the subidentifier. + let index = subpats.len().to_str(); + let ident = cx.ident_of(prefix + index); + + // Create the subpattern. + let subpath = build::mk_raw_path(span, ~[ ident ]); + let subpat = pat_ident(bind_by_ref(m_imm), subpath, None); + let subpat = build::mk_pat(cx, span, subpat); + subpats.push(subpat); + } + return subpats; +} + +pub fn is_struct_tuple(struct_def: &struct_def) -> bool { + struct_def.fields.len() > 0 && struct_def.fields.all(|f| { + match f.node.kind { + named_field(*) => false, + unnamed_field => true + } + }) +} + +pub fn create_enum_variant_pattern(cx: @ext_ctxt, + span: span, + variant: &variant, + prefix: ~str) + -> @pat { + let variant_ident = variant.node.name; + match variant.node.kind { + tuple_variant_kind(ref variant_args) => { + if variant_args.len() == 0 { + return build::mk_pat_ident_with_binding_mode( + cx, span, variant_ident, ast::bind_infer); + } + + let matching_path = build::mk_raw_path(span, ~[ variant_ident ]); + let subpats = create_subpatterns(cx, + span, + prefix, + variant_args.len()); + + return build::mk_pat_enum(cx, span, matching_path, subpats); + } + struct_variant_kind(struct_def) => { + let matching_path = build::mk_raw_path(span, ~[ variant_ident ]); + let subpats = create_subpatterns(cx, + span, + prefix, + struct_def.fields.len()); + + let field_pats = do struct_def.fields.mapi |i, struct_field| { + let ident = match struct_field.node.kind { + named_field(ident, _, _) => ident, + unnamed_field => { + cx.span_bug(span, ~"unexpected unnamed field"); + } + }; + ast::field_pat { ident: ident, pat: subpats[i] } + }; + + build::mk_pat_struct(cx, span, matching_path, field_pats) + } + enum_variant_kind(*) => { + cx.span_unimpl(span, ~"enum variants for `deriving`"); + } + } +} + +pub fn variant_arg_count(cx: @ext_ctxt, span: span, variant: &variant) -> uint { + match variant.node.kind { + tuple_variant_kind(ref args) => args.len(), + struct_variant_kind(ref struct_def) => struct_def.fields.len(), + enum_variant_kind(*) => { + cx.span_bug(span, ~"variant_arg_count: enum variants deprecated") + } + } +} + +pub fn expand_enum_or_struct_match(cx: @ext_ctxt, + span: span, + arms: ~[ ast::arm ]) + -> @expr { + let self_ident = cx.ident_of(~"self"); + let self_expr = build::mk_path(cx, span, ~[ self_ident ]); + let self_expr = build::mk_unary(cx, span, deref, self_expr); + let self_match_expr = expr_match(self_expr, arms); + build::mk_expr(cx, span, self_match_expr) +} diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index ad05e2f21e64b..fb9d96a783174 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -464,6 +464,28 @@ pub fn core_macros() -> ~str { } ) + macro_rules! assert( + ($cond:expr) => { + if !$cond { + ::core::sys::fail_assert(stringify!($cond), file!(), line!()) + } + }; + ($cond:expr, $msg:expr) => { + if !$cond { + ::core::sys::fail_assert($msg, file!(), line!()) + } + } + ) + + macro_rules! assert_eq ( + ($given:expr , $expected:expr) => + ({let given_val = $given; + let expected_val = $expected; + // check both directions of equality.... + if !((given_val == expected_val) && (expected_val == given_val)) { + fail!(fmt!(\"expected: %?, given: %?\",expected_val,given_val)); + }})) + macro_rules! condition ( { $c:ident: $in:ty -> $out:ty; } => { @@ -471,8 +493,8 @@ pub fn core_macros() -> ~str { mod $c { fn key(_x: @::core::condition::Handler<$in,$out>) { } - pub const cond : - ::core::condition::Condition/&static<$in,$out> = + pub static cond : + ::core::condition::Condition<'static,$in,$out> = ::core::condition::Condition { name: stringify!($c), key: key @@ -481,6 +503,7 @@ pub fn core_macros() -> ~str { } ) + }"; } @@ -547,7 +570,6 @@ mod test { use codemap; use codemap::spanned; use parse; - use util::testing::check_equal; use core::option::{None, Some}; // make sure that fail! is present @@ -634,9 +656,9 @@ mod test { let attr2 = make_dummy_attr (@~"bar"); let escape_attr = make_dummy_attr (@~"macro_escape"); let attrs1 = ~[attr1, escape_attr, attr2]; - check_equal (contains_macro_escape (attrs1),true); + assert_eq!(contains_macro_escape (attrs1),true); let attrs2 = ~[attr1,attr2]; - check_equal (contains_macro_escape (attrs2),false); + assert_eq!(contains_macro_escape (attrs2),false); } // make a "meta_word" outer attribute with the given name diff --git a/src/libsyntax/ext/fmt.rs b/src/libsyntax/ext/fmt.rs index 9973c9558c968..3ebe844950a40 100644 --- a/src/libsyntax/ext/fmt.rs +++ b/src/libsyntax/ext/fmt.rs @@ -139,19 +139,17 @@ fn pieces_to_expr(cx: @ext_ctxt, sp: span, make_conv_struct(cx, sp, rt_conv_flags, rt_conv_width, rt_conv_precision, rt_conv_ty) } - fn make_conv_call(cx: @ext_ctxt, sp: span, conv_type: ~str, cnv: &Conv, - arg: @ast::expr) -> @ast::expr { + fn make_conv_call(cx: @ext_ctxt, sp: span, conv_type: &str, cnv: &Conv, + arg: @ast::expr, buf: @ast::expr) -> @ast::expr { let fname = ~"conv_" + conv_type; let path = make_path_vec(cx, @fname); let cnv_expr = make_rt_conv_expr(cx, sp, cnv); - let args = ~[cnv_expr, arg]; + let args = ~[cnv_expr, arg, buf]; return mk_call_global(cx, arg.span, path, args); } - fn make_new_conv(cx: @ext_ctxt, sp: span, cnv: &Conv, arg: @ast::expr) -> - @ast::expr { - // FIXME: Move validation code into core::extfmt (Issue #2249) - + fn make_new_conv(cx: @ext_ctxt, sp: span, cnv: &Conv, + arg: @ast::expr, buf: @ast::expr) -> @ast::expr { fn is_signed_type(cnv: &Conv) -> bool { match cnv.ty { TyInt(s) => match s { @@ -198,29 +196,20 @@ fn pieces_to_expr(cx: @ext_ctxt, sp: span, CountIs(_) => (), _ => cx.span_unimpl(sp, unsupported) } - match cnv.ty { - TyStr => return make_conv_call(cx, arg.span, ~"str", cnv, arg), - TyInt(sign) => match sign { - Signed => return make_conv_call(cx, arg.span, ~"int", cnv, arg), - Unsigned => { - return make_conv_call(cx, arg.span, ~"uint", cnv, arg) - } - }, - TyBool => return make_conv_call(cx, arg.span, ~"bool", cnv, arg), - TyChar => return make_conv_call(cx, arg.span, ~"char", cnv, arg), - TyHex(_) => { - return make_conv_call(cx, arg.span, ~"uint", cnv, arg); - } - TyBits => return make_conv_call(cx, arg.span, ~"uint", cnv, arg), - TyOctal => return make_conv_call(cx, arg.span, ~"uint", cnv, arg), - TyFloat => { - return make_conv_call(cx, arg.span, ~"float", cnv, arg); - } - TyPoly => return make_conv_call(cx, arg.span, ~"poly", cnv, - mk_addr_of(cx, sp, arg)) - } + let (name, actual_arg) = match cnv.ty { + TyStr => ("str", arg), + TyInt(Signed) => ("int", arg), + TyBool => ("bool", arg), + TyChar => ("char", arg), + TyBits | TyOctal | TyHex(_) | TyInt(Unsigned) => ("uint", arg), + TyFloat => ("float", arg), + TyPoly => ("poly", mk_addr_of(cx, sp, arg)) + }; + return make_conv_call(cx, arg.span, name, cnv, actual_arg, + mk_mut_addr_of(cx, arg.span, buf)); } fn log_conv(c: &Conv) { + debug!("Building conversion:"); match c.param { Some(p) => { debug!("param: %s", p.to_str()); } _ => debug!("param: none") @@ -268,49 +257,72 @@ fn pieces_to_expr(cx: @ext_ctxt, sp: span, TyPoly => debug!("type: poly") } } + let fmt_sp = args[0].span; let mut n = 0u; - let mut piece_exprs = ~[]; let nargs = args.len(); - for pieces.each |pc| { - match *pc { - PieceString(ref s) => { - piece_exprs.push(mk_uniq_str(cx, fmt_sp, copy *s)) - } - PieceConv(ref conv) => { - n += 1u; - if n >= nargs { - cx.span_fatal(sp, - ~"not enough arguments to fmt! " + + + /* 'ident' is the local buffer building up the result of fmt! */ + let ident = cx.parse_sess().interner.intern(@~"__fmtbuf"); + let buf = || mk_path(cx, fmt_sp, ~[ident]); + let str_ident = cx.parse_sess().interner.intern(@~"str"); + let push_ident = cx.parse_sess().interner.intern(@~"push_str"); + let mut stms = ~[]; + + /* Translate each piece (portion of the fmt expression) by invoking the + corresponding function in core::unstable::extfmt. Each function takes a + buffer to insert data into along with the data being formatted. */ + do vec::consume(pieces) |i, pc| { + match pc { + /* Raw strings get appended via str::push_str */ + PieceString(s) => { + let portion = mk_uniq_str(cx, fmt_sp, s); + + /* If this is the first portion, then initialize the local + buffer with it directly */ + if i == 0 { + stms.push(mk_local(cx, fmt_sp, true, ident, portion)); + } else { + let args = ~[mk_mut_addr_of(cx, fmt_sp, buf()), portion]; + let call = mk_call_global(cx, + fmt_sp, + ~[str_ident, push_ident], + args); + stms.push(mk_stmt(cx, fmt_sp, call)); + } + } + + /* Invoke the correct conv function in extfmt */ + PieceConv(ref conv) => { + n += 1u; + if n >= nargs { + cx.span_fatal(sp, + ~"not enough arguments to fmt! " + ~"for the given format string"); + } + + log_conv(conv); + /* If the first portion is a conversion, then the local buffer + must be initialized as an empty string */ + if i == 0 { + stms.push(mk_local(cx, fmt_sp, true, ident, + mk_uniq_str(cx, fmt_sp, ~""))); + } + stms.push(mk_stmt(cx, fmt_sp, + make_new_conv(cx, fmt_sp, conv, + args[n], buf()))); } - debug!("Building conversion:"); - log_conv(conv); - let arg_expr = args[n]; - let c_expr = make_new_conv( - cx, - fmt_sp, - conv, - arg_expr - ); - piece_exprs.push(c_expr); - } } } - let expected_nargs = n + 1u; // n conversions + the fmt string + let expected_nargs = n + 1u; // n conversions + the fmt string if expected_nargs < nargs { cx.span_fatal (sp, fmt!("too many arguments to fmt!. found %u, expected %u", nargs, expected_nargs)); } - let arg_vec = mk_fixed_vec_e(cx, fmt_sp, piece_exprs); - return mk_call_global(cx, - fmt_sp, - ~[cx.parse_sess().interner.intern(@~"str"), - cx.parse_sess().interner.intern(@~"concat")], - ~[arg_vec]); + return mk_block(cx, fmt_sp, ~[], stms, Some(buf())); } // // Local Variables: diff --git a/src/libsyntax/ext/pipes/proto.rs b/src/libsyntax/ext/pipes/proto.rs index a47b39a45c864..4a8ceedc8e301 100644 --- a/src/libsyntax/ext/pipes/proto.rs +++ b/src/libsyntax/ext/pipes/proto.rs @@ -17,11 +17,11 @@ use ext::pipes::ast_builder::{append_types, ext_ctxt_ast_builder, path}; use core::to_str::ToStr; -#[deriving_eq] +#[deriving(Eq)] pub enum direction { send, recv } impl ToStr for direction { - pure fn to_str(&self) -> ~str { + fn to_str(&self) -> ~str { match *self { send => ~"Send", recv => ~"Recv" diff --git a/src/libsyntax/ext/tt/macro_parser.rs b/src/libsyntax/ext/tt/macro_parser.rs index b0628437bb0ff..688d7a57d91a5 100644 --- a/src/libsyntax/ext/tt/macro_parser.rs +++ b/src/libsyntax/ext/tt/macro_parser.rs @@ -109,7 +109,7 @@ pub fn is_some(&&mpu: matcher_pos_up) -> bool { } pub struct MatcherPos { - elts: ~[ast::matcher], // maybe should be /&? Need to understand regions. + elts: ~[ast::matcher], // maybe should be <'>? Need to understand regions. sep: Option, idx: uint, up: matcher_pos_up, // mutable for swapping only diff --git a/src/libsyntax/ext/tt/macro_rules.rs b/src/libsyntax/ext/tt/macro_rules.rs index dcc84ce46fe05..5a6fd6fec5894 100644 --- a/src/libsyntax/ext/tt/macro_rules.rs +++ b/src/libsyntax/ext/tt/macro_rules.rs @@ -112,7 +112,7 @@ pub fn add_new_extension(cx: @ext_ctxt, match (*tt) { // cut off delimiters; don't parse 'em tt_delim(ref tts) => { - (*tts).slice(1u,(*tts).len()-1u) + (*tts).slice(1u,(*tts).len()-1u).to_owned() } _ => cx.span_fatal( sp, ~"macro rhs must be delimited") diff --git a/src/libsyntax/ext/tt/transcribe.rs b/src/libsyntax/ext/tt/transcribe.rs index 0196ee6d18426..49076c74972f6 100644 --- a/src/libsyntax/ext/tt/transcribe.rs +++ b/src/libsyntax/ext/tt/transcribe.rs @@ -79,7 +79,7 @@ pub fn new_tt_reader(sp_diag: @span_handler, return r; } -pure fn dup_tt_frame(f: @mut TtFrame) -> @mut TtFrame { +fn dup_tt_frame(f: @mut TtFrame) -> @mut TtFrame { @mut TtFrame { readme: @mut (copy *f.readme), idx: f.idx, @@ -92,7 +92,7 @@ pure fn dup_tt_frame(f: @mut TtFrame) -> @mut TtFrame { } } -pub pure fn dup_tt_reader(r: @mut TtReader) -> @mut TtReader { +pub fn dup_tt_reader(r: @mut TtReader) -> @mut TtReader { @mut TtReader { sp_diag: r.sp_diag, interner: r.interner, @@ -106,10 +106,10 @@ pub pure fn dup_tt_reader(r: @mut TtReader) -> @mut TtReader { } -pure fn lookup_cur_matched_by_matched(r: &mut TtReader, +fn lookup_cur_matched_by_matched(r: &mut TtReader, start: @named_match) -> @named_match { - pure fn red(+ad: @named_match, idx: &uint) -> @named_match { + fn red(+ad: @named_match, idx: &uint) -> @named_match { match *ad { matched_nonterminal(_) => { // end of the line; duplicate henceforth diff --git a/src/libsyntax/opt_vec.rs b/src/libsyntax/opt_vec.rs index dbabca55a11f4..67c3d19dd0fb7 100644 --- a/src/libsyntax/opt_vec.rs +++ b/src/libsyntax/opt_vec.rs @@ -61,18 +61,18 @@ impl OptVec { } } - pure fn get(&self, i: uint) -> &'self T { + fn get(&self, i: uint) -> &'self T { match *self { Empty => fail!(fmt!("Invalid index %u", i)), Vec(ref v) => &v[i] } } - pure fn is_empty(&self) -> bool { + fn is_empty(&self) -> bool { self.len() == 0 } - pure fn len(&self) -> uint { + fn len(&self) -> uint { match *self { Empty => 0, Vec(ref v) => v.len() @@ -105,8 +105,8 @@ impl OptVec { } impl Eq for OptVec { - pure fn eq(&self, other: &OptVec) -> bool { - // Note: cannot use #[deriving_eq] here because + fn eq(&self, other: &OptVec) -> bool { + // Note: cannot use #[deriving(Eq)] here because // (Empty, Vec(~[])) ought to be equal. match (self, other) { (&Empty, &Empty) => true, @@ -116,51 +116,51 @@ impl Eq for OptVec { } } - pure fn ne(&self, other: &OptVec) -> bool { + fn ne(&self, other: &OptVec) -> bool { !self.eq(other) } } impl BaseIter for OptVec { - pure fn each(&self, blk: &fn(v: &A) -> bool) { + fn each(&self, blk: &fn(v: &A) -> bool) { match *self { Empty => {} Vec(ref v) => v.each(blk) } } - pure fn size_hint(&self) -> Option { + fn size_hint(&self) -> Option { Some(self.len()) } } impl iter::ExtendedIter for OptVec { #[inline(always)] - pure fn eachi(&self, blk: &fn(+v: uint, v: &A) -> bool) { + fn eachi(&self, blk: &fn(+v: uint, v: &A) -> bool) { iter::eachi(self, blk) } #[inline(always)] - pure fn all(&self, blk: &fn(&A) -> bool) -> bool { + fn all(&self, blk: &fn(&A) -> bool) -> bool { iter::all(self, blk) } #[inline(always)] - pure fn any(&self, blk: &fn(&A) -> bool) -> bool { + fn any(&self, blk: &fn(&A) -> bool) -> bool { iter::any(self, blk) } #[inline(always)] - pure fn foldl(&self, +b0: B, blk: &fn(&B, &A) -> B) -> B { + fn foldl(&self, +b0: B, blk: &fn(&B, &A) -> B) -> B { iter::foldl(self, b0, blk) } #[inline(always)] - pure fn position(&self, f: &fn(&A) -> bool) -> Option { + fn position(&self, f: &fn(&A) -> bool) -> Option { iter::position(self, f) } #[inline(always)] - pure fn map_to_vec(&self, op: &fn(&A) -> B) -> ~[B] { + fn map_to_vec(&self, op: &fn(&A) -> B) -> ~[B] { iter::map_to_vec(self, op) } #[inline(always)] - pure fn flat_map_to_vec>(&self, op: &fn(&A) -> IB) + fn flat_map_to_vec>(&self, op: &fn(&A) -> IB) -> ~[B] { iter::flat_map_to_vec(self, op) } @@ -169,27 +169,27 @@ impl iter::ExtendedIter for OptVec { impl iter::EqIter for OptVec { #[inline(always)] - pure fn contains(&self, x: &A) -> bool { iter::contains(self, x) } + fn contains(&self, x: &A) -> bool { iter::contains(self, x) } #[inline(always)] - pure fn count(&self, x: &A) -> uint { iter::count(self, x) } + fn count(&self, x: &A) -> uint { iter::count(self, x) } } impl iter::CopyableIter for OptVec { #[inline(always)] - pure fn filter_to_vec(&self, pred: &fn(&A) -> bool) -> ~[A] { + fn filter_to_vec(&self, pred: &fn(&A) -> bool) -> ~[A] { iter::filter_to_vec(self, pred) } #[inline(always)] - pure fn to_vec(&self) -> ~[A] { iter::to_vec(self) } + fn to_vec(&self) -> ~[A] { iter::to_vec(self) } #[inline(always)] - pure fn find(&self, f: &fn(&A) -> bool) -> Option { + fn find(&self, f: &fn(&A) -> bool) -> Option { iter::find(self, f) } } impl iter::CopyableOrderedIter for OptVec { #[inline(always)] - pure fn min(&self) -> A { iter::min(self) } + fn min(&self) -> A { iter::min(self) } #[inline(always)] - pure fn max(&self) -> A { iter::max(self) } + fn max(&self) -> A { iter::max(self) } } diff --git a/src/libsyntax/parse/comments.rs b/src/libsyntax/parse/comments.rs index 98208bf9f7668..3f8a5588c7163 100644 --- a/src/libsyntax/parse/comments.rs +++ b/src/libsyntax/parse/comments.rs @@ -35,10 +35,10 @@ pub enum cmnt_style { } impl cmp::Eq for cmnt_style { - pure fn eq(&self, other: &cmnt_style) -> bool { + fn eq(&self, other: &cmnt_style) -> bool { ((*self) as uint) == ((*other) as uint) } - pure fn ne(&self, other: &cmnt_style) -> bool { + fn ne(&self, other: &cmnt_style) -> bool { ((*self) as uint) != ((*other) as uint) } } @@ -76,7 +76,7 @@ pub fn strip_doc_comment_decoration(comment: &str) -> ~str { while j > i && lines[j - 1u].trim().is_empty() { j -= 1u; } - return lines.slice(i, j); + return lines.slice(i, j).to_owned(); } // drop leftmost columns that contain only values in chars @@ -103,17 +103,20 @@ pub fn strip_doc_comment_decoration(comment: &str) -> ~str { if i > chars.len() { ~"" } else { - str::from_chars(chars.slice(i, chars.len())) + str::from_chars(chars.slice(i, chars.len()).to_owned()) } }; } if comment.starts_with(~"//") { - return comment.slice(3u, comment.len()).trim(); + // FIXME #5475: + // return comment.slice(3u, comment.len()).trim().to_owned(); + let r = comment.slice(3u, comment.len()); return r.trim().to_owned(); + } if comment.starts_with(~"/*") { - let lines = str::lines_any(comment.slice(3u, comment.len() - 2u)); + let lines = str::lines_any(comment.slice(3u, comment.len() - 2u).to_owned()); let lines = vertical_trim(lines); let lines = block_trim(lines, ~"\t ", None); let lines = block_trim(lines, ~"*", Some(1u)); @@ -218,7 +221,7 @@ fn trim_whitespace_prefix_and_push_line(lines: &mut ~[~str], let col = col.to_uint(); if all_whitespace(s, 0u, uint::min(len, col)) { if col < len { - s1 = str::slice(s, col, len); + s1 = str::slice(s, col, len).to_owned(); } else { s1 = ~""; } } else { s1 = s; } debug!("pushing line: %s", s1); diff --git a/src/libsyntax/parse/common.rs b/src/libsyntax/parse/common.rs index 1b64a9a6275c1..ea599e8290a27 100644 --- a/src/libsyntax/parse/common.rs +++ b/src/libsyntax/parse/common.rs @@ -134,7 +134,7 @@ pub impl Parser { } } - pure fn token_is_word(&self, word: &~str, tok: &token::Token) -> bool { + fn token_is_word(&self, word: &~str, tok: &token::Token) -> bool { match *tok { token::IDENT(sid, false) => { *self.id_to_str(sid) == *word } _ => { false } diff --git a/src/libsyntax/parse/lexer.rs b/src/libsyntax/parse/lexer.rs index 90f51fe9b65af..ffd2a1d801c96 100644 --- a/src/libsyntax/parse/lexer.rs +++ b/src/libsyntax/parse/lexer.rs @@ -32,12 +32,12 @@ pub trait reader { fn next_token(@mut self) -> TokenAndSpan; fn fatal(@mut self, ~str) -> !; fn span_diag(@mut self) -> @span_handler; - pure fn interner(@mut self) -> @token::ident_interner; + fn interner(@mut self) -> @token::ident_interner; fn peek(@mut self) -> TokenAndSpan; fn dup(@mut self) -> @reader; } -#[deriving_eq] +#[deriving(Eq)] pub struct TokenAndSpan {tok: token::Token, sp: span} pub struct StringReader { @@ -122,7 +122,7 @@ impl reader for StringReader { self.span_diagnostic.span_fatal(copy self.peek_span, m) } fn span_diag(@mut self) -> @span_handler { self.span_diagnostic } - pure fn interner(@mut self) -> @token::ident_interner { self.interner } + fn interner(@mut self) -> @token::ident_interner { self.interner } fn peek(@mut self) -> TokenAndSpan { TokenAndSpan { tok: copy self.peek_tok, @@ -139,7 +139,7 @@ impl reader for TtReader { self.sp_diag.span_fatal(copy self.cur_span, m); } fn span_diag(@mut self) -> @span_handler { self.sp_diag } - pure fn interner(@mut self) -> @token::ident_interner { self.interner } + fn interner(@mut self) -> @token::ident_interner { self.interner } fn peek(@mut self) -> TokenAndSpan { TokenAndSpan { tok: copy self.cur_tok, @@ -177,7 +177,7 @@ pub fn get_str_from(rdr: @mut StringReader, start: BytePos) -> ~str { // I'm pretty skeptical about this subtraction. What if there's a // multi-byte character before the mark? return str::slice(*rdr.src, start.to_uint() - 1u, - byte_offset(rdr).to_uint() - 1u); + byte_offset(rdr).to_uint() - 1u).to_owned(); } } @@ -261,7 +261,7 @@ fn consume_whitespace_and_comments(rdr: @mut StringReader) return consume_any_line_comment(rdr); } -pub pure fn is_line_non_doc_comment(s: &str) -> bool { +pub fn is_line_non_doc_comment(s: &str) -> bool { s.trim_right().all(|ch| ch == '/') } @@ -313,7 +313,7 @@ fn consume_any_line_comment(rdr: @mut StringReader) return None; } -pub pure fn is_block_non_doc_comment(s: &str) -> bool { +pub fn is_block_non_doc_comment(s: &str) -> bool { fail_unless!(s.len() >= 1u); str::all_between(s, 1u, s.len() - 1u, |ch| ch == '*') } @@ -779,7 +779,6 @@ pub mod test { use core::option::None; use diagnostic; use parse::token; - use util::testing::{check_equal, check_equal_ptr}; // represents a testing reader (incl. both reader and interner) struct Env { @@ -809,17 +808,17 @@ pub mod test { let tok2 = TokenAndSpan{ tok:token::IDENT(id, false), sp:span {lo:BytePos(21),hi:BytePos(23),expn_info: None}}; - check_equal (tok1,tok2); + assert_eq!(tok1,tok2); // the 'main' id is already read: - check_equal (copy string_reader.last_pos,BytePos(28)); + assert_eq!(copy string_reader.last_pos,BytePos(28)); // read another token: let tok3 = string_reader.next_token(); let tok4 = TokenAndSpan{ tok:token::IDENT(ident_interner.intern (@~"main"), false), sp:span {lo:BytePos(24),hi:BytePos(28),expn_info: None}}; - check_equal (tok3,tok4); + assert_eq!(tok3,tok4); // the lparen is already read: - check_equal (copy string_reader.last_pos,BytePos(29)) + assert_eq!(copy string_reader.last_pos,BytePos(29)) } // check that the given reader produces the desired stream @@ -828,7 +827,7 @@ pub mod test { for expected.each |expected_tok| { let TokenAndSpan {tok:actual_tok, sp: _} = env.string_reader.next_token(); - check_equal(&actual_tok,expected_tok); + assert_eq!(&actual_tok,expected_tok); } } @@ -872,21 +871,21 @@ pub mod test { let env = setup(~"'a'"); let TokenAndSpan {tok, sp: _} = env.string_reader.next_token(); - fail_unless!(tok == token::LIT_INT('a' as i64, ast::ty_char)); + assert_eq!(tok,token::LIT_INT('a' as i64, ast::ty_char)); } #[test] fn character_space() { let env = setup(~"' '"); let TokenAndSpan {tok, sp: _} = env.string_reader.next_token(); - fail_unless!(tok == token::LIT_INT(' ' as i64, ast::ty_char)); + assert_eq!(tok, token::LIT_INT(' ' as i64, ast::ty_char)); } #[test] fn character_escaped() { let env = setup(~"'\n'"); let TokenAndSpan {tok, sp: _} = env.string_reader.next_token(); - fail_unless!(tok == token::LIT_INT('\n' as i64, ast::ty_char)); + assert_eq!(tok, token::LIT_INT('\n' as i64, ast::ty_char)); } #[test] fn lifetime_name() { @@ -894,7 +893,7 @@ pub mod test { let TokenAndSpan {tok, sp: _} = env.string_reader.next_token(); let id = env.interner.intern(@~"abc"); - fail_unless!(tok == token::LIFETIME(id)); + assert_eq!(tok, token::LIFETIME(id)); } } diff --git a/src/libsyntax/parse/mod.rs b/src/libsyntax/parse/mod.rs index a133befb046a7..a0c73668a05f9 100644 --- a/src/libsyntax/parse/mod.rs +++ b/src/libsyntax/parse/mod.rs @@ -313,7 +313,6 @@ mod test { use std; use core::io; use core::option::None; - use util::testing::*; #[test] fn to_json_str>(val: @E) -> ~str { do io::with_str_writer |writer| { @@ -327,7 +326,7 @@ mod test { @~"fn foo (x : int) { x; }", ~[], new_parse_sess(None)); - check_equal(to_json_str(@tts), + assert_eq!(to_json_str(@tts), ~"[[\"tt_tok\",[null,[\"IDENT\",[\"fn\",false]]]],\ [\"tt_tok\",[null,[\"IDENT\",[\"foo\",false]]]],\ [\"tt_delim\",[[[\"tt_tok\",[null,[\"LPAREN\",[]]]],\ @@ -347,7 +346,7 @@ mod test { @~"fn foo (x : int) { x; }", ~[],~[], new_parse_sess(None)); - check_equal(ast1,ast2); + assert_eq!(ast1,ast2); } } diff --git a/src/libsyntax/parse/obsolete.rs b/src/libsyntax/parse/obsolete.rs index f5e83a1beae08..0f4de9257c99c 100644 --- a/src/libsyntax/parse/obsolete.rs +++ b/src/libsyntax/parse/obsolete.rs @@ -30,7 +30,7 @@ use core::str; use core::to_bytes; /// The specific types of unsupported syntax -#[deriving_eq] +#[deriving(Eq)] pub enum ObsoleteSyntax { ObsoleteLowerCaseKindBounds, ObsoleteLet, @@ -51,18 +51,21 @@ pub enum ObsoleteSyntax { ObsoleteTraitImplVisibility, ObsoleteRecordType, ObsoleteRecordPattern, - ObsoleteAssertion, ObsoletePostFnTySigil, ObsoleteBareFnType, ObsoleteNewtypeEnum, ObsoleteMode, ObsoleteImplicitSelf, ObsoleteLifetimeNotation, + ObsoleteConstManagedPointer, + ObsoletePurity, + ObsoleteStaticMethod, + ObsoleteConstItem, } impl to_bytes::IterBytes for ObsoleteSyntax { #[inline(always)] - pure fn iter_bytes(&self, +lsb0: bool, f: to_bytes::Cb) { + fn iter_bytes(&self, +lsb0: bool, f: to_bytes::Cb) { (*self as uint).iter_bytes(lsb0, f); } } @@ -162,10 +165,6 @@ pub impl Parser { "structural record pattern", "use a structure instead" ), - ObsoleteAssertion => ( - "assertion", - "use `fail_unless!()` instead" - ), ObsoletePostFnTySigil => ( "fn sigil in postfix position", "Rather than `fn@`, `fn~`, or `fn&`, \ @@ -193,6 +192,23 @@ pub impl Parser { "instead of `&foo/bar`, write `&'foo bar`; instead of \ `bar/&foo`, write `&bar<'foo>" ), + ObsoleteConstManagedPointer => ( + "const `@` pointer", + "instead of `@const Foo`, write `@Foo`" + ), + ObsoletePurity => ( + "pure function", + "remove `pure`" + ), + ObsoleteStaticMethod => ( + "`static` notation", + "`static` is superfluous; remove it" + ), + ObsoleteConstItem => ( + "`const` item", + "`const` items are now `static` items; replace `const` with \ + `static`" + ), }; self.report(sp, kind, kind_str, desc); diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 086bf86b4b268..af64bf07b7c3e 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -76,10 +76,12 @@ use parse::obsolete::{ObsoleteUnsafeBlock, ObsoleteImplSyntax}; use parse::obsolete::{ObsoleteTraitBoundSeparator, ObsoleteMutOwnedPointer}; use parse::obsolete::{ObsoleteMutVector, ObsoleteTraitImplVisibility}; use parse::obsolete::{ObsoleteRecordType, ObsoleteRecordPattern}; -use parse::obsolete::{ObsoleteAssertion, ObsoletePostFnTySigil}; +use parse::obsolete::{ObsoletePostFnTySigil}; use parse::obsolete::{ObsoleteBareFnType, ObsoleteNewtypeEnum}; use parse::obsolete::{ObsoleteMode, ObsoleteImplicitSelf}; -use parse::obsolete::{ObsoleteLifetimeNotation}; +use parse::obsolete::{ObsoleteLifetimeNotation, ObsoleteConstManagedPointer}; +use parse::obsolete::{ObsoletePurity, ObsoleteStaticMethod}; +use parse::obsolete::{ObsoleteConstItem}; use parse::prec::{as_prec, token_to_binop}; use parse::token::{can_begin_expr, is_ident, is_ident_or_path}; use parse::token::{is_plain_ident, INTERPOLATED, special_idents}; @@ -93,7 +95,7 @@ use core::either; use core::vec; use std::oldmap::HashMap; -#[deriving_eq] +#[deriving(Eq)] enum restriction { UNRESTRICTED, RESTRICT_STMT_EXPR, @@ -196,8 +198,8 @@ macro_rules! maybe_whole ( ) -pure fn maybe_append(+lhs: ~[attribute], rhs: Option<~[attribute]>) - -> ~[attribute] { +fn maybe_append(+lhs: ~[attribute], rhs: Option<~[attribute]>) + -> ~[attribute] { match rhs { None => lhs, Some(ref attrs) => vec::append(lhs, (*attrs)) @@ -268,6 +270,7 @@ pub struct Parser { } +#[unsafe_destructor] impl Drop for Parser { /* do not copy the parser; its state is tied to outside state */ fn finalize(&self) {} @@ -330,7 +333,7 @@ pub impl Parser { } fn get_id(&self) -> node_id { next_node_id(self.sess) } - pure fn id_to_str(&self, id: ident) -> @~str { + fn id_to_str(&self, id: ident) -> @~str { self.sess.interner.get(id) } @@ -412,7 +415,7 @@ pub impl Parser { fn parse_purity(&self) -> purity { if self.eat_keyword(&~"pure") { - // NB: We parse this as impure for bootstrapping purposes. + self.obsolete(*self.last_span, ObsoletePurity); return impure_fn; } else if self.eat_keyword(&~"unsafe") { return unsafe_fn; @@ -581,7 +584,9 @@ pub impl Parser { } } - fn parse_ty(&self, colons_before_params: bool) -> @Ty { + // Useless second parameter for compatibility with quasiquote macros. + // Bleh! + fn parse_ty(&self, _: bool) -> @Ty { maybe_whole!(self, nt_ty); let lo = self.span.lo; @@ -661,7 +666,7 @@ pub impl Parser { result } else if *self.token == token::MOD_SEP || is_ident_or_path(&*self.token) { - let path = self.parse_path_with_tps(colons_before_params); + let path = self.parse_path_with_tps(false); ty_path(path, self.get_id()) } else { self.fatal(~"expected type"); @@ -707,6 +712,9 @@ pub impl Parser { if mt.mutbl != m_imm && sigil == OwnedSigil { self.obsolete(*self.last_span, ObsoleteMutOwnedPointer); } + if mt.mutbl == m_const && sigil == ManagedSigil { + self.obsolete(*self.last_span, ObsoleteConstManagedPointer); + } ctor(mt) } @@ -902,6 +910,7 @@ pub impl Parser { && self.look_ahead(1u) == token::BINOP(token::AND) { self.bump(); self.bump(); + self.obsolete(*self.last_span, ObsoleteLifetimeNotation); match *self.token { token::IDENT(sid, _) => { let span = copy self.span; @@ -1210,10 +1219,6 @@ pub impl Parser { ex = expr_log(ast::log_other, lvl, e); hi = self.span.hi; self.expect(&token::RPAREN); - } else if self.eat_keyword(&~"assert") { - let e = self.parse_expr(); - ex = expr_copy(e); // whatever - self.obsolete(*self.last_span, ObsoleteAssertion); } else if self.eat_keyword(&~"return") { if can_begin_expr(&*self.token) { let e = self.parse_expr(); @@ -1633,6 +1638,10 @@ pub impl Parser { token::AT => { self.bump(); let m = self.parse_mutability(); + if m == m_const { + self.obsolete(*self.last_span, ObsoleteConstManagedPointer); + } + let e = self.parse_prefix_expr(); hi = e.span.hi; // HACK: turn @[...] into a @-evec @@ -2674,7 +2683,7 @@ pub impl Parser { fn parse_optional_purity(&self) -> ast::purity { if self.eat_keyword(&~"pure") { - // NB: We parse this as impure for bootstrapping purposes. + self.obsolete(*self.last_span, ObsoletePurity); ast::impure_fn } else if self.eat_keyword(&~"unsafe") { ast::unsafe_fn @@ -2694,49 +2703,52 @@ pub impl Parser { let mut result = opt_vec::Empty; loop { - if self.eat(&token::BINOP(token::AND)) { - if self.eat_keyword(&~"static") { - result.push(RegionTyParamBound); - } else { - self.span_err(*self.span, - ~"`&static` is the only permissible \ - region bound here"); + match *self.token { + token::LIFETIME(lifetime) => { + if str::eq_slice(*self.id_to_str(lifetime), "static") { + result.push(RegionTyParamBound); + } else { + self.span_err(*self.span, + ~"`'static` is the only permissible \ + region bound here"); + } + self.bump(); } - } else if is_ident(&*self.token) { - let maybe_bound = match *self.token { - token::IDENT(copy sid, _) => { - match *self.id_to_str(sid) { - ~"send" | - ~"copy" | - ~"const" | - ~"owned" => { - self.obsolete( - *self.span, - ObsoleteLowerCaseKindBounds); - - // Bogus value, but doesn't matter, since - // is an error - Some(TraitTyParamBound( - self.mk_ty_path(sid))) + token::IDENT(*) => { + let maybe_bound = match *self.token { + token::IDENT(copy sid, _) => { + match *self.id_to_str(sid) { + ~"send" | + ~"copy" | + ~"const" | + ~"owned" => { + self.obsolete( + *self.span, + ObsoleteLowerCaseKindBounds); + + // Bogus value, but doesn't matter, since + // is an error + Some(TraitTyParamBound( + self.mk_ty_path(sid))) + } + _ => None } - _ => None } - } - _ => fail!() - }; + _ => fail!() + }; - match maybe_bound { - Some(bound) => { - self.bump(); - result.push(bound); - } - None => { - let ty = self.parse_ty(false); - result.push(TraitTyParamBound(ty)); + match maybe_bound { + Some(bound) => { + self.bump(); + result.push(bound); + } + None => { + let ty = self.parse_ty(false); + result.push(TraitTyParamBound(ty)); + } } } - } else { - break; + _ => break, } if self.eat(&token::BINOP(token::PLUS)) { @@ -3328,8 +3340,14 @@ pub impl Parser { else if self.eat_keyword(&~"priv") { private } else { inherited } } + fn parse_staticness(&self) -> bool { - self.eat_keyword(&~"static") + if self.eat_keyword(&~"static") { + self.obsolete(*self.last_span, ObsoleteStaticMethod); + true + } else { + false + } } // given a termination token and a vector of already-parsed @@ -3547,7 +3565,9 @@ pub impl Parser { let lo = self.span.lo; // XXX: Obsolete; remove after snap. - if !self.eat_keyword(&~"const") { + if self.eat_keyword(&~"const") { + self.obsolete(*self.last_span, ObsoleteConstItem); + } else { self.expect_keyword(&~"static"); } @@ -3567,6 +3587,7 @@ pub impl Parser { fn parse_fn_purity(&self) -> purity { if self.eat_keyword(&~"fn") { impure_fn } else if self.eat_keyword(&~"pure") { + self.obsolete(*self.last_span, ObsoletePurity); self.expect_keyword(&~"fn"); // NB: We parse this as impure for bootstrapping purposes. impure_fn @@ -3942,6 +3963,9 @@ pub impl Parser { (self.is_keyword(&~"static") && !self.token_is_keyword(&~"fn", &self.look_ahead(1)))) { // CONST ITEM + if self.is_keyword(&~"const") { + self.obsolete(*self.span, ObsoleteConstItem); + } self.bump(); let (ident, item_, extra_attrs) = self.parse_item_const(); return iovi_item(self.mk_item(lo, self.last_span.hi, ident, item_, @@ -3966,7 +3990,7 @@ pub impl Parser { } if items_allowed && self.eat_keyword(&~"pure") { // PURE FUNCTION ITEM - // NB: We parse this as impure for bootstrapping purposes. + self.obsolete(*self.last_span, ObsoletePurity); self.expect_keyword(&~"fn"); let (ident, item_, extra_attrs) = self.parse_item_fn(impure_fn); return iovi_item(self.mk_item(lo, self.last_span.hi, ident, item_, diff --git a/src/libsyntax/parse/prec.rs b/src/libsyntax/parse/prec.rs index e2a89d2a28cc1..79adabec9b773 100644 --- a/src/libsyntax/parse/prec.rs +++ b/src/libsyntax/parse/prec.rs @@ -16,13 +16,13 @@ use parse::token::Token; use core::prelude::*; /// Unary operators have higher precedence than binary -pub const unop_prec: uint = 100u; +pub static unop_prec: uint = 100u; /** * Precedence of the `as` operator, which is a binary operator * but is not represented in the precedence table. */ -pub const as_prec: uint = 11u; +pub static as_prec: uint = 11u; /** * Maps a token to a record specifying the corresponding binary diff --git a/src/libsyntax/parse/token.rs b/src/libsyntax/parse/token.rs index c41b3aec09bdc..074bb13e19908 100644 --- a/src/libsyntax/parse/token.rs +++ b/src/libsyntax/parse/token.rs @@ -24,7 +24,7 @@ use std::oldmap::HashMap; #[auto_encode] #[auto_decode] -#[deriving_eq] +#[deriving(Eq)] pub enum binop { PLUS, MINUS, @@ -40,7 +40,7 @@ pub enum binop { #[auto_encode] #[auto_decode] -#[deriving_eq] +#[deriving(Eq)] pub enum Token { /* Expression-operator symbols. */ EQ, @@ -103,7 +103,7 @@ pub enum Token { #[auto_encode] #[auto_decode] -#[deriving_eq] +#[deriving(Eq)] /// For interpolation during macro expansion. pub enum nonterminal { nt_item(@ast::item), @@ -118,7 +118,7 @@ pub enum nonterminal { nt_matchers(~[ast::matcher]) } -pub pure fn binop_to_str(o: binop) -> ~str { +pub fn binop_to_str(o: binop) -> ~str { match o { PLUS => ~"+", MINUS => ~"-", @@ -228,7 +228,7 @@ pub fn to_str(in: @ident_interner, t: &Token) -> ~str { } } -pub pure fn can_begin_expr(t: &Token) -> bool { +pub fn can_begin_expr(t: &Token) -> bool { match *t { LPAREN => true, LBRACE => true, @@ -286,22 +286,22 @@ pub fn is_lit(t: &Token) -> bool { } } -pub pure fn is_ident(t: &Token) -> bool { +pub fn is_ident(t: &Token) -> bool { match *t { IDENT(_, _) => true, _ => false } } -pub pure fn is_ident_or_path(t: &Token) -> bool { +pub fn is_ident_or_path(t: &Token) -> bool { match *t { IDENT(_, _) | INTERPOLATED(nt_path(*)) => true, _ => false } } -pub pure fn is_plain_ident(t: &Token) -> bool { +pub fn is_plain_ident(t: &Token) -> bool { match *t { IDENT(_, false) => true, _ => false } } -pub pure fn is_bar(t: &Token) -> bool { +pub fn is_bar(t: &Token) -> bool { match *t { BINOP(OR) | OROR => true, _ => false } } @@ -309,50 +309,50 @@ pub pure fn is_bar(t: &Token) -> bool { pub mod special_idents { use ast::ident; - pub const underscore : ident = ident { repr: 0u }; - pub const anon : ident = ident { repr: 1u }; - pub const dtor : ident = ident { repr: 2u }; // 'drop', but that's + pub static underscore : ident = ident { repr: 0u }; + pub static anon : ident = ident { repr: 1u }; + pub static dtor : ident = ident { repr: 2u }; // 'drop', but that's // reserved - pub const invalid : ident = ident { repr: 3u }; // '' - pub const unary : ident = ident { repr: 4u }; - pub const not_fn : ident = ident { repr: 5u }; - pub const idx_fn : ident = ident { repr: 6u }; - pub const unary_minus_fn : ident = ident { repr: 7u }; - pub const clownshoes_extensions : ident = ident { repr: 8u }; + pub static invalid : ident = ident { repr: 3u }; // '' + pub static unary : ident = ident { repr: 4u }; + pub static not_fn : ident = ident { repr: 5u }; + pub static idx_fn : ident = ident { repr: 6u }; + pub static unary_minus_fn : ident = ident { repr: 7u }; + pub static clownshoes_extensions : ident = ident { repr: 8u }; - pub const self_ : ident = ident { repr: 9u }; // 'self' + pub static self_ : ident = ident { repr: 9u }; // 'self' /* for matcher NTs */ - pub const item : ident = ident { repr: 10u }; - pub const block : ident = ident { repr: 11u }; - pub const stmt : ident = ident { repr: 12u }; - pub const pat : ident = ident { repr: 13u }; - pub const expr : ident = ident { repr: 14u }; - pub const ty : ident = ident { repr: 15u }; - pub const ident : ident = ident { repr: 16u }; - pub const path : ident = ident { repr: 17u }; - pub const tt : ident = ident { repr: 18u }; - pub const matchers : ident = ident { repr: 19u }; - - pub const str : ident = ident { repr: 20u }; // for the type + pub static item : ident = ident { repr: 10u }; + pub static block : ident = ident { repr: 11u }; + pub static stmt : ident = ident { repr: 12u }; + pub static pat : ident = ident { repr: 13u }; + pub static expr : ident = ident { repr: 14u }; + pub static ty : ident = ident { repr: 15u }; + pub static ident : ident = ident { repr: 16u }; + pub static path : ident = ident { repr: 17u }; + pub static tt : ident = ident { repr: 18u }; + pub static matchers : ident = ident { repr: 19u }; + + pub static str : ident = ident { repr: 20u }; // for the type /* outside of libsyntax */ - pub const ty_visitor : ident = ident { repr: 21u }; - pub const arg : ident = ident { repr: 22u }; - pub const descrim : ident = ident { repr: 23u }; - pub const clownshoe_abi : ident = ident { repr: 24u }; - pub const clownshoe_stack_shim : ident = ident { repr: 25u }; - pub const tydesc : ident = ident { repr: 26u }; - pub const literally_dtor : ident = ident { repr: 27u }; - pub const main : ident = ident { repr: 28u }; - pub const opaque : ident = ident { repr: 29u }; - pub const blk : ident = ident { repr: 30u }; - pub const static : ident = ident { repr: 31u }; - pub const intrinsic : ident = ident { repr: 32u }; - pub const clownshoes_foreign_mod: ident = ident { repr: 33 }; - pub const unnamed_field: ident = ident { repr: 34 }; - pub const c_abi: ident = ident { repr: 35 }; - pub const type_self: ident = ident { repr: 36 }; // `Self` + pub static ty_visitor : ident = ident { repr: 21u }; + pub static arg : ident = ident { repr: 22u }; + pub static descrim : ident = ident { repr: 23u }; + pub static clownshoe_abi : ident = ident { repr: 24u }; + pub static clownshoe_stack_shim : ident = ident { repr: 25u }; + pub static tydesc : ident = ident { repr: 26u }; + pub static literally_dtor : ident = ident { repr: 27u }; + pub static main : ident = ident { repr: 28u }; + pub static opaque : ident = ident { repr: 29u }; + pub static blk : ident = ident { repr: 30u }; + pub static static : ident = ident { repr: 31u }; + pub static intrinsic : ident = ident { repr: 32u }; + pub static clownshoes_foreign_mod: ident = ident { repr: 33 }; + pub static unnamed_field: ident = ident { repr: 34 }; + pub static c_abi: ident = ident { repr: 35 }; + pub static type_self: ident = ident { repr: 36 }; // `Self` } pub struct ident_interner { @@ -366,7 +366,7 @@ pub impl ident_interner { fn gensym(&self, val: @~str) -> ast::ident { ast::ident { repr: self.interner.gensym(val) } } - pure fn get(&self, idx: ast::ident) -> @~str { + fn get(&self, idx: ast::ident) -> @~str { self.interner.get(idx.repr) } fn len(&self) -> uint { @@ -488,7 +488,7 @@ pub fn temporary_keyword_table() -> HashMap<~str, ()> { pub fn strict_keyword_table() -> HashMap<~str, ()> { let words = HashMap(); let keys = ~[ - ~"as", ~"assert", + ~"as", ~"break", ~"const", ~"copy", ~"do", ~"drop", diff --git a/src/libsyntax/print/pp.rs b/src/libsyntax/print/pp.rs index 492ecdb3f4de5..af9cb7b841ef6 100644 --- a/src/libsyntax/print/pp.rs +++ b/src/libsyntax/print/pp.rs @@ -66,7 +66,7 @@ use core::vec; * line (which it can't) and so naturally place the content on its own line to * avoid combining it with other lines and making matters even worse. */ -#[deriving_eq] +#[deriving(Eq)] pub enum breaks { consistent, inconsistent, } pub struct break_t { @@ -117,7 +117,7 @@ pub fn tok_str(++t: token) -> ~str { pub fn buf_str(toks: ~[token], szs: ~[int], left: uint, right: uint, lim: uint) -> ~str { let n = vec::len(toks); - fail_unless!((n == vec::len(szs))); + fail_unless!(n == vec::len(szs)); let mut i = left; let mut L = lim; let mut s = ~"["; @@ -139,7 +139,7 @@ pub struct print_stack_elt { pbreak: print_stack_break } -pub const size_infinity: int = 0xffff; +pub static size_infinity: int = 0xffff; pub fn mk_printer(out: @io::Writer, linewidth: uint) -> @mut Printer { // Yes 3, it makes the ring buffers big enough to never diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index ba9a5082132e7..9a9834c488b19 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -92,10 +92,10 @@ pub fn rust_printer(writer: @io::Writer, intr: @ident_interner) -> @ps { }; } -pub const indent_unit: uint = 4u; -pub const match_indent_unit: uint = 2u; +pub static indent_unit: uint = 4u; +pub static match_indent_unit: uint = 2u; -pub const default_columns: uint = 78u; +pub static 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 @@ -180,12 +180,12 @@ pub fn path_to_str(&&p: @ast::path, intr: @ident_interner) -> ~str { to_str(p, |a,b| print_path(a, b, false), intr) } -pub fn fun_to_str(decl: &ast::fn_decl, name: ast::ident, +pub fn fun_to_str(decl: &ast::fn_decl, purity: ast::purity, name: ast::ident, opt_self_ty: Option, generics: &ast::Generics, intr: @ident_interner) -> ~str { do io::with_str_writer |wr| { let s = rust_printer(wr, intr); - print_fn(s, decl, None, name, generics, opt_self_ty, ast::inherited); + print_fn(s, decl, purity, name, generics, opt_self_ty, ast::inherited); end(s); // Close the head box end(s); // Close the outer box eof(s.s); @@ -370,10 +370,6 @@ pub fn print_opt_lifetime(s: @ps, lifetime: Option<@ast::Lifetime>) { } pub fn print_type(s: @ps, &&ty: @ast::Ty) { - print_type_ex(s, ty, false); -} - -pub fn print_type_ex(s: @ps, &&ty: @ast::Ty, print_colons: bool) { maybe_print_comment(s, ty.span.lo); ibox(s, 0u); match ty.node { @@ -415,7 +411,7 @@ pub fn print_type_ex(s: @ps, &&ty: @ast::Ty, print_colons: bool) { f.purity, f.onceness, &f.decl, None, None, None); } - ast::ty_path(path, _) => print_path(s, path, print_colons), + ast::ty_path(path, _) => print_path(s, path, false), ast::ty_fixed_length_vec(ref mt, v) => { word(s.s, ~"["); match mt.mutbl { @@ -445,7 +441,7 @@ pub fn print_foreign_item(s: @ps, item: @ast::foreign_item) { print_outer_attributes(s, item.attrs); match item.node { ast::foreign_item_fn(ref decl, purity, ref generics) => { - print_fn(s, decl, Some(purity), item.ident, generics, None, + print_fn(s, decl, purity, item.ident, generics, None, ast::inherited); end(s); // end head-ibox word(s.s, ~";"); @@ -488,7 +484,7 @@ pub fn print_item(s: @ps, &&item: @ast::item) { print_fn( s, decl, - Some(purity), + purity, item.ident, typarams, None, @@ -819,7 +815,7 @@ pub fn print_method(s: @ps, meth: @ast::method) { hardbreak_if_not_bol(s); maybe_print_comment(s, meth.span.lo); print_outer_attributes(s, meth.attrs); - print_fn(s, &meth.decl, Some(meth.purity), + print_fn(s, &meth.decl, meth.purity, meth.ident, &meth.generics, Some(meth.self_ty.node), meth.vis); word(s.s, ~" "); @@ -1211,7 +1207,7 @@ pub fn print_expr(s: @ps, &&expr: @ast::expr) { print_expr(s, expr); space(s.s); word_space(s, ~"as"); - print_type_ex(s, ty, true); + print_type(s, ty); } ast::expr_if(test, ref blk, elseopt) => { print_if(s, test, blk, elseopt, false); @@ -1667,7 +1663,7 @@ pub fn print_self_ty(s: @ps, self_ty: ast::self_ty_) -> bool { pub fn print_fn(s: @ps, decl: &ast::fn_decl, - purity: Option, + purity: ast::purity, name: ast::ident, generics: &ast::Generics, opt_self_ty: Option, @@ -1759,7 +1755,7 @@ pub fn print_bounds(s: @ps, bounds: @OptVec) { match *bound { TraitTyParamBound(ty) => print_type(s, ty), - RegionTyParamBound => word(s.s, ~"&static"), + RegionTyParamBound => word(s.s, ~"'static"), } } } @@ -1934,7 +1930,6 @@ pub fn print_ty_fn(s: @ps, // Duplicates the logic in `print_fn_header_info()`. This is because that // function prints the sigil in the wrong place. That should be fixed. - print_self_ty_if_static(s, opt_self_ty); print_opt_abi(s, opt_abi); print_opt_sigil(s, opt_sigil); print_opt_lifetime(s, opt_region); @@ -2163,24 +2158,6 @@ pub fn next_comment(s: @ps) -> Option { } } -pub fn print_self_ty_if_static(s: @ps, - opt_self_ty: Option) { - match opt_self_ty { - Some(ast::sty_static) => { word(s.s, ~"static "); } - _ => {} - } -} - -pub fn print_opt_purity(s: @ps, opt_purity: Option) { - match opt_purity { - Some(ast::impure_fn) => { } - Some(purity) => { - word_nbsp(s, purity_to_str(purity)); - } - None => {} - } -} - pub fn print_opt_abi(s: @ps, opt_abi: Option) { match opt_abi { Some(ast::RustAbi) => { word_nbsp(s, ~"extern"); } @@ -2199,13 +2176,12 @@ pub fn print_opt_sigil(s: @ps, opt_sigil: Option) { pub fn print_fn_header_info(s: @ps, opt_sty: Option, - opt_purity: Option, + purity: ast::purity, onceness: ast::Onceness, opt_sigil: Option, vis: ast::visibility) { - print_self_ty_if_static(s, opt_sty); word(s.s, visibility_qualified(vis, ~"")); - print_opt_purity(s, opt_purity); + print_purity(s, purity); print_onceness(s, onceness); word(s.s, ~"fn"); print_opt_sigil(s, opt_sigil); @@ -2218,7 +2194,7 @@ pub fn opt_sigil_to_str(opt_p: Option) -> ~str { } } -pub pure fn purity_to_str(p: ast::purity) -> ~str { +pub fn purity_to_str(p: ast::purity) -> ~str { match p { ast::impure_fn => ~"impure", ast::unsafe_fn => ~"unsafe", @@ -2227,7 +2203,7 @@ pub pure fn purity_to_str(p: ast::purity) -> ~str { } } -pub pure fn onceness_to_str(o: ast::Onceness) -> ~str { +pub fn onceness_to_str(o: ast::Onceness) -> ~str { match o { ast::Once => ~"once", ast::Many => ~"many" @@ -2258,7 +2234,6 @@ pub mod test { use core::cmp::Eq; use core::option::None; use parse; - use util::testing::check_equal; fn string_check (given : &T, expected: &T) { if !(given == expected) { @@ -2279,8 +2254,9 @@ pub mod test { cf: ast::return_val }; let generics = ast_util::empty_generics(); - check_equal (&fun_to_str(&decl, abba_ident, None, &generics, mock_interner), - &~"fn abba()"); + assert_eq!(&fun_to_str(&decl, ast::impure_fn, abba_ident, + None, &generics, mock_interner), + &~"fn abba()"); } #[test] @@ -2299,7 +2275,7 @@ pub mod test { }); let varstr = variant_to_str(var,mock_interner); - check_equal(&varstr,&~"pub principal_skinner"); + assert_eq!(&varstr,&~"pub principal_skinner"); } } diff --git a/src/libsyntax/syntax.rc b/src/libsyntax/syntax.rc index 912846d9f0f8b..19ed68093267a 100644 --- a/src/libsyntax/syntax.rc +++ b/src/libsyntax/syntax.rc @@ -46,7 +46,6 @@ pub mod visit; pub mod fold; pub mod util { pub mod interner; - pub mod testing; } @@ -64,6 +63,8 @@ pub mod ext { pub mod expand; pub mod quote; + + #[path = "deriving/mod.rs"] pub mod deriving; pub mod build; diff --git a/src/libsyntax/util/interner.rs b/src/libsyntax/util/interner.rs index 47f49ebadaabf..159a205637b59 100644 --- a/src/libsyntax/util/interner.rs +++ b/src/libsyntax/util/interner.rs @@ -22,14 +22,14 @@ pub struct Interner { // when traits can extend traits, we should extend index to get [] pub impl Interner { - static fn new() -> Interner { + fn new() -> Interner { Interner { map: @mut LinearMap::new(), vect: @mut ~[], } } - static fn prefill(init: &[T]) -> Interner { + fn prefill(init: &[T]) -> Interner { let rv = Interner::new(); for init.each() |v| { rv.intern(*v); } rv @@ -61,7 +61,7 @@ pub impl Interner { // this isn't "pure" in the traditional sense, because it can go from // failing to returning a value as items are interned. But for typestate, // where we first check a pred and then rely on it, ceasing to fail is ok. - pure fn get(&self, idx: uint) -> T { self.vect[idx] } + fn get(&self, idx: uint) -> T { self.vect[idx] } fn len(&self) -> uint { let vect = &*self.vect; vect.len() } } @@ -77,32 +77,32 @@ pub fn i1 () { pub fn i2 () { let i : Interner<@~str> = Interner::new(); // first one is zero: - fail_unless!(i.intern (@~"dog") == 0); + assert_eq!(i.intern (@~"dog"), 0); // re-use gets the same entry: - fail_unless!(i.intern (@~"dog") == 0); + assert_eq!(i.intern (@~"dog"), 0); // different string gets a different #: - fail_unless!(i.intern (@~"cat") == 1); - fail_unless!(i.intern (@~"cat") == 1); + assert_eq!(i.intern (@~"cat"), 1); + assert_eq!(i.intern (@~"cat"), 1); // dog is still at zero - fail_unless!(i.intern (@~"dog") == 0); + assert_eq!(i.intern (@~"dog"), 0); // gensym gets 3 - fail_unless!(i.gensym (@~"zebra" ) == 2); + assert_eq!(i.gensym (@~"zebra" ), 2); // gensym of same string gets new number : - fail_unless!(i.gensym (@~"zebra" ) == 3); + assert_eq!(i.gensym (@~"zebra" ), 3); // gensym of *existing* string gets new number: - fail_unless!(i.gensym (@~"dog") == 4); - fail_unless!(i.get(0) == @~"dog"); - fail_unless!(i.get(1) == @~"cat"); - fail_unless!(i.get(2) == @~"zebra"); - fail_unless!(i.get(3) == @~"zebra"); - fail_unless!(i.get(4) == @~"dog"); + assert_eq!(i.gensym (@~"dog"), 4); + assert_eq!(i.get(0), @~"dog"); + assert_eq!(i.get(1), @~"cat"); + assert_eq!(i.get(2), @~"zebra"); + assert_eq!(i.get(3), @~"zebra"); + assert_eq!(i.get(4), @~"dog"); } #[test] pub fn i3 () { let i : Interner<@~str> = Interner::prefill([@~"Alan",@~"Bob",@~"Carol"]); - fail_unless!(i.get(0) == @~"Alan"); - fail_unless!(i.get(1) == @~"Bob"); - fail_unless!(i.get(2) == @~"Carol"); - fail_unless!(i.intern(@~"Bob") == 1); + assert_eq!(i.get(0), @~"Alan"); + assert_eq!(i.get(1), @~"Bob"); + assert_eq!(i.get(2), @~"Carol"); + assert_eq!(i.intern(@~"Bob"), 1); } diff --git a/src/libsyntax/util/testing.rs b/src/libsyntax/util/testing.rs deleted file mode 100644 index 78a175df29f27..0000000000000 --- a/src/libsyntax/util/testing.rs +++ /dev/null @@ -1,24 +0,0 @@ -// Copyright 2012 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -// support for test cases. -use core::cmp; - -pub pure fn check_equal_ptr (given : &T, expected: &T) { - if !((given == expected) && (expected == given )) { - fail!(fmt!("given %?, expected %?",given,expected)); - } -} - -pub pure fn check_equal (given : T, expected: T) { - if !((given == expected) && (expected == given )) { - fail!(fmt!("given %?, expected %?",given,expected)); - } -} diff --git a/src/rt/arch/arm/sp.h b/src/rt/arch/arm/sp.h new file mode 100644 index 0000000000000..cd79884760777 --- /dev/null +++ b/src/rt/arch/arm/sp.h @@ -0,0 +1,29 @@ +// Copyright 2012 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// Getting the stack pointer and getting/setting sp limit. + +#ifndef SP_H +#define SP_H + +#include "../../rust_globals.h" + +// Gets a pointer to the vicinity of the current stack pointer +extern "C" uintptr_t get_sp(); + +// Gets the pointer to the end of the Rust stack from a platform- +// specific location in the thread control block +extern "C" CDECL uintptr_t get_sp_limit(); + +// Records the pointer to the end of the Rust stack in a platform- +// specific location in the thread control block +extern "C" CDECL void record_sp_limit(void *limit); + +#endif diff --git a/src/rt/arch/i386/record_sp.S b/src/rt/arch/i386/record_sp.S index 20cafa3dffbf5..e69de29bb2d1d 100644 --- a/src/rt/arch/i386/record_sp.S +++ b/src/rt/arch/i386/record_sp.S @@ -1,60 +0,0 @@ -.text - -#if defined(__APPLE__) || defined(_WIN32) -#define RECORD_SP_LIMIT _record_sp_limit -#define GET_SP_LIMIT _get_sp_limit -#define GET_SP _get_sp -#else -#define RECORD_SP_LIMIT record_sp_limit -#define GET_SP_LIMIT get_sp_limit -#define GET_SP get_sp -#endif - -.globl RECORD_SP_LIMIT -.globl GET_SP_LIMIT -.globl GET_SP - -#if defined(__linux__) || defined(__FreeBSD__) -RECORD_SP_LIMIT: - movl 4(%esp), %eax - movl %eax, %gs:48 - ret -#endif - -#if defined(__APPLE__) -RECORD_SP_LIMIT: - movl $0x48+90*4, %eax - movl 4(%esp), %ecx - movl %ecx, %gs:(%eax) - ret -#endif - -#if defined(_WIN32) -RECORD_SP_LIMIT: - movl 4(%esp), %eax - movl %eax, %fs:0x14 - ret -#endif - -#if defined(__linux__) || defined(__FreeBSD__) -GET_SP_LIMIT: - movl %gs:48, %eax - ret -#endif - -#if defined(__APPLE__) -GET_SP_LIMIT: - movl $0x48+90*4, %ecx - movl %gs:(%ecx), %eax - ret -#endif - -#if defined(_WIN32) -GET_SP_LIMIT: - movl %fs:0x14, %eax - ret -#endif - -GET_SP: - movl %esp, %eax - ret diff --git a/src/rt/arch/i386/sp.h b/src/rt/arch/i386/sp.h new file mode 100644 index 0000000000000..4f4c84c817573 --- /dev/null +++ b/src/rt/arch/i386/sp.h @@ -0,0 +1,71 @@ +// Copyright 2012 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// Getting the stack pointer and getting/setting sp limit. + +#ifndef SP_H +#define SP_H + +#include "../../rust_globals.h" + +// Gets a pointer to the vicinity of the current stack pointer +extern "C" ALWAYS_INLINE uintptr_t get_sp() { + uintptr_t sp; + asm volatile ( + "movl %%esp, %0" + : "=m"(sp)); + return sp; +} + +// Gets the pointer to the end of the Rust stack from a platform- +// specific location in the thread control block +extern "C" CDECL ALWAYS_INLINE uintptr_t get_sp_limit() { + uintptr_t limit; + +#if defined(__linux__) || defined(__FreeBSD__) + asm volatile ( + "movl %%gs:48, %0" + : "=r"(limit)); +#elif defined(__APPLE__) + asm volatile ( + "movl $0x48+90*4, %%ecx\n\t" + "movl %%gs:(%%ecx), %0" + : "=r"(limit) + :: "ecx"); +#elif defined(_WIN32) + asm volatile ( + "movl %%fs:0x14, %0" + : "=r"(limit)); +#endif + + return limit; +} + +// Records the pointer to the end of the Rust stack in a platform- +// specific location in the thread control block +extern "C" CDECL ALWAYS_INLINE void record_sp_limit(void *limit) { +#if defined(__linux__) || defined(__FreeBSD__) + asm volatile ( + "movl %0, %%gs:48" + :: "r"(limit)); +#elif defined(__APPLE__) + asm volatile ( + "movl $0x48+90*4, %%eax\n\t" + "movl %0, %%gs:(%%eax)" + :: "r"(limit) + : "eax"); +#elif defined(_WIN32) + asm volatile ( + "movl %0, %%fs:0x14" + :: "r"(limit)); +#endif +} + +#endif diff --git a/src/rt/arch/mips/sp.h b/src/rt/arch/mips/sp.h new file mode 100644 index 0000000000000..cd79884760777 --- /dev/null +++ b/src/rt/arch/mips/sp.h @@ -0,0 +1,29 @@ +// Copyright 2012 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// Getting the stack pointer and getting/setting sp limit. + +#ifndef SP_H +#define SP_H + +#include "../../rust_globals.h" + +// Gets a pointer to the vicinity of the current stack pointer +extern "C" uintptr_t get_sp(); + +// Gets the pointer to the end of the Rust stack from a platform- +// specific location in the thread control block +extern "C" CDECL uintptr_t get_sp_limit(); + +// Records the pointer to the end of the Rust stack in a platform- +// specific location in the thread control block +extern "C" CDECL void record_sp_limit(void *limit); + +#endif diff --git a/src/rt/arch/x86_64/record_sp.S b/src/rt/arch/x86_64/record_sp.S index 0999e19f32885..e69de29bb2d1d 100644 --- a/src/rt/arch/x86_64/record_sp.S +++ b/src/rt/arch/x86_64/record_sp.S @@ -1,52 +0,0 @@ -.text - -#if defined(__APPLE__) || defined(_WIN32) -#define RECORD_SP_LIMIT _record_sp_limit -#define GET_SP_LIMIT _get_sp_limit -#define GET_SP _get_sp -#else -#define RECORD_SP_LIMIT record_sp_limit -#define GET_SP_LIMIT get_sp_limit -#define GET_SP get_sp -#endif - -.globl RECORD_SP_LIMIT -.globl GET_SP_LIMIT -.globl GET_SP - -#if defined(__linux__) -RECORD_SP_LIMIT: - movq %rdi, %fs:112 - ret -#elif defined(__APPLE__) -RECORD_SP_LIMIT: - movq $0x60+90*8, %rsi - movq %rdi, %gs:(%rsi) - ret -#elif defined(__FreeBSD__) -RECORD_SP_LIMIT: - movq %rdi, %fs:24 - ret -#else -RECORD_SP_LIMIT: - ret -#endif - -#if defined(__linux__) -GET_SP_LIMIT: - movq %fs:112, %rax - ret -#elif defined(__APPLE__) -GET_SP_LIMIT: - movq $0x60+90*8, %rsi - movq %gs:(%rsi), %rax - ret -#elif defined(__FreeBSD__) -GET_SP_LIMIT: - movq %fs:24, %rax - ret -#endif - -GET_SP: - movq %rsp, %rax - ret diff --git a/src/rt/arch/x86_64/sp.h b/src/rt/arch/x86_64/sp.h new file mode 100644 index 0000000000000..bf011f4d01976 --- /dev/null +++ b/src/rt/arch/x86_64/sp.h @@ -0,0 +1,71 @@ +// Copyright 2012 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// Getting the stack pointer and getting/setting sp limit. + +#ifndef SP_H +#define SP_H + +#include "../../rust_globals.h" + +// Gets a pointer to the vicinity of the current stack pointer +extern "C" ALWAYS_INLINE uintptr_t get_sp() { + uintptr_t sp; + asm volatile ( + "movq %%rsp, %0" + : "=m"(sp)); + return sp; +} + +// Gets the pointer to the end of the Rust stack from a platform- +// specific location in the thread control block +extern "C" CDECL ALWAYS_INLINE uintptr_t get_sp_limit() { + uintptr_t limit; + +#if defined(__linux__) + asm volatile ( + "movq %%fs:112, %0" + : "=r"(limit)); +#elif defined(__APPLE__) + asm volatile ( + "movq $0x60+90*8, %%rsi\n\t" + "movq %%gs:(%%rsi), %0" + : "=r"(limit) + :: "rsi"); +#elif defined(__FreeBSD__) + asm volatile ( + "movq %%fs:24, %0" + : "=r"(limit)); +#endif + + return limit; +} + +// Records the pointer to the end of the Rust stack in a platform- +// specific location in the thread control block +extern "C" CDECL ALWAYS_INLINE void record_sp_limit(void *limit) { +#if defined(__linux__) + asm volatile ( + "movq %0, %%fs:112" + :: "r"(limit)); +#elif defined(__APPLE__) + asm volatile ( + "movq $0x60+90*8, %%rsi\n\t" + "movq %0, %%gs:(%%rsi)" + :: "r"(limit) + : "rsi"); +#elif defined(__FreeBSD__) + asm volatile ( + "movq %0, %%fs:24" + :: "r"(limit)); +#endif +} + +#endif diff --git a/src/rt/rust.cpp b/src/rt/rust.cpp index d9ef6a52dbef6..803da32cbc8ac 100644 --- a/src/rt/rust.cpp +++ b/src/rt/rust.cpp @@ -21,17 +21,6 @@ void* global_crate_map = NULL; -#ifndef _WIN32 -pthread_key_t sched_key; -#else -DWORD sched_key; -#endif - -extern "C" void* -rust_get_sched_tls_key() { - return &sched_key; -} - /** The runtime entrypoint. The (C ABI) main function generated by rustc calls `rust_start`, providing the address of the Rust ABI main function, the @@ -41,10 +30,6 @@ rust_get_sched_tls_key() { extern "C" CDECL int rust_start(uintptr_t main_fn, int argc, char **argv, void* crate_map) { -#ifndef _WIN32 - pthread_key_create(&sched_key, NULL); -#endif - // Load runtime configuration options from the environment. // FIXME #1497: Should provide a way to get these from the command // line as well. diff --git a/src/rt/rust_builtin.cpp b/src/rt/rust_builtin.cpp index a2053c115bbbf..f586e05772b76 100644 --- a/src/rt/rust_builtin.cpp +++ b/src/rt/rust_builtin.cpp @@ -882,6 +882,46 @@ rust_get_rt_env() { return task->kernel->env; } +typedef void *(*nullary_fn)(); + +extern "C" CDECL void +rust_call_nullary_fn(nullary_fn f) { + f(); +} + +#ifndef _WIN32 +pthread_key_t sched_key; +#else +DWORD sched_key; +#endif + +extern "C" void* +rust_get_sched_tls_key() { + return &sched_key; +} + +// Initialize the global state required by the new scheduler +extern "C" CDECL void +rust_initialize_global_state() { + + static lock_and_signal init_lock; + static bool initialized = false; + + scoped_lock with(init_lock); + + if (!initialized) { + +#ifndef _WIN32 + assert(!pthread_key_create(&sched_key, NULL)); +#else + sched_key = TlsAlloc(); + assert(sched_key != TLS_OUT_OF_INDEXES); +#endif + + initialized = true; + } +} + // // Local Variables: // mode: C++ diff --git a/src/rt/rust_globals.h b/src/rt/rust_globals.h index 3d3ce7562b5ed..ff57af0833713 100644 --- a/src/rt/rust_globals.h +++ b/src/rt/rust_globals.h @@ -11,6 +11,22 @@ #ifndef RUST_GLOBALS_H #define RUST_GLOBALS_H +#if defined(__cplusplus) +#define INLINE inline +#elif defined(_MSC_VER) || defined(__GNUC__) +#define INLINE __inline__ +#else +#define INLINE inline +#endif + +#if defined(__GNUC__) +#define ALWAYS_INLINE __attribute((always_inline)) INLINE +#elif defined(_MSC_VER) +#define ALWAYS_INLINE __forceinline +#else +#define ALWAYS_INLINE INLINE +#endif + #ifndef __STDC_LIMIT_MACROS #define __STDC_LIMIT_MACROS 1 #endif diff --git a/src/rt/rust_sched_loop.cpp b/src/rt/rust_sched_loop.cpp index c215752d8dd39..90393acdd59d6 100644 --- a/src/rt/rust_sched_loop.cpp +++ b/src/rt/rust_sched_loop.cpp @@ -19,7 +19,7 @@ pthread_key_t rust_sched_loop::task_key; DWORD rust_sched_loop::task_key; #endif -const size_t C_STACK_SIZE = 1024*1024; +const size_t C_STACK_SIZE = 2*1024*1024; bool rust_sched_loop::tls_initialized = false; diff --git a/src/rt/rust_task.h b/src/rt/rust_task.h index 8c9ec172c45ec..00d20fefc0ee5 100644 --- a/src/rt/rust_task.h +++ b/src/rt/rust_task.h @@ -118,6 +118,7 @@ #include "rust_stack.h" #include "rust_type.h" #include "rust_sched_loop.h" +#include "sp.h" // The amount of extra space at the end of each stack segment, available // to the rt, compiler and dynamic linker for running small functions @@ -419,15 +420,6 @@ template struct task_owned { } }; -// This stuff is on the stack-switching fast path - -// Records the pointer to the end of the Rust stack in a platform- -// specific location in the thread control block -extern "C" CDECL void record_sp_limit(void *limit); -extern "C" CDECL uintptr_t get_sp_limit(); -// Gets a pointer to the vicinity of the current stack pointer -extern "C" uintptr_t get_sp(); - // This is the function that switches between the C and the Rust stack by // calling another function with a single void* argument while changing the // stack pointer. It has a funny name because gdb doesn't normally like to @@ -600,9 +592,6 @@ rust_task::prev_stack() { record_stack_limit(); } -extern "C" CDECL void -record_sp_limit(void *limit); - // The LLVM-generated segmented-stack function prolog compares the amount of // stack needed for each frame to the end-of-stack pointer stored in the // TCB. As an optimization, when the frame size is less than 256 bytes, it diff --git a/src/rt/rust_uv.cpp b/src/rt/rust_uv.cpp index 5159434873733..325b10b92df6b 100644 --- a/src/rt/rust_uv.cpp +++ b/src/rt/rust_uv.cpp @@ -479,6 +479,34 @@ extern "C" struct sockaddr_in6 rust_uv_ip6_addr(const char* ip, int port) { return uv_ip6_addr(ip, port); } + +extern "C" struct sockaddr_in* +rust_uv_ip4_addrp(const char* ip, int port) { + struct sockaddr_in addr = uv_ip4_addr(ip, port); + struct sockaddr_in *addrp = (sockaddr_in*)malloc(sizeof(struct sockaddr_in)); + assert(addrp); + memcpy(addrp, &addr, sizeof(struct sockaddr_in)); + return addrp; +} +extern "C" struct sockaddr_in6* +rust_uv_ip6_addrp(const char* ip, int port) { + struct sockaddr_in6 addr = uv_ip6_addr(ip, port); + struct sockaddr_in6 *addrp = (sockaddr_in6*)malloc(sizeof(struct sockaddr_in6)); + assert(addrp); + memcpy(addrp, &addr, sizeof(struct sockaddr_in6)); + return addrp; +} + +extern "C" void +rust_uv_free_ip4_addr(sockaddr_in *addrp) { + free(addrp); +} + +extern "C" void +rust_uv_free_ip6_addr(sockaddr_in6 *addrp) { + free(addrp); +} + extern "C" int rust_uv_ip4_name(struct sockaddr_in* src, char* dst, size_t size) { return uv_ip4_name(src, dst, size); @@ -563,3 +591,23 @@ extern "C" int rust_uv_idle_stop(uv_idle_t* idle) { return uv_idle_stop(idle); } + +extern "C" size_t +rust_uv_handle_size(uintptr_t type) { + return uv_handle_size((uv_handle_type)type); +} + +extern "C" size_t +rust_uv_req_size(uintptr_t type) { + return uv_req_size((uv_req_type)type); +} + +extern "C" uintptr_t +rust_uv_handle_type_max() { + return UV_HANDLE_TYPE_MAX; +} + +extern "C" uintptr_t +rust_uv_req_type_max() { + return UV_REQ_TYPE_MAX; +} diff --git a/src/rt/rustrt.def.in b/src/rt/rustrt.def.in index 5a8868f33f9f9..59fd8991622c6 100644 --- a/src/rt/rustrt.def.in +++ b/src/rt/rustrt.def.in @@ -202,3 +202,15 @@ rust_dbg_extern_identity_TwoU64s rust_dbg_extern_identity_double rust_dbg_extern_identity_u8 rust_get_rt_env +rust_uv_handle_size +rust_uv_req_size +rust_uv_handle_type_max +rust_uv_req_type_max +rust_uv_ip4_addrp +rust_uv_ip6_addrp +rust_uv_free_ip4_addr +rust_uv_free_ip6_addr +rust_call_nullary_fn +rust_initialize_global_state + + diff --git a/src/snapshots.txt b/src/snapshots.txt index 31acfa81100d3..7116e32b28390 100644 --- a/src/snapshots.txt +++ b/src/snapshots.txt @@ -1,3 +1,11 @@ +S 2013-03-21 ed25a67 + freebsd-x86_64 5f0b08839ae3d1207808f0d57cbfdb00eff9c883 + linux-i386 54765a17c6b6d04a7013cada2a51d190462979b8 + linux-x86_64 c6cae795aecb8c4d5f17c73bfdd01d2b0ff32126 + macos-i386 bc05e17fc93187a1906f118ecdb258f09317f220 + macos-x86_64 c39838814f45e343d4f5754390aad22c41a34ba6 + winnt-i386 c4a858ef45ab2c9319e607640b2bbb3bc4b48093 + S 2013-02-27 a6d9689 freebsd-x86_64 683f329fe589af854f9a375405468691d98015ac linux-i386 22f5c2a91941735007ed804586fc0f0e82fc3601 diff --git a/src/test/auxiliary/anon_trait_static_method_lib.rs b/src/test/auxiliary/anon_trait_static_method_lib.rs index 1162131960a9c..9a778b1887414 100644 --- a/src/test/auxiliary/anon_trait_static_method_lib.rs +++ b/src/test/auxiliary/anon_trait_static_method_lib.rs @@ -13,7 +13,7 @@ pub struct Foo { } pub impl Foo { - static fn new() -> Foo { + fn new() -> Foo { Foo { x: 3 } } } diff --git a/src/test/auxiliary/cci_class_cast.rs b/src/test/auxiliary/cci_class_cast.rs index 5006c72ad156b..edda0644b16a6 100644 --- a/src/test/auxiliary/cci_class_cast.rs +++ b/src/test/auxiliary/cci_class_cast.rs @@ -18,7 +18,7 @@ pub mod kitty { } impl ToStr for cat { - pure fn to_str(&self) -> ~str { copy self.name } + fn to_str(&self) -> ~str { copy self.name } } priv impl cat { diff --git a/src/test/auxiliary/cci_const.rs b/src/test/auxiliary/cci_const.rs index 945004ede6de8..17029b9d3778a 100644 --- a/src/test/auxiliary/cci_const.rs +++ b/src/test/auxiliary/cci_const.rs @@ -11,6 +11,6 @@ pub extern fn bar() { } -pub const foopy: &'static str = "hi there"; -pub const uint_val: uint = 12; -pub const uint_expr: uint = (1 << uint_val) - 1; +pub static foopy: &'static str = "hi there"; +pub static uint_val: uint = 12; +pub static uint_expr: uint = (1 << uint_val) - 1; diff --git a/src/test/auxiliary/crateresolve5-1.rs b/src/test/auxiliary/crateresolve5-1.rs index c11e39706f595..c120a971c6b90 100644 --- a/src/test/auxiliary/crateresolve5-1.rs +++ b/src/test/auxiliary/crateresolve5-1.rs @@ -25,4 +25,11 @@ pub enum e { pub fn nominal() -> e { e_val } +pub fn nominal_eq(e1: e, e2: e) -> bool { true } + +impl Eq for e { + fn eq(&self, other: &e) -> bool { nominal_eq(*self, *other) } + fn ne(&self, other: &e) -> bool { !nominal_eq(*self, *other) } +} + pub fn f() -> int { 10 } diff --git a/src/test/auxiliary/crateresolve5-2.rs b/src/test/auxiliary/crateresolve5-2.rs index bc57328ac8066..230fdad046891 100644 --- a/src/test/auxiliary/crateresolve5-2.rs +++ b/src/test/auxiliary/crateresolve5-2.rs @@ -22,6 +22,13 @@ pub enum e { e_val } +impl Eq for e { + fn eq(&self, other: &e) -> bool { !nominal_neq(*self, *other) } + fn ne(&self, other: &e) -> bool { nominal_neq(*self, *other) } +} + pub fn nominal() -> e { e_val } +pub fn nominal_neq(e1: e, e2: e) -> bool { false } + pub fn f() -> int { 20 } diff --git a/src/test/auxiliary/impl_privacy_xc_2.rs b/src/test/auxiliary/impl_privacy_xc_2.rs index d8c2a9ede5cff..0fa15fa14f613 100644 --- a/src/test/auxiliary/impl_privacy_xc_2.rs +++ b/src/test/auxiliary/impl_privacy_xc_2.rs @@ -7,8 +7,8 @@ pub struct Fish { mod unexported { use super::Fish; impl Eq for Fish { - pure fn eq(&self, _: &Fish) -> bool { true } - pure fn ne(&self, _: &Fish) -> bool { false } + fn eq(&self, _: &Fish) -> bool { true } + fn ne(&self, _: &Fish) -> bool { false } } } diff --git a/src/test/auxiliary/issue-2526.rs b/src/test/auxiliary/issue-2526.rs index c09e64eac8cb4..775955ff38c43 100644 --- a/src/test/auxiliary/issue-2526.rs +++ b/src/test/auxiliary/issue-2526.rs @@ -19,6 +19,7 @@ struct arc_destruct { _data: int, } +#[unsafe_destructor] impl Drop for arc_destruct { fn finalize(&self) {} } diff --git a/src/test/auxiliary/static-methods-crate.rs b/src/test/auxiliary/static-methods-crate.rs index dbfff4e8acaaf..74c46a8b8c6b4 100644 --- a/src/test/auxiliary/static-methods-crate.rs +++ b/src/test/auxiliary/static-methods-crate.rs @@ -14,17 +14,17 @@ #[crate_type = "lib"]; pub trait read { - static fn readMaybe(s: ~str) -> Option; + fn readMaybe(s: ~str) -> Option; } impl read for int { - static fn readMaybe(s: ~str) -> Option { + fn readMaybe(s: ~str) -> Option { int::from_str(s) } } impl read for bool { - static fn readMaybe(s: ~str) -> Option { + fn readMaybe(s: ~str) -> Option { match s { ~"true" => Some(true), ~"false" => Some(false), diff --git a/src/test/auxiliary/static_fn_inline_xc_aux.rs b/src/test/auxiliary/static_fn_inline_xc_aux.rs index f595529b7f6d7..5fc6621f18658 100644 --- a/src/test/auxiliary/static_fn_inline_xc_aux.rs +++ b/src/test/auxiliary/static_fn_inline_xc_aux.rs @@ -11,14 +11,14 @@ pub mod num { pub trait Num2 { - static pure fn from_int2(n: int) -> Self; + fn from_int2(n: int) -> Self; } } pub mod float { impl ::num::Num2 for float { #[inline] - static pure fn from_int2(n: int) -> float { return n as float; } + fn from_int2(n: int) -> float { return n as float; } } } diff --git a/src/test/auxiliary/static_fn_trait_xc_aux.rs b/src/test/auxiliary/static_fn_trait_xc_aux.rs index 80734b8336b87..cc03ac3894304 100644 --- a/src/test/auxiliary/static_fn_trait_xc_aux.rs +++ b/src/test/auxiliary/static_fn_trait_xc_aux.rs @@ -1,11 +1,11 @@ pub mod num { pub trait Num2 { - static pure fn from_int2(n: int) -> Self; + fn from_int2(n: int) -> Self; } } pub mod float { impl ::num::Num2 for float { - static pure fn from_int2(n: int) -> float { return n as float; } + fn from_int2(n: int) -> float { return n as float; } } } diff --git a/src/test/auxiliary/trait_inheritance_overloading_xc.rs b/src/test/auxiliary/trait_inheritance_overloading_xc.rs index e86f7cfd26ad5..1b480ff17b330 100644 --- a/src/test/auxiliary/trait_inheritance_overloading_xc.rs +++ b/src/test/auxiliary/trait_inheritance_overloading_xc.rs @@ -18,24 +18,24 @@ pub struct MyInt { } impl Add for MyInt { - pure fn add(&self, other: &MyInt) -> MyInt { mi(self.val + other.val) } + fn add(&self, other: &MyInt) -> MyInt { mi(self.val + other.val) } } impl Sub for MyInt { - pure fn sub(&self, other: &MyInt) -> MyInt { mi(self.val - other.val) } + fn sub(&self, other: &MyInt) -> MyInt { mi(self.val - other.val) } } impl Mul for MyInt { - pure fn mul(&self, other: &MyInt) -> MyInt { mi(self.val * other.val) } + fn mul(&self, other: &MyInt) -> MyInt { mi(self.val * other.val) } } impl Eq for MyInt { - pure fn eq(&self, other: &MyInt) -> bool { self.val == other.val } + fn eq(&self, other: &MyInt) -> bool { self.val == other.val } - pure fn ne(&self, other: &MyInt) -> bool { !self.eq(other) } + fn ne(&self, other: &MyInt) -> bool { !self.eq(other) } } impl MyNum for MyInt; -pure fn mi(v: int) -> MyInt { MyInt { val: v } } +fn mi(v: int) -> MyInt { MyInt { val: v } } diff --git a/src/test/auxiliary/xc_private_method_lib.rs b/src/test/auxiliary/xc_private_method_lib.rs new file mode 100644 index 0000000000000..f9fda2b0810b3 --- /dev/null +++ b/src/test/auxiliary/xc_private_method_lib.rs @@ -0,0 +1,10 @@ +#[crate_type="lib"]; + +pub struct Foo { + x: int +} + +impl Foo { + fn new() -> Foo { Foo { x: 1 } } +} + diff --git a/src/test/bench/core-map.rs b/src/test/bench/core-map.rs index c86d2fe4d9332..67281594a395a 100644 --- a/src/test/bench/core-map.rs +++ b/src/test/bench/core-map.rs @@ -1,4 +1,4 @@ -// Copyright 2012 The Rust Project Developers. See the COPYRIGHT +// Copyright 2013 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // @@ -9,322 +9,161 @@ // except according to those terms. extern mod std; -use std::oldmap; -use std::treemap::TreeMap; -use core::hashmap::linear::*; -use core::io::WriterUtil; - -struct Results { - sequential_ints: float, - random_ints: float, - delete_ints: float, - - sequential_strings: float, - random_strings: float, - delete_strings: float -} -fn timed(result: &mut float, - op: &fn()) { - let start = std::time::precise_time_s(); - op(); - let end = std::time::precise_time_s(); - *result = (end - start); +use core::io; +use std::time; +use std::treemap::TreeMap; +use core::hashmap::linear::{LinearMap, LinearSet}; +use core::trie::TrieMap; + +fn timed(label: &str, f: &fn()) { + let start = time::precise_time_s(); + f(); + let end = time::precise_time_s(); + io::println(fmt!(" %s: %f", label, end - start)); } -fn old_int_benchmarks(rng: @rand::Rng, num_keys: uint, results: &mut Results) { - - { - let map = oldmap::HashMap(); - do timed(&mut results.sequential_ints) { - for uint::range(0, num_keys) |i| { - map.insert(i, i+1); - } +fn ascending>(map: &mut M, n_keys: uint) { + io::println(" Ascending integers:"); - for uint::range(0, num_keys) |i| { - fail_unless!(map.get(&i) == i+1); - } + do timed("insert") { + for uint::range(0, n_keys) |i| { + map.insert(i, i + 1); } } - { - let map = oldmap::HashMap(); - do timed(&mut results.random_ints) { - for uint::range(0, num_keys) |i| { - map.insert(rng.next() as uint, i); - } + do timed("search") { + for uint::range(0, n_keys) |i| { + fail_unless!(map.find(&i).unwrap() == &(i + 1)); } } - { - let map = oldmap::HashMap(); - for uint::range(0, num_keys) |i| { - map.insert(i, i);; - } - - do timed(&mut results.delete_ints) { - for uint::range(0, num_keys) |i| { - fail_unless!(map.remove(&i)); - } + do timed("remove") { + for uint::range(0, n_keys) |i| { + fail_unless!(map.remove(&i)); } } } -fn old_str_benchmarks(rng: @rand::Rng, num_keys: uint, results: &mut Results) { - { - let map = oldmap::HashMap(); - do timed(&mut results.sequential_strings) { - for uint::range(0, num_keys) |i| { - let s = uint::to_str(i); - map.insert(s, i); - } +fn descending>(map: &mut M, n_keys: uint) { + io::println(" Descending integers:"); - for uint::range(0, num_keys) |i| { - let s = uint::to_str(i); - fail_unless!(map.get(&s) == i); - } + do timed("insert") { + for uint::range(0, n_keys) |i| { + map.insert(i, i + 1); } } - { - let map = oldmap::HashMap(); - do timed(&mut results.random_strings) { - for uint::range(0, num_keys) |i| { - let s = uint::to_str(rng.next() as uint); - map.insert(s, i); - } + do timed("search") { + for uint::range(0, n_keys) |i| { + fail_unless!(map.find(&i).unwrap() == &(i + 1)); } } - { - let map = oldmap::HashMap(); - for uint::range(0, num_keys) |i| { - map.insert(uint::to_str(i), i); - } - do timed(&mut results.delete_strings) { - for uint::range(0, num_keys) |i| { - fail_unless!(map.remove(&uint::to_str(i))); - } + do timed("remove") { + for uint::range(0, n_keys) |i| { + fail_unless!(map.remove(&i)); } } } -fn linear_int_benchmarks(rng: @rand::Rng, num_keys: uint, results: &mut Results) { - { - let mut map = LinearMap::new(); - do timed(&mut results.sequential_ints) { - for uint::range(0, num_keys) |i| { - map.insert(i, i+1); - } +fn vector>(map: &mut M, n_keys: uint, dist: &[uint]) { - for uint::range(0, num_keys) |i| { - fail_unless!(map.find(&i).unwrap() == &(i+1)); - } + do timed("insert") { + for uint::range(0, n_keys) |i| { + map.insert(dist[i], i + 1); } } - { - let mut map = LinearMap::new(); - do timed(&mut results.random_ints) { - for uint::range(0, num_keys) |i| { - map.insert(rng.next() as uint, i); - } + do timed("search") { + for uint::range(0, n_keys) |i| { + fail_unless!(map.find(&dist[i]).unwrap() == &(i + 1)); } } - { - let mut map = LinearMap::new(); - for uint::range(0, num_keys) |i| { - map.insert(i, i);; - } - - do timed(&mut results.delete_ints) { - for uint::range(0, num_keys) |i| { - fail_unless!(map.remove(&i)); - } + do timed("remove") { + for uint::range(0, n_keys) |i| { + fail_unless!(map.remove(&dist[i])); } } } -fn linear_str_benchmarks(rng: @rand::Rng, num_keys: uint, results: &mut Results) { - { - let mut map = LinearMap::new(); - do timed(&mut results.sequential_strings) { - for uint::range(0, num_keys) |i| { - let s = uint::to_str(i); - map.insert(s, i); - } - - for uint::range(0, num_keys) |i| { - let s = uint::to_str(i); - fail_unless!(map.find(&s).unwrap() == &i); - } +fn main() { + let args = os::args(); + let n_keys = { + if args.len() == 2 { + uint::from_str(args[1]).get() + } else { + 1000000 } - } + }; - { - let mut map = LinearMap::new(); - do timed(&mut results.random_strings) { - for uint::range(0, num_keys) |i| { - let s = uint::to_str(rng.next() as uint); - map.insert(s, i); - } - } - } + let mut rand = vec::with_capacity(n_keys); { - let mut map = LinearMap::new(); - for uint::range(0, num_keys) |i| { - map.insert(uint::to_str(i), i); - } - do timed(&mut results.delete_strings) { - for uint::range(0, num_keys) |i| { - fail_unless!(map.remove(&uint::to_str(i))); + let rng = core::rand::seeded_rng([1, 1, 1, 1, 1, 1, 1]); + let mut set = LinearSet::new(); + while set.len() != n_keys { + let next = rng.next() as uint; + if set.insert(next) { + rand.push(next); } } } -} -fn tree_int_benchmarks(rng: @rand::Rng, num_keys: uint, results: &mut Results) { - { - let mut map = TreeMap::new(); - do timed(&mut results.sequential_ints) { - for uint::range(0, num_keys) |i| { - map.insert(i, i+1); - } + io::println(fmt!("%? keys", n_keys)); - for uint::range(0, num_keys) |i| { - fail_unless!(map.find(&i).unwrap() == &(i+1)); - } - } - } + io::println("\nTreeMap:"); { - let mut map = TreeMap::new(); - do timed(&mut results.random_ints) { - for uint::range(0, num_keys) |i| { - map.insert(rng.next() as uint, i); - } - } + let mut map = TreeMap::new::(); + ascending(&mut map, n_keys); } { - let mut map = TreeMap::new(); - for uint::range(0, num_keys) |i| { - map.insert(i, i);; - } - - do timed(&mut results.delete_ints) { - for uint::range(0, num_keys) |i| { - fail_unless!(map.remove(&i)); - } - } + let mut map = TreeMap::new::(); + descending(&mut map, n_keys); } -} -fn tree_str_benchmarks(rng: @rand::Rng, num_keys: uint, results: &mut Results) { { - let mut map = TreeMap::new(); - do timed(&mut results.sequential_strings) { - for uint::range(0, num_keys) |i| { - let s = uint::to_str(i); - map.insert(s, i); - } - - for uint::range(0, num_keys) |i| { - let s = uint::to_str(i); - fail_unless!(map.find(&s).unwrap() == &i); - } - } + io::println(" Random integers:"); + let mut map = TreeMap::new::(); + vector(&mut map, n_keys, rand); } + io::println("\nLinearMap:"); + { - let mut map = TreeMap::new(); - do timed(&mut results.random_strings) { - for uint::range(0, num_keys) |i| { - let s = uint::to_str(rng.next() as uint); - map.insert(s, i); - } - } + let mut map = LinearMap::new::(); + ascending(&mut map, n_keys); } { - let mut map = TreeMap::new(); - for uint::range(0, num_keys) |i| { - map.insert(uint::to_str(i), i); - } - do timed(&mut results.delete_strings) { - for uint::range(0, num_keys) |i| { - fail_unless!(map.remove(&uint::to_str(i))); - } - } + let mut map = LinearMap::new::(); + descending(&mut map, n_keys); } -} - -fn write_header(header: &str) { - io::stdout().write_str(header); - io::stdout().write_str("\n"); -} - -fn write_row(label: &str, value: float) { - io::stdout().write_str(fmt!("%30s %f s\n", label, value)); -} - -fn write_results(label: &str, results: &Results) { - write_header(label); - write_row("sequential_ints", results.sequential_ints); - write_row("random_ints", results.random_ints); - write_row("delete_ints", results.delete_ints); - write_row("sequential_strings", results.sequential_strings); - write_row("random_strings", results.random_strings); - write_row("delete_strings", results.delete_strings); -} -fn empty_results() -> Results { - Results { - sequential_ints: 0f, - random_ints: 0f, - delete_ints: 0f, - - sequential_strings: 0f, - random_strings: 0f, - delete_strings: 0f, + { + io::println(" Random integers:"); + let mut map = LinearMap::new::(); + vector(&mut map, n_keys, rand); } -} - -fn main() { - let args = os::args(); - let num_keys = { - if args.len() == 2 { - uint::from_str(args[1]).get() - } else { - 100 // woefully inadequate for any real measurement - } - }; - let seed = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; + io::println("\nTrieMap:"); { - let rng = rand::seeded_rng(seed); - let mut results = empty_results(); - old_int_benchmarks(rng, num_keys, &mut results); - old_str_benchmarks(rng, num_keys, &mut results); - write_results("std::oldmap::HashMap", &results); + let mut map = TrieMap::new::(); + ascending(&mut map, n_keys); } { - let rng = rand::seeded_rng(seed); - let mut results = empty_results(); - linear_int_benchmarks(rng, num_keys, &mut results); - linear_str_benchmarks(rng, num_keys, &mut results); - write_results("core::hashmap::linear::LinearMap", &results); + let mut map = TrieMap::new::(); + descending(&mut map, n_keys); } { - let rng = rand::seeded_rng(seed); - let mut results = empty_results(); - tree_int_benchmarks(rng, num_keys, &mut results); - tree_str_benchmarks(rng, num_keys, &mut results); - write_results("std::treemap::TreeMap", &results); + io::println(" Random integers:"); + let mut map = TrieMap::new::(); + vector(&mut map, n_keys, rand); } } diff --git a/src/test/bench/shootout-k-nucleotide-pipes.rs b/src/test/bench/shootout-k-nucleotide-pipes.rs index fc980e3d6db53..f0847b635b4bd 100644 --- a/src/test/bench/shootout-k-nucleotide-pipes.rs +++ b/src/test/bench/shootout-k-nucleotide-pipes.rs @@ -27,14 +27,14 @@ fn sort_and_fmt(mm: HashMap<~[u8], uint>, total: uint) -> ~str { return (xx as float) * 100f / (yy as float); } - pure fn le_by_val(kv0: &(TT,UU), + fn le_by_val(kv0: &(TT,UU), kv1: &(TT,UU)) -> bool { let (_, v0) = *kv0; let (_, v1) = *kv1; return v0 >= v1; } - pure fn le_by_key(kv0: &(TT,UU), + fn le_by_key(kv0: &(TT,UU), kv1: &(TT,UU)) -> bool { let (k0, _) = *kv0; let (k1, _) = *kv1; diff --git a/src/test/bench/shootout-mandelbrot.rs b/src/test/bench/shootout-mandelbrot.rs index eeea62d50fb3a..ada5ff7be2fa8 100644 --- a/src/test/bench/shootout-mandelbrot.rs +++ b/src/test/bench/shootout-mandelbrot.rs @@ -33,7 +33,7 @@ struct cmplx { } impl ops::Mul for cmplx { - pure fn mul(&self, x: &cmplx) -> cmplx { + fn mul(&self, x: &cmplx) -> cmplx { cmplx { re: self.re*(*x).re - self.im*(*x).im, im: self.re*(*x).im + self.im*(*x).re @@ -42,7 +42,7 @@ impl ops::Mul for cmplx { } impl ops::Add for cmplx { - pure fn add(&self, x: &cmplx) -> cmplx { + fn add(&self, x: &cmplx) -> cmplx { cmplx { re: self.re + (*x).re, im: self.im + (*x).im @@ -52,7 +52,7 @@ impl ops::Add for cmplx { struct Line {i: uint, b: ~[u8]} -pure fn cabs(x: cmplx) -> f64 +fn cabs(x: cmplx) -> f64 { x.re*x.re + x.im*x.im } diff --git a/src/test/bench/shootout-nbody.rs b/src/test/bench/shootout-nbody.rs index 6ce9fce881a6a..97907025bd1a0 100644 --- a/src/test/bench/shootout-nbody.rs +++ b/src/test/bench/shootout-nbody.rs @@ -167,10 +167,10 @@ pub mod NBodySystem { pub mod Body { use Body; - pub const PI: float = 3.141592653589793; - pub const SOLAR_MASS: float = 39.478417604357432; + pub static PI: float = 3.141592653589793; + pub static SOLAR_MASS: float = 39.478417604357432; // was 4 * PI * PI originally - pub const DAYS_PER_YEAR: float = 365.24; + pub static DAYS_PER_YEAR: float = 365.24; pub struct Props { x: float, diff --git a/src/test/bench/sudoku.rs b/src/test/bench/sudoku.rs index 92320986ae83b..4964cea28ad91 100644 --- a/src/test/bench/sudoku.rs +++ b/src/test/bench/sudoku.rs @@ -40,11 +40,11 @@ struct Sudoku { } pub impl Sudoku { - static pub fn new(g: grid) -> Sudoku { + pub fn new(g: grid) -> Sudoku { return Sudoku { grid: g } } - static pub fn from_vec(vec: &[[u8 * 9] * 9]) -> Sudoku { + pub fn from_vec(vec: &[[u8 * 9] * 9]) -> Sudoku { let mut g = do vec::from_fn(9u) |i| { do vec::from_fn(9u) |j| { vec[i][j] } }; @@ -62,12 +62,13 @@ pub impl Sudoku { return true; } - static pub fn read(reader: @io::Reader) -> Sudoku { + pub fn read(reader: @io::Reader) -> Sudoku { fail_unless!(reader.read_line() == ~"9,9"); /* assert first line is exactly "9,9" */ let mut g = vec::from_fn(10u, { |_i| ~[0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8] }); while !reader.eof() { - let comps = str::split_char(str::trim(reader.read_line()), ','); + let line = reader.read_line(); + let comps = str::split_char(line.trim(), ','); if vec::len(comps) == 3u { let row = uint::from_str(comps[0]).get() as u8; let col = uint::from_str(comps[1]).get() as u8; @@ -152,10 +153,10 @@ pub impl Sudoku { // Stores available colors as simple bitfield, bit 0 is always unset struct Colors(u16); -const heads: u16 = (1u16 << 10) - 1; /* bits 9..0 */ +static heads: u16 = (1u16 << 10) - 1; /* bits 9..0 */ impl Colors { - static fn new(start_color: u8) -> Colors { + fn new(start_color: u8) -> Colors { // Sets bits 9..start_color let tails = !0u16 << start_color; return Colors(heads & tails); @@ -181,7 +182,7 @@ impl Colors { } } -const default_sudoku: [[u8 * 9] * 9] = [ +static default_sudoku: [[u8 * 9] * 9] = [ /* 0 1 2 3 4 5 6 7 8 */ /* 0 */ [0u8, 4u8, 0u8, 6u8, 0u8, 0u8, 0u8, 3u8, 2u8], /* 1 */ [0u8, 0u8, 8u8, 0u8, 2u8, 0u8, 0u8, 0u8, 0u8], @@ -195,7 +196,7 @@ const default_sudoku: [[u8 * 9] * 9] = [ ]; #[cfg(test)] -const default_solution: [[u8 * 9] * 9] = [ +static default_solution: [[u8 * 9] * 9] = [ /* 0 1 2 3 4 5 6 7 8 */ /* 0 */ [1u8, 4u8, 9u8, 6u8, 7u8, 5u8, 8u8, 3u8, 2u8], /* 1 */ [5u8, 3u8, 8u8, 1u8, 2u8, 9u8, 7u8, 4u8, 6u8], diff --git a/src/test/bench/task-perf-alloc-unwind.rs b/src/test/bench/task-perf-alloc-unwind.rs index 4a372d016f9cf..c29ab9a769e1a 100644 --- a/src/test/bench/task-perf-alloc-unwind.rs +++ b/src/test/bench/task-perf-alloc-unwind.rs @@ -56,6 +56,7 @@ struct r { _l: @nillist, } +#[unsafe_destructor] impl Drop for r { fn finalize(&self) {} } diff --git a/src/test/compile-fail/auto-ref-slice-plus-ref.rs b/src/test/compile-fail/auto-ref-slice-plus-ref.rs index 7faee6f7ea28f..609e8de87d68b 100644 --- a/src/test/compile-fail/auto-ref-slice-plus-ref.rs +++ b/src/test/compile-fail/auto-ref-slice-plus-ref.rs @@ -20,9 +20,9 @@ fn main() { } trait MyIter { - pure fn test_mut(&mut self); + fn test_mut(&mut self); } impl MyIter for &'self [int] { - pure fn test_mut(&mut self) { } + fn test_mut(&mut self) { } } diff --git a/src/test/compile-fail/autoderef-full-lval.rs b/src/test/compile-fail/autoderef-full-lval.rs index 8178b46d1d3fc..000d03ea73c0d 100644 --- a/src/test/compile-fail/autoderef-full-lval.rs +++ b/src/test/compile-fail/autoderef-full-lval.rs @@ -8,7 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// error-pattern: mismatched types struct clam { x: @int, y: @int, @@ -21,12 +20,12 @@ struct fish { fn main() { let a: clam = clam{x: @1, y: @2}; let b: clam = clam{x: @10, y: @20}; - let z: int = a.x + b.y; + let z: int = a.x + b.y; //~ ERROR binary operation + cannot be applied to type `@int` debug!(z); fail_unless!((z == 21)); let forty: fish = fish{a: @40}; let two: fish = fish{a: @2}; - let answer: int = forty.a + two.a; + let answer: int = forty.a + two.a; //~ ERROR binary operation + cannot be applied to type `@int` debug!(answer); fail_unless!((answer == 42)); } diff --git a/src/test/compile-fail/bad-const-type.rs b/src/test/compile-fail/bad-const-type.rs index e35d5e79bde65..a66c00d5411b4 100644 --- a/src/test/compile-fail/bad-const-type.rs +++ b/src/test/compile-fail/bad-const-type.rs @@ -10,5 +10,5 @@ // error-pattern:expected `~str` but found `int` -const i: str = 10i; +static i: ~str = 10i; fn main() { debug!(i); } diff --git a/src/test/compile-fail/borrowck-assign-to-constants.rs b/src/test/compile-fail/borrowck-assign-to-constants.rs index 78a95cb33c0c3..0d65aacb65b7a 100644 --- a/src/test/compile-fail/borrowck-assign-to-constants.rs +++ b/src/test/compile-fail/borrowck-assign-to-constants.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -const foo: int = 5; +static foo: int = 5; fn main() { // assigning to various global constants diff --git a/src/test/compile-fail/borrowck-assign-to-subfield.rs b/src/test/compile-fail/borrowck-assign-to-subfield.rs index 736e950cd82df..610802ca68b31 100644 --- a/src/test/compile-fail/borrowck-assign-to-subfield.rs +++ b/src/test/compile-fail/borrowck-assign-to-subfield.rs @@ -13,7 +13,6 @@ fn main() { a: int, w: B, x: @B, - y: @const B, z: @mut B } struct B { @@ -23,7 +22,6 @@ fn main() { a: 1, w: B {a: 1}, x: @B {a: 1}, - y: @const B {a: 1}, z: @mut B {a: 1} }; @@ -37,6 +35,5 @@ fn main() { // in these cases we pass through a box, so the mut // of the box is dominant p.x.a = 2; //~ ERROR assigning to immutable field - p.y.a = 2; //~ ERROR assigning to const field p.z.a = 2; } diff --git a/src/test/compile-fail/borrowck-borrowed-uniq-rvalue-2.rs b/src/test/compile-fail/borrowck-borrowed-uniq-rvalue-2.rs index fd8190358c9d0..fe7b29cf9a868 100644 --- a/src/test/compile-fail/borrowck-borrowed-uniq-rvalue-2.rs +++ b/src/test/compile-fail/borrowck-borrowed-uniq-rvalue-2.rs @@ -12,9 +12,12 @@ struct defer { x: &'self [&'self str], } +#[unsafe_destructor] impl Drop for defer<'self> { fn finalize(&self) { - error!("%?", self.x); + unsafe { + error!("%?", self.x); + } } } diff --git a/src/test/compile-fail/borrowck-loan-in-overloaded-op.rs b/src/test/compile-fail/borrowck-loan-in-overloaded-op.rs index ece9ae7e86199..482d1b6b8b617 100644 --- a/src/test/compile-fail/borrowck-loan-in-overloaded-op.rs +++ b/src/test/compile-fail/borrowck-loan-in-overloaded-op.rs @@ -13,7 +13,7 @@ struct foo(~uint); impl Add for foo { - pure fn add(f: &foo) -> foo { + fn add(f: &foo) -> foo { foo(~(**self + **(*f))) } } diff --git a/src/test/compile-fail/borrowck-loan-rcvr-overloaded-op.rs b/src/test/compile-fail/borrowck-loan-rcvr-overloaded-op.rs index 23debb4c5e212..a4ad7e69b3336 100644 --- a/src/test/compile-fail/borrowck-loan-rcvr-overloaded-op.rs +++ b/src/test/compile-fail/borrowck-loan-rcvr-overloaded-op.rs @@ -14,7 +14,7 @@ struct Point { } impl ops::Add for Point { - pure fn add(&self, z: &int) -> int { + fn add(&self, z: &int) -> int { self.x + self.y + (*z) } } diff --git a/src/test/compile-fail/borrowck-loan-rcvr.rs b/src/test/compile-fail/borrowck-loan-rcvr.rs index 4a7228dcca39b..4473574926a34 100644 --- a/src/test/compile-fail/borrowck-loan-rcvr.rs +++ b/src/test/compile-fail/borrowck-loan-rcvr.rs @@ -13,7 +13,7 @@ struct point { x: int, y: int } trait methods { fn impurem(&self); fn blockm(&self, f: &fn()); - pure fn purem(&self); + fn purem(&self); } impl methods for point { @@ -22,7 +22,7 @@ impl methods for point { fn blockm(&self, f: &fn()) { f() } - pure fn purem(&self) { + fn purem(&self) { } } diff --git a/src/test/compile-fail/borrowck-pat-enum-in-box.rs b/src/test/compile-fail/borrowck-pat-enum-in-box.rs deleted file mode 100644 index bd1001bf38cb7..0000000000000 --- a/src/test/compile-fail/borrowck-pat-enum-in-box.rs +++ /dev/null @@ -1,37 +0,0 @@ -// Copyright 2012 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -fn match_imm_box(v: &const @Option) -> int { - match *v { - @Some(ref i) => {*i} - @None => {0} - } -} - -fn match_const_box(v: &const @const Option) -> int { - match *v { - @Some(ref i) => { *i } // ok because this is pure - @None => {0} - } -} - -fn process(_i: int) {} - -fn match_const_box_and_do_bad_things(v: &const @const Option) { - match *v { - @Some(ref i) => { //~ ERROR illegal borrow unless pure - process(*i) //~ NOTE impure due to access to impure function - } - @None => {} - } -} - -fn main() { -} diff --git a/src/test/compile-fail/borrowck-uniq-via-box.rs b/src/test/compile-fail/borrowck-uniq-via-box.rs index 914b5caa01139..e1c0e67ff8dcc 100644 --- a/src/test/compile-fail/borrowck-uniq-via-box.rs +++ b/src/test/compile-fail/borrowck-uniq-via-box.rs @@ -50,18 +50,6 @@ fn box_imm_recs(v: @Outer) { borrow(v.f.g.h); // OK } -fn box_const(v: @const ~int) { - borrow(*v); //~ ERROR illegal borrow unless pure -} - -fn box_const_rec(v: @const Rec) { - borrow(v.f); //~ ERROR illegal borrow unless pure -} - -fn box_const_recs(v: @const Outer) { - borrow(v.f.g.h); //~ ERROR illegal borrow unless pure -} - fn main() { } diff --git a/src/test/compile-fail/coerce-bad-variance.rs b/src/test/compile-fail/coerce-bad-variance.rs deleted file mode 100644 index 6ce969c7eaf3c..0000000000000 --- a/src/test/compile-fail/coerce-bad-variance.rs +++ /dev/null @@ -1,17 +0,0 @@ -fn mutate(x: &mut @const int) { - *x = @3; -} - -fn give_away1(y: @mut @mut int) { - mutate(y); //~ ERROR values differ in mutability -} - -fn give_away2(y: @mut @const int) { - mutate(y); -} - -fn give_away3(y: @mut @int) { - mutate(y); //~ ERROR values differ in mutability -} - -fn main() {} diff --git a/src/test/compile-fail/const-cast-different-types.rs b/src/test/compile-fail/const-cast-different-types.rs index 45e39b47d2371..56ec0bb929636 100644 --- a/src/test/compile-fail/const-cast-different-types.rs +++ b/src/test/compile-fail/const-cast-different-types.rs @@ -8,9 +8,9 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -const a: &'static str = &"foo"; -const b: *u8 = a as *u8; //~ ERROR non-scalar cast -const c: *u8 = &a as *u8; //~ ERROR mismatched types +static a: &'static str = &"foo"; +static b: *u8 = a as *u8; //~ ERROR non-scalar cast +static c: *u8 = &a as *u8; //~ ERROR mismatched types fn main() { -} \ No newline at end of file +} diff --git a/src/test/compile-fail/const-cast-wrong-type.rs b/src/test/compile-fail/const-cast-wrong-type.rs index fe91056d47b6f..677f4318db759 100644 --- a/src/test/compile-fail/const-cast-wrong-type.rs +++ b/src/test/compile-fail/const-cast-wrong-type.rs @@ -8,8 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -const a: [u8 * 3] = ['h' as u8, 'i' as u8, 0 as u8]; -const b: *i8 = &a as *i8; //~ ERROR mismatched types +static a: [u8 * 3] = ['h' as u8, 'i' as u8, 0 as u8]; +static b: *i8 = &a as *i8; //~ ERROR mismatched types fn main() { -} \ No newline at end of file +} diff --git a/src/test/compile-fail/const-recursive.rs b/src/test/compile-fail/const-recursive.rs index f565a44c97f97..9c633e082b194 100644 --- a/src/test/compile-fail/const-recursive.rs +++ b/src/test/compile-fail/const-recursive.rs @@ -9,8 +9,8 @@ // except according to those terms. // error-pattern: recursive constant -const a: int = b; -const b: int = a; +static a: int = b; +static b: int = a; fn main() { } diff --git a/src/test/compile-fail/crateresolve5.rs b/src/test/compile-fail/crateresolve5.rs index b8c2274076c33..96e88f99bcb18 100644 --- a/src/test/compile-fail/crateresolve5.rs +++ b/src/test/compile-fail/crateresolve5.rs @@ -11,12 +11,12 @@ // xfail-fast // aux-build:crateresolve5-1.rs // aux-build:crateresolve5-2.rs -// error-pattern:mismatched types extern mod cr5_1 (name = "crateresolve5", vers = "0.1"); extern mod cr5_2 (name = "crateresolve5", vers = "0.2"); + fn main() { // Nominal types from two multiple versions of a crate are different types - fail_unless!(cr5_1::nominal() == cr5_2::nominal()); + fail_unless!(cr5_1::nominal() == cr5_2::nominal()); //~ ERROR mismatched types: expected } diff --git a/src/test/compile-fail/deriving-obsolete.rs b/src/test/compile-fail/deriving-obsolete.rs new file mode 100644 index 0000000000000..298dced1e21ed --- /dev/null +++ b/src/test/compile-fail/deriving-obsolete.rs @@ -0,0 +1,17 @@ +// Copyright 2013 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#[deriving_clone] //~ ERROR `#[deriving_clone]` is obsolete; use `#[deriving(Clone)]` instead +#[deriving_eq] //~ ERROR `#[deriving_eq]` is obsolete; use `#[deriving(Eq)]` instead +#[deriving_iter_bytes] +//~^ ERROR `#[deriving_iter_bytes]` is obsolete; use `#[deriving(IterBytes)]` instead +struct Foo; + +pub fn main() { } diff --git a/src/test/compile-fail/fn-variance-1.rs b/src/test/compile-fail/fn-variance-1.rs index c5c29bd3ecfe7..6f3ccfd35ac21 100644 --- a/src/test/compile-fail/fn-variance-1.rs +++ b/src/test/compile-fail/fn-variance-1.rs @@ -11,7 +11,6 @@ #[legacy_modes]; fn takes_mut(&&x: @mut int) { } -fn takes_const(&&x: @const int) { } fn takes_imm(&&x: @int) { } fn apply(t: T, f: &fn(T)) { @@ -20,10 +19,8 @@ fn apply(t: T, f: &fn(T)) { fn main() { apply(@3, takes_mut); //~ ERROR (values differ in mutability) - apply(@3, takes_const); apply(@3, takes_imm); apply(@mut 3, takes_mut); - apply(@mut 3, takes_const); apply(@mut 3, takes_imm); //~ ERROR (values differ in mutability) } diff --git a/src/test/compile-fail/fn-variance-2.rs b/src/test/compile-fail/fn-variance-2.rs index 2a30f9fb96faf..61668cbdb9eab 100644 --- a/src/test/compile-fail/fn-variance-2.rs +++ b/src/test/compile-fail/fn-variance-2.rs @@ -25,9 +25,6 @@ fn main() { // @mut int. let f: @mut int = r(); - // OK. - let g: @const int = r(); - // Bad. let h: @int = r(); //~ ERROR (values differ in mutability) } diff --git a/src/test/compile-fail/issue-2478.rs b/src/test/compile-fail/issue-2478.rs index 2b52cab7fe79a..d5663e57f4bf7 100644 --- a/src/test/compile-fail/issue-2478.rs +++ b/src/test/compile-fail/issue-2478.rs @@ -12,5 +12,5 @@ fn foo() -> &'a int { return &x; } -const x: int = 5; +static x: int = 5; fn main() {} diff --git a/src/test/compile-fail/issue-2548.rs b/src/test/compile-fail/issue-2548.rs index 83fdb86628b65..f8f973dbc6bed 100644 --- a/src/test/compile-fail/issue-2548.rs +++ b/src/test/compile-fail/issue-2548.rs @@ -16,10 +16,13 @@ struct foo { } +#[unsafe_destructor] impl Drop for foo { fn finalize(&self) { - io::println("Goodbye, World!"); - *self.x += 1; + unsafe { + io::println("Goodbye, World!"); + *self.x += 1; + } } } diff --git a/src/test/compile-fail/issue-3344.rs b/src/test/compile-fail/issue-3344.rs index df768860cba94..e931a8fa7e144 100644 --- a/src/test/compile-fail/issue-3344.rs +++ b/src/test/compile-fail/issue-3344.rs @@ -10,8 +10,8 @@ struct thing(uint); impl cmp::Ord for thing { //~ ERROR missing method `gt` - pure fn lt(&self, other: &thing) -> bool { **self < **other } - pure fn le(&self, other: &thing) -> bool { **self < **other } - pure fn ge(&self, other: &thing) -> bool { **self < **other } + fn lt(&self, other: &thing) -> bool { **self < **other } + fn le(&self, other: &thing) -> bool { **self < **other } + fn ge(&self, other: &thing) -> bool { **self < **other } } fn main() {} diff --git a/src/test/compile-fail/issue-3521-2.rs b/src/test/compile-fail/issue-3521-2.rs index 39c14b4d316b0..431f98d8181a0 100644 --- a/src/test/compile-fail/issue-3521-2.rs +++ b/src/test/compile-fail/issue-3521-2.rs @@ -11,7 +11,7 @@ fn main() { let foo = 100; - const y: int = foo + 1; //~ ERROR: attempt to use a non-constant value in a constant + static y: int = foo + 1; //~ ERROR: attempt to use a non-constant value in a constant error!(y); } diff --git a/src/test/compile-fail/issue-3668-2.rs b/src/test/compile-fail/issue-3668-2.rs index be96918b25055..f7637f684be5a 100644 --- a/src/test/compile-fail/issue-3668-2.rs +++ b/src/test/compile-fail/issue-3668-2.rs @@ -9,7 +9,7 @@ // except according to those terms. fn f(x:int) { - const child: int = x + 1; //~ ERROR attempt to use a non-constant value in a constant + static child: int = x + 1; //~ ERROR attempt to use a non-constant value in a constant } fn main() {} diff --git a/src/test/compile-fail/issue-3668.rs b/src/test/compile-fail/issue-3668.rs index 1b121878697de..77e2e4f21e8a1 100644 --- a/src/test/compile-fail/issue-3668.rs +++ b/src/test/compile-fail/issue-3668.rs @@ -15,7 +15,7 @@ trait PTrait { impl PTrait for P { fn getChildOption(&self) -> Option<@P> { - const childVal: @P = self.child.get(); //~ ERROR attempt to use a non-constant value in a constant + static childVal: @P = self.child.get(); //~ ERROR attempt to use a non-constant value in a constant fail!(); } } diff --git a/src/test/compile-fail/issue-3707.rs b/src/test/compile-fail/issue-3707.rs index 040bd46ab8c8d..2c8f94c4695b0 100644 --- a/src/test/compile-fail/issue-3707.rs +++ b/src/test/compile-fail/issue-3707.rs @@ -14,10 +14,10 @@ struct Obj { } pub impl Obj { - static pure fn boom() -> bool { + fn boom() -> bool { return 1+1 == 2 } - pure fn chirp() { + fn chirp() { self.boom(); //~ ERROR wat } } diff --git a/src/test/compile-fail/issue-3820.rs b/src/test/compile-fail/issue-3820.rs index 3a726d270ffce..68c00494b9b4d 100644 --- a/src/test/compile-fail/issue-3820.rs +++ b/src/test/compile-fail/issue-3820.rs @@ -14,7 +14,7 @@ struct Thing { } impl Mul*/ for Thing/* { //~ ERROR Look ma, no Mul! - pure fn mul(c: &int) -> Thing { + fn mul(c: &int) -> Thing { Thing {x: self.x * *c} } } diff --git a/src/test/compile-fail/issue-3888.rs b/src/test/compile-fail/issue-3888.rs index 482d1e9fe8a4b..c9a5507f8de0f 100644 --- a/src/test/compile-fail/issue-3888.rs +++ b/src/test/compile-fail/issue-3888.rs @@ -17,7 +17,7 @@ fn vec_peek(v: &'r [T]) -> Option< (&'r T, &'r [T]) > { let vec_len = v.len(); let head = &v[0]; // note: this *shouldn't* be an illegal borrow! See #3888 - let tail = v.view(1, vec_len); //~ ERROR illegal borrow: borrowed value does not live long enough + let tail = v.slice(1, vec_len); //~ ERROR illegal borrow: borrowed value does not live long enough Some( (head, tail) ) } } diff --git a/src/test/compile-fail/issue-3953.rs b/src/test/compile-fail/issue-3953.rs index bfc17c589db91..b726f090e7db7 100644 --- a/src/test/compile-fail/issue-3953.rs +++ b/src/test/compile-fail/issue-3953.rs @@ -25,8 +25,8 @@ struct Lol(int); impl Hahaha for Lol { } impl Eq for Lol { - pure fn eq(&self, other: &Lol) -> bool { **self != **other } - pure fn ne(&self, other: &Lol) -> bool { **self == **other } + fn eq(&self, other: &Lol) -> bool { **self != **other } + fn ne(&self, other: &Lol) -> bool { **self == **other } } fn main() { diff --git a/src/test/compile-fail/issue-3969.rs b/src/test/compile-fail/issue-3969.rs index e2bf708feabc7..60991d40a54c3 100644 --- a/src/test/compile-fail/issue-3969.rs +++ b/src/test/compile-fail/issue-3969.rs @@ -17,7 +17,7 @@ trait BikeMethods { } impl BikeMethods for Bike { - static fn woops(&const self) -> ~str { ~"foo" } + fn woops() -> ~str { ~"foo" } //~^ ERROR method `woops` is declared as static in its impl, but not in its trait } diff --git a/src/test/compile-fail/issue-3973.rs b/src/test/compile-fail/issue-3973.rs index 19244d24bcc71..b1d741f9186b3 100644 --- a/src/test/compile-fail/issue-3973.rs +++ b/src/test/compile-fail/issue-3973.rs @@ -16,11 +16,11 @@ struct Point { } impl ToStr for Point { //~ ERROR implements a method not defined in the trait - static fn new(x: float, y: float) -> Point { + fn new(x: float, y: float) -> Point { Point { x: x, y: y } } - pure fn to_str(&self) -> ~str { + fn to_str(&self) -> ~str { fmt!("(%f, %f)", self.x, self.y) } } diff --git a/src/test/compile-fail/issue-4523.rs b/src/test/compile-fail/issue-4523.rs index e8e2702937110..6d072ce210e2d 100644 --- a/src/test/compile-fail/issue-4523.rs +++ b/src/test/compile-fail/issue-4523.rs @@ -10,7 +10,7 @@ fn foopy() {} -const f: &'static fn() = foopy; //~ ERROR mismatched types: expected `&'static fn()` +static f: &'static fn() = foopy; //~ ERROR mismatched types: expected `&'static fn()` fn main () { f(); diff --git a/src/test/compile-fail/mutable-huh-box-assign.rs b/src/test/compile-fail/issue-4736.rs similarity index 67% rename from src/test/compile-fail/mutable-huh-box-assign.rs rename to src/test/compile-fail/issue-4736.rs index bb06cbb6d03a2..f7144b4c8fa91 100644 --- a/src/test/compile-fail/mutable-huh-box-assign.rs +++ b/src/test/compile-fail/issue-4736.rs @@ -1,4 +1,4 @@ -// Copyright 2012 The Rust Project Developers. See the COPYRIGHT +// Copyright 2013 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // @@ -8,12 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -fn main() { - fn f(&&v: @const int) { - *v = 1 //~ ERROR assigning to dereference of const @ pointer - } - - let v = @0; +struct NonCopyable(()); - f(v); -} +fn main() { + let z = NonCopyable{ p: () }; //~ ERROR structure has no field named `p` +} \ No newline at end of file diff --git a/src/test/compile-fail/issue-4968.rs b/src/test/compile-fail/issue-4968.rs index 315c2affe349c..fc0c29e9a7987 100644 --- a/src/test/compile-fail/issue-4968.rs +++ b/src/test/compile-fail/issue-4968.rs @@ -10,7 +10,7 @@ // Regression test for issue #4968 -const A: (int,int) = (4,2); +static A: (int,int) = (4,2); fn main() { match 42 { A => () } //~ ERROR mismatched types: expected `` but found `(int,int)` (expected integral variable but found tuple) } diff --git a/src/test/compile-fail/kindck-destructor-owned.rs b/src/test/compile-fail/kindck-destructor-owned.rs new file mode 100644 index 0000000000000..e956f95b4229c --- /dev/null +++ b/src/test/compile-fail/kindck-destructor-owned.rs @@ -0,0 +1,12 @@ +struct Foo { + f: @mut int, +} + +impl Drop for Foo { //~ ERROR cannot implement a destructor on a struct that is not Owned + fn finalize(&self) { + *self.f = 10; + } +} + +fn main() { } + diff --git a/src/test/compile-fail/kindck-owned-trait-scoped.rs b/src/test/compile-fail/kindck-owned-trait-scoped.rs index 63690f030934f..34ceb67f24343 100644 --- a/src/test/compile-fail/kindck-owned-trait-scoped.rs +++ b/src/test/compile-fail/kindck-owned-trait-scoped.rs @@ -37,10 +37,10 @@ fn to_foo_2(t: T) -> @foo { // Not OK---T may contain borrowed ptrs and it is going to escape // as part of the returned foo value struct F { f: T } - @F {f:t} as @foo //~ ERROR value may contain borrowed pointers; use `&static` bound + @F {f:t} as @foo //~ ERROR value may contain borrowed pointers; use `'static` bound } -fn to_foo_3(t: T) -> @foo { +fn to_foo_3(t: T) -> @foo { // OK---T may escape as part of the returned foo value, but it is // owned and hence does not contain borrowed ptrs struct F { f: T } diff --git a/src/test/compile-fail/kindck-owned-trait.rs b/src/test/compile-fail/kindck-owned-trait.rs index af6924ef608b2..c61bbc69be519 100644 --- a/src/test/compile-fail/kindck-owned-trait.rs +++ b/src/test/compile-fail/kindck-owned-trait.rs @@ -11,10 +11,10 @@ trait foo { fn foo(&self); } fn to_foo(t: T) -> @foo { - @t as @foo //~ ERROR value may contain borrowed pointers; use `&static` bound + @t as @foo //~ ERROR value may contain borrowed pointers; use `'static` bound } -fn to_foo2(t: T) -> @foo { +fn to_foo2(t: T) -> @foo { @t as @foo } diff --git a/src/test/compile-fail/kindck-owned.rs b/src/test/compile-fail/kindck-owned.rs index 31ab555b38ab6..27cc07ed123ba 100644 --- a/src/test/compile-fail/kindck-owned.rs +++ b/src/test/compile-fail/kindck-owned.rs @@ -13,22 +13,22 @@ fn copy1(t: T) -> @fn() -> T { result } -fn copy2(t: T) -> @fn() -> T { +fn copy2(t: T) -> @fn() -> T { let result: @fn() -> T = || t; result } fn main() { let x = &3; - copy2(&x); //~ ERROR does not fulfill `&static` + copy2(&x); //~ ERROR does not fulfill `'static` copy2(@3); - copy2(@&x); //~ ERROR does not fulfill `&static` + copy2(@&x); //~ ERROR does not fulfill `'static` let boxed: @fn() = || {}; copy2(boxed); let owned: ~fn() = || {}; copy2(owned); //~ ERROR does not fulfill `Copy` let borrowed: &fn() = || {}; - copy2(borrowed); //~ ERROR does not fulfill `&static` + copy2(borrowed); //~ ERROR does not fulfill `'static` } diff --git a/src/test/compile-fail/missing-derivable-attr.rs b/src/test/compile-fail/missing-derivable-attr.rs index 057e6dbc06864..67cf67bfa5a04 100644 --- a/src/test/compile-fail/missing-derivable-attr.rs +++ b/src/test/compile-fail/missing-derivable-attr.rs @@ -9,7 +9,7 @@ // except according to those terms. trait MyEq { - pure fn eq(&self, other: &Self) -> bool; + fn eq(&self, other: &Self) -> bool; } struct A { @@ -17,7 +17,7 @@ struct A { } impl MyEq for int { - pure fn eq(&self, other: &int) -> bool { *self == *other } + fn eq(&self, other: &int) -> bool { *self == *other } } impl MyEq for A; //~ ERROR missing method diff --git a/src/test/compile-fail/no-send-res-ports.rs b/src/test/compile-fail/no-send-res-ports.rs index 192cde21bf169..c1071e5a8c4d9 100644 --- a/src/test/compile-fail/no-send-res-ports.rs +++ b/src/test/compile-fail/no-send-res-ports.rs @@ -17,6 +17,7 @@ fn main() { _x: Port<()>, } + #[unsafe_destructor] impl Drop for foo { fn finalize(&self) {} } diff --git a/src/test/compile-fail/pattern-tyvar-2.rs b/src/test/compile-fail/pattern-tyvar-2.rs index 7e65d1908c4d1..41529b3da93ed 100644 --- a/src/test/compile-fail/pattern-tyvar-2.rs +++ b/src/test/compile-fail/pattern-tyvar-2.rs @@ -12,10 +12,9 @@ extern mod std; -// error-pattern: mismatched types - enum bar { t1((), Option<~[int]>), t2, } -fn foo(t: bar) -> int { match t { t1(_, Some(x)) => { return x * 3; } _ => { fail!(); } } } +// n.b. my change changes this error message, but I think it's right -- tjc +fn foo(t: bar) -> int { match t { t1(_, Some(x)) => { return x * 3; } _ => { fail!(); } } } //~ ERROR binary operation * cannot be applied to fn main() { } diff --git a/src/test/compile-fail/pinned-deep-copy.rs b/src/test/compile-fail/pinned-deep-copy.rs index 5df65832099f5..17e23360a5bbc 100644 --- a/src/test/compile-fail/pinned-deep-copy.rs +++ b/src/test/compile-fail/pinned-deep-copy.rs @@ -12,9 +12,12 @@ struct r { i: @mut int, } +#[unsafe_destructor] impl Drop for r { fn finalize(&self) { - *(self.i) = *(self.i) + 1; + unsafe { + *(self.i) = *(self.i) + 1; + } } } diff --git a/src/test/compile-fail/regions-in-consts.rs b/src/test/compile-fail/regions-in-consts.rs index 2ba27e888cbe0..c34e5fb29de5a 100644 --- a/src/test/compile-fail/regions-in-consts.rs +++ b/src/test/compile-fail/regions-in-consts.rs @@ -8,9 +8,9 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -const c_x: &'blk int = &22; //~ ERROR Illegal lifetime 'blk: only 'static is allowed here -const c_y: &int = &22; //~ ERROR Illegal anonymous lifetime: only 'static is allowed here -const c_z: &'static int = &22; +static c_x: &'blk int = &22; //~ ERROR Illegal lifetime 'blk: only 'static is allowed here +static c_y: &int = &22; //~ ERROR Illegal anonymous lifetime: only 'static is allowed here +static c_z: &'static int = &22; fn main() { } diff --git a/src/test/compile-fail/regions-infer-contravariance-due-to-immutability.rs b/src/test/compile-fail/regions-infer-contravariance-due-to-immutability.rs index fca8f759da0b2..0b7477a30989e 100644 --- a/src/test/compile-fail/regions-infer-contravariance-due-to-immutability.rs +++ b/src/test/compile-fail/regions-infer-contravariance-due-to-immutability.rs @@ -20,7 +20,7 @@ fn to_shorter_lifetime(bi: contravariant<'r>) { let bj: contravariant<'blk> = bi; } -fn to_longer_lifetime(bi: contravariant<'r>) -> contravariant/&static { +fn to_longer_lifetime(bi: contravariant<'r>) -> contravariant<'static> { bi //~ ERROR mismatched types } diff --git a/src/test/compile-fail/regions-infer-contravariance-due-to-ret.rs b/src/test/compile-fail/regions-infer-contravariance-due-to-ret.rs index d93713f3f2335..15f40a9173582 100644 --- a/src/test/compile-fail/regions-infer-contravariance-due-to-ret.rs +++ b/src/test/compile-fail/regions-infer-contravariance-due-to-ret.rs @@ -13,19 +13,19 @@ // You can upcast to a *smaller region* but not a larger one. This is // the normal case. -struct contravariant { +struct contravariant<'self> { f: @fn() -> &'self int } -fn to_same_lifetime(bi: contravariant/&r) { - let bj: contravariant/&r = bi; +fn to_same_lifetime<'r>(bi: contravariant<'r>) { + let bj: contravariant<'r> = bi; } -fn to_shorter_lifetime(bi: contravariant/&r) { - let bj: contravariant/&blk = bi; +fn to_shorter_lifetime<'r>(bi: contravariant<'r>) { + let bj: contravariant<'blk> = bi; } -fn to_longer_lifetime(bi: contravariant/&r) -> contravariant/&static { +fn to_longer_lifetime<'r>(bi: contravariant<'r>) -> contravariant<'static> { bi //~ ERROR mismatched types } diff --git a/src/test/compile-fail/regions-infer-covariance-due-to-arg.rs b/src/test/compile-fail/regions-infer-covariance-due-to-arg.rs index c527cdf233d6c..c92d770b1b6e4 100644 --- a/src/test/compile-fail/regions-infer-covariance-due-to-arg.rs +++ b/src/test/compile-fail/regions-infer-covariance-due-to-arg.rs @@ -16,15 +16,15 @@ struct covariant { f: @fn(x: &'self int) -> int } -fn to_same_lifetime(bi: covariant/&r) { - let bj: covariant/&r = bi; +fn to_same_lifetime<'r>(bi: covariant<'r>) { + let bj: covariant<'r> = bi; } -fn to_shorter_lifetime(bi: covariant/&r) { - let bj: covariant/&blk = bi; //~ ERROR mismatched types +fn to_shorter_lifetime<'r>(bi: covariant<'r>) { + let bj: covariant<'blk> = bi; //~ ERROR mismatched types } -fn to_longer_lifetime(bi: covariant/&r) -> covariant/&static { +fn to_longer_lifetime<'r>(bi: covariant<'r>) -> covariant<'static> { bi } diff --git a/src/test/compile-fail/regions-infer-invariance-due-to-arg-and-ret.rs b/src/test/compile-fail/regions-infer-invariance-due-to-arg-and-ret.rs index 3ad841923e313..0d4d4056a4401 100644 --- a/src/test/compile-fail/regions-infer-invariance-due-to-arg-and-ret.rs +++ b/src/test/compile-fail/regions-infer-invariance-due-to-arg-and-ret.rs @@ -12,19 +12,19 @@ // // You cannot convert between regions. -struct invariant { +struct invariant<'self> { f: &'self fn(x: &'self int) -> &'self int } -fn to_same_lifetime(bi: invariant<'r>) { +fn to_same_lifetime<'r>(bi: invariant<'r>) { let bj: invariant<'r> = bi; } -fn to_shorter_lifetime(bi: invariant<'r>) { +fn to_shorter_lifetime<'r>(bi: invariant<'r>) { let bj: invariant<'blk> = bi; //~ ERROR mismatched types } -fn to_longer_lifetime(bi: invariant<'r>) -> invariant/&static { +fn to_longer_lifetime<'r>(bi: invariant<'r>) -> invariant<'static> { bi //~ ERROR mismatched types } diff --git a/src/test/compile-fail/regions-infer-invariance-due-to-mutability-3.rs b/src/test/compile-fail/regions-infer-invariance-due-to-mutability-3.rs index 15b39d772f08b..4c9d397f971da 100644 --- a/src/test/compile-fail/regions-infer-invariance-due-to-mutability-3.rs +++ b/src/test/compile-fail/regions-infer-invariance-due-to-mutability-3.rs @@ -8,19 +8,19 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -struct invariant { +struct invariant<'self> { f: @fn(x: @mut &'self int) } -fn to_same_lifetime(bi: invariant/&r) { - let bj: invariant/&r = bi; +fn to_same_lifetime<'r>(bi: invariant<'r>) { + let bj: invariant<'r> = bi; } -fn to_shorter_lifetime(bi: invariant/&r) { - let bj: invariant/&blk = bi; //~ ERROR mismatched types +fn to_shorter_lifetime(bi: invariant<'r>) { + let bj: invariant<'blk> = bi; //~ ERROR mismatched types } -fn to_longer_lifetime(bi: invariant/&r) -> invariant/&static { +fn to_longer_lifetime(bi: invariant<'r>) -> invariant<'static> { bi //~ ERROR mismatched types } diff --git a/src/test/compile-fail/regions-infer-invariance-due-to-mutability-4.rs b/src/test/compile-fail/regions-infer-invariance-due-to-mutability-4.rs index ff2b4246f01b8..6789476974b7a 100644 --- a/src/test/compile-fail/regions-infer-invariance-due-to-mutability-4.rs +++ b/src/test/compile-fail/regions-infer-invariance-due-to-mutability-4.rs @@ -8,19 +8,19 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -struct invariant { +struct invariant<'self> { f: @fn() -> @mut &'self int } -fn to_same_lifetime(bi: invariant/&r) { - let bj: invariant/&r = bi; +fn to_same_lifetime(bi: invariant<'r>) { + let bj: invariant<'r> = bi; } -fn to_shorter_lifetime(bi: invariant/&r) { - let bj: invariant/&blk = bi; //~ ERROR mismatched types +fn to_shorter_lifetime(bi: invariant<'r>) { + let bj: invariant<'blk> = bi; //~ ERROR mismatched types } -fn to_longer_lifetime(bi: invariant/&r) -> invariant/&static { +fn to_longer_lifetime(bi: invariant<'r>) -> invariant<'static> { bi //~ ERROR mismatched types } diff --git a/src/test/compile-fail/regions-infer-invariance-due-to-mutability.rs b/src/test/compile-fail/regions-infer-invariance-due-to-mutability.rs index f9c6e2e36ec95..c2a7f29a8ab5b 100644 --- a/src/test/compile-fail/regions-infer-invariance-due-to-mutability.rs +++ b/src/test/compile-fail/regions-infer-invariance-due-to-mutability.rs @@ -8,19 +8,19 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -struct invariant { +struct invariant<'self> { f: @mut &'self int } -fn to_same_lifetime(bi: invariant<'r>) { +fn to_same_lifetime<'r>(bi: invariant<'r>) { let bj: invariant<'r> = bi; } -fn to_shorter_lifetime(bi: invariant<'r>) { +fn to_shorter_lifetime<'r>(bi: invariant<'r>) { let bj: invariant<'blk> = bi; //~ ERROR mismatched types } -fn to_longer_lifetime(bi: invariant<'r>) -> invariant/&static { +fn to_longer_lifetime<'r>(bi: invariant<'r>) -> invariant<'static> { bi //~ ERROR mismatched types } diff --git a/src/test/compile-fail/regions-trait-3.rs b/src/test/compile-fail/regions-trait-3.rs index e947dbf93083a..072b0e83fdf58 100644 --- a/src/test/compile-fail/regions-trait-3.rs +++ b/src/test/compile-fail/regions-trait-3.rs @@ -11,11 +11,11 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -trait get_ctxt { +trait get_ctxt<'self> { fn get_ctxt(self) -> &'self uint; } -fn make_gc1(gc: @get_ctxt/&a) -> @get_ctxt/&b { +fn make_gc1(gc: @get_ctxt<'a>) -> @get_ctxt<'b> { return gc; //~ ERROR mismatched types: expected `@get_ctxt/&b` but found `@get_ctxt/&a` } @@ -27,7 +27,7 @@ impl get_ctxt for Foo<'self> { fn get_ctxt(&self) -> &'self uint { self.r } } -fn make_gc2(foo: Foo/&a) -> @get_ctxt/&b { +fn make_gc2<'a,'b>(foo: Foo<'a>) -> @get_ctxt<'b> { return @foo as @get_ctxt; //~ ERROR cannot infer an appropriate lifetime } diff --git a/src/test/compile-fail/static-method-privacy.rs b/src/test/compile-fail/static-method-privacy.rs index d9b4112b1bd86..50df4f04971c8 100644 --- a/src/test/compile-fail/static-method-privacy.rs +++ b/src/test/compile-fail/static-method-privacy.rs @@ -1,7 +1,7 @@ mod a { pub struct S; impl S { - static fn new() -> S { S } + fn new() -> S { S } } } diff --git a/src/test/compile-fail/static-region-bound.rs b/src/test/compile-fail/static-region-bound.rs index b70b0cdf88191..500a5b0c8bcbc 100644 --- a/src/test/compile-fail/static-region-bound.rs +++ b/src/test/compile-fail/static-region-bound.rs @@ -1,4 +1,4 @@ -fn f(_: T) {} +fn f(_: T) {} fn main() { let x = @3; diff --git a/src/test/compile-fail/staticness-mismatch.rs b/src/test/compile-fail/staticness-mismatch.rs index 531d722d8bc3c..719da233335e1 100644 --- a/src/test/compile-fail/staticness-mismatch.rs +++ b/src/test/compile-fail/staticness-mismatch.rs @@ -10,7 +10,7 @@ trait foo { - static fn bar(); + fn bar(); } impl foo for int { diff --git a/src/test/compile-fail/tps-invariant-class.rs b/src/test/compile-fail/tps-invariant-class.rs deleted file mode 100644 index 0411eeb05ebe1..0000000000000 --- a/src/test/compile-fail/tps-invariant-class.rs +++ /dev/null @@ -1,33 +0,0 @@ -// Copyright 2012 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -struct box_impl { - f: T, -} - -fn box_impl(f: T) -> box_impl { - box_impl { - f: f - } -} - -fn set_box_impl(b: box_impl<@const T>, v: @const T) { - b.f = v; -} - -fn main() { - let b = box_impl::<@int>(@3); - set_box_impl(b, @mut 5); - //~^ ERROR values differ in mutability - - // No error when type of parameter actually IS @const int - let b = box_impl::<@const int>(@3); - set_box_impl(b, @mut 5); -} diff --git a/src/test/compile-fail/tps-invariant-enum.rs b/src/test/compile-fail/tps-invariant-enum.rs deleted file mode 100644 index 9e19ecdcb7556..0000000000000 --- a/src/test/compile-fail/tps-invariant-enum.rs +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright 2012 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -struct box { - f: T -} - -struct box_impl(box); - -fn set_box_impl(b: box_impl<@const T>, v: @const T) { - b.f = v; -} - -fn main() { - let b = box_impl::<@int>(box::<@int> {f: @3}); - set_box_impl(b, @mut 5); - //~^ ERROR values differ in mutability - - // No error when type of parameter actually IS @const int - let x: @const int = @3; // only way I could find to upcast - let b = box_impl::<@const int>(box::<@const int>{f: x}); - set_box_impl(b, @mut 5); -} diff --git a/src/test/compile-fail/tps-invariant-trait.rs b/src/test/compile-fail/tps-invariant-trait.rs deleted file mode 100644 index 127aa23d6aba4..0000000000000 --- a/src/test/compile-fail/tps-invariant-trait.rs +++ /dev/null @@ -1,41 +0,0 @@ -// Copyright 2012 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -trait box_trait { - fn get(&self) -> T; - fn set(&self, t: T); -} - -struct box { - f: T -} - -struct box_impl(box); - -impl box_trait for box_impl { - fn get(&self) -> T { return self.f; } - fn set(&self, t: T) { self.f = t; } -} - -fn set_box_trait(b: @box_trait<@const T>, v: @const T) { - b.set(v); -} - -fn set_box_impl(b: box_impl<@const T>, v: @const T) { - b.set(v); -} - -fn main() { - let b = box_impl::<@int>(box::<@int> {f: @3}); - set_box_trait(@b as @box_trait<@int>, @mut 5); - //~^ ERROR values differ in mutability - set_box_impl(b, @mut 5); - //~^ ERROR values differ in mutability -} diff --git a/src/test/compile-fail/trait-impl-method-mismatch.rs b/src/test/compile-fail/trait-impl-method-mismatch.rs index 6676cde3c96a6..7f4c227d2d083 100644 --- a/src/test/compile-fail/trait-impl-method-mismatch.rs +++ b/src/test/compile-fail/trait-impl-method-mismatch.rs @@ -10,22 +10,12 @@ trait Mumbo { fn jumbo(&self, x: @uint) -> uint; - fn jambo(&self, x: @const uint) -> uint; - fn jbmbo(&self) -> @uint; } impl Mumbo for uint { // Cannot have a larger effect than the trait: unsafe fn jumbo(&self, x: @uint) { *self + *x; } //~^ ERROR expected impure fn but found unsafe fn - - // Cannot accept a narrower range of parameters: - fn jambo(&self, x: @uint) { *self + *x; } - //~^ ERROR values differ in mutability - - // Cannot return a wider range of values: - fn jbmbo(&self) -> @const uint { @const 0 } - //~^ ERROR values differ in mutability } fn main() {} diff --git a/src/test/compile-fail/trait-impl-subtype.rs b/src/test/compile-fail/trait-impl-subtype.rs deleted file mode 100644 index eb34ebbdfb0d8..0000000000000 --- a/src/test/compile-fail/trait-impl-subtype.rs +++ /dev/null @@ -1,31 +0,0 @@ -// Copyright 2012 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -trait Mumbo { - fn jumbo(&self, x: @uint) -> uint; -} - -impl Mumbo for uint { - // Note: this method def is ok, it is more accepting and - // less effecting than the trait method: - pure fn jumbo(&self, x: @const uint) -> uint { *self + *x } -} - -fn main() { - let a = 3u; - let b = a.jumbo(@mut 6); - - let x = @a as @Mumbo; - let y = x.jumbo(@mut 6); //~ ERROR values differ in mutability - let z = x.jumbo(@6); -} - - - diff --git a/src/test/compile-fail/unique-vec-res.rs b/src/test/compile-fail/unique-vec-res.rs index 3f4636328b661..a3c51e2b7b1fc 100644 --- a/src/test/compile-fail/unique-vec-res.rs +++ b/src/test/compile-fail/unique-vec-res.rs @@ -12,9 +12,12 @@ struct r { i: @mut int, } +#[unsafe_destructor] impl Drop for r { fn finalize(&self) { - *(self.i) = *(self.i) + 1; + unsafe { + *(self.i) = *(self.i) + 1; + } } } diff --git a/src/test/compile-fail/xc-private-method.rs b/src/test/compile-fail/xc-private-method.rs new file mode 100644 index 0000000000000..d194820df9408 --- /dev/null +++ b/src/test/compile-fail/xc-private-method.rs @@ -0,0 +1,9 @@ +// xfail-fast +// aux-build:xc_private_method_lib.rs + +extern mod xc_private_method_lib; + +fn main() { + let _ = xc_private_method_lib::Foo::new(); //~ ERROR function `new` is private +} + diff --git a/src/test/run-fail/assert-eq-macro-fail.rs b/src/test/run-fail/assert-eq-macro-fail.rs new file mode 100644 index 0000000000000..d3177e7c0a8a8 --- /dev/null +++ b/src/test/run-fail/assert-eq-macro-fail.rs @@ -0,0 +1,8 @@ +// error-pattern:expected: 15, given: 14 + +#[deriving(Eq)] +struct Point { x : int } + +fn main() { + assert_eq!(14,15); +} diff --git a/src/test/run-fail/die-macro-pure.rs b/src/test/run-fail/die-macro-pure.rs index 4479c2ecbeb35..296fba2ae9bcc 100644 --- a/src/test/run-fail/die-macro-pure.rs +++ b/src/test/run-fail/die-macro-pure.rs @@ -1,6 +1,6 @@ // error-pattern:test -pure fn f() { +fn f() { fail!(~"test"); } diff --git a/src/test/run-fail/if-check-fail.rs b/src/test/run-fail/if-check-fail.rs index a3831a10874c3..a77d520b07e95 100644 --- a/src/test/run-fail/if-check-fail.rs +++ b/src/test/run-fail/if-check-fail.rs @@ -9,7 +9,7 @@ // except according to those terms. // error-pattern:Number is odd -pure fn even(x: uint) -> bool { +fn even(x: uint) -> bool { if x < 2u { return false; } else if x == 2u { return true; } else { return even(x - 2u); } diff --git a/src/test/run-fail/unwind-misc-1.rs b/src/test/run-fail/unwind-misc-1.rs index 572d5a90751d1..06a3f0113b01c 100644 --- a/src/test/run-fail/unwind-misc-1.rs +++ b/src/test/run-fail/unwind-misc-1.rs @@ -8,15 +8,13 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// error-pattern:fail +// xfail-test - issue #5512, fails but exits with 0 -extern mod std; -use std::oldmap; -use std::oldmap::HashMap; +// error-pattern:fail fn main() { let count = @mut 0u; - let map = oldmap::HashMap(); + let mut map = core::hashmap::linear::LinearMap::new(); let mut arr = ~[]; for uint::range(0u, 10u) |i| { arr += ~[@~"key stuff"]; diff --git a/src/test/run-fail/unwind-resource-fail3.rs b/src/test/run-fail/unwind-resource-fail3.rs index 27e0ebe77614f..d3ba5737b71f6 100644 --- a/src/test/run-fail/unwind-resource-fail3.rs +++ b/src/test/run-fail/unwind-resource-fail3.rs @@ -17,6 +17,7 @@ struct faily_box { fn faily_box(i: @int) -> faily_box { faily_box { i: i } } +#[unsafe_destructor] impl Drop for faily_box { fn finalize(&self) { fail!(~"quux"); diff --git a/src/test/run-pass-fulldeps/qquote.rs b/src/test/run-pass-fulldeps/qquote.rs index 613480e3a63cd..779fd3e490416 100644 --- a/src/test/run-pass-fulldeps/qquote.rs +++ b/src/test/run-pass-fulldeps/qquote.rs @@ -63,8 +63,8 @@ fn main() { let ty = quote_ty!(int); check_pp(ext_cx, ty, pprust::print_type, ~"int"); - let item = quote_item!(const x : int = 10;).get(); - check_pp(ext_cx, item, pprust::print_item, ~"const x: int = 10;"); + let item = quote_item!(static x : int = 10;).get(); + check_pp(ext_cx, item, pprust::print_item, ~"static x: int = 10;"); let stmt = quote_stmt!(let x = 20;); check_pp(ext_cx, *stmt, pprust::print_stmt, ~"let x = 20;"); diff --git a/src/test/run-pass-fulldeps/quote-tokens.rs b/src/test/run-pass-fulldeps/quote-tokens.rs index f324f2d198b0b..ccee163eafe5b 100644 --- a/src/test/run-pass-fulldeps/quote-tokens.rs +++ b/src/test/run-pass-fulldeps/quote-tokens.rs @@ -19,7 +19,7 @@ fn syntax_extension(ext_cx: @ext_ctxt) { let p_toks : ~[syntax::ast::token_tree] = quote_tokens!((x, 1 .. 4, *)); let a: @syntax::ast::expr = quote_expr!(1 + 2); - let _b: Option<@syntax::ast::item> = quote_item!( const foo : int = $e_toks; ); + let _b: Option<@syntax::ast::item> = quote_item!( static foo : int = $e_toks; ); let _c: @syntax::ast::pat = quote_pat!( (x, 1 .. 4, *) ); let _d: @syntax::ast::stmt = quote_stmt!( let x = $a; ); let _e: @syntax::ast::expr = quote_expr!( match foo { $p_toks => 10 } ); diff --git a/src/test/run-pass/alignment-gep-tup-like-1.rs b/src/test/run-pass/alignment-gep-tup-like-1.rs index 4c99e6f1a099c..f9ba6ed7f5438 100644 --- a/src/test/run-pass/alignment-gep-tup-like-1.rs +++ b/src/test/run-pass/alignment-gep-tup-like-1.rs @@ -12,7 +12,7 @@ struct pair { a: A, b: B } -fn f(a: A, b: u16) -> @fn() -> (A, u16) { +fn f(a: A, b: u16) -> @fn() -> (A, u16) { let result: @fn() -> (A, u16) = || (a, b); result } diff --git a/src/test/run-pass/anon-trait-static-method.rs b/src/test/run-pass/anon-trait-static-method.rs index 2ec0b59e13fee..8e11786786ff9 100644 --- a/src/test/run-pass/anon-trait-static-method.rs +++ b/src/test/run-pass/anon-trait-static-method.rs @@ -13,7 +13,7 @@ struct Foo { } pub impl Foo { - static fn new() -> Foo { + fn new() -> Foo { Foo { x: 3 } } } diff --git a/src/test/run-pass/assert-eq-macro-success.rs b/src/test/run-pass/assert-eq-macro-success.rs new file mode 100644 index 0000000000000..b204e1aba3a71 --- /dev/null +++ b/src/test/run-pass/assert-eq-macro-success.rs @@ -0,0 +1,10 @@ +#[deriving(Eq)] +struct Point { x : int } + +fn main() { + assert_eq!(14,14); + assert_eq!(~"abc",~"abc"); + assert_eq!(~Point{x:34},~Point{x:34}); + assert_eq!(&Point{x:34},&Point{x:34}); + assert_eq!(@Point{x:34},@Point{x:34}); +} diff --git a/src/test/run-pass/auto-encode.rs b/src/test/run-pass/auto-encode.rs index b6fdb07789c8d..1a8ad446c7954 100644 --- a/src/test/run-pass/auto-encode.rs +++ b/src/test/run-pass/auto-encode.rs @@ -60,7 +60,7 @@ enum Expr { } impl cmp::Eq for Expr { - pure fn eq(&self, other: &Expr) -> bool { + fn eq(&self, other: &Expr) -> bool { match *self { Val(e0a) => { match *other { @@ -82,18 +82,18 @@ impl cmp::Eq for Expr { } } } - pure fn ne(&self, other: &Expr) -> bool { !(*self).eq(other) } + fn ne(&self, other: &Expr) -> bool { !(*self).eq(other) } } impl cmp::Eq for Point { - pure fn eq(&self, other: &Point) -> bool { + fn eq(&self, other: &Point) -> bool { self.x == other.x && self.y == other.y } - pure fn ne(&self, other: &Point) -> bool { !(*self).eq(other) } + fn ne(&self, other: &Point) -> bool { !(*self).eq(other) } } impl cmp::Eq for Quark { - pure fn eq(&self, other: &Quark) -> bool { + fn eq(&self, other: &Quark) -> bool { match *self { Top(ref q) => { match *other { @@ -109,19 +109,19 @@ impl cmp::Eq for Quark { }, } } - pure fn ne(&self, other: &Quark) -> bool { !(*self).eq(other) } + fn ne(&self, other: &Quark) -> bool { !(*self).eq(other) } } impl cmp::Eq for CLike { - pure fn eq(&self, other: &CLike) -> bool { + fn eq(&self, other: &CLike) -> bool { (*self) as int == *other as int } - pure fn ne(&self, other: &CLike) -> bool { !self.eq(other) } + fn ne(&self, other: &CLike) -> bool { !self.eq(other) } } #[auto_encode] #[auto_decode] -#[deriving_eq] +#[deriving(Eq)] struct Spanned { lo: uint, hi: uint, diff --git a/src/test/run-pass/auto-ref-slice-plus-ref.rs b/src/test/run-pass/auto-ref-slice-plus-ref.rs index 39fe34bfe5286..65366a350efa3 100644 --- a/src/test/run-pass/auto-ref-slice-plus-ref.rs +++ b/src/test/run-pass/auto-ref-slice-plus-ref.rs @@ -12,18 +12,18 @@ // and also references them to create the &self pointer trait MyIter { - pure fn test_imm(&self); - pure fn test_const(&const self); + fn test_imm(&self); + fn test_const(&const self); } impl MyIter for &'self [int] { - pure fn test_imm(&self) { fail_unless!(self[0] == 1) } - pure fn test_const(&const self) { fail_unless!(self[0] == 1) } + fn test_imm(&self) { fail_unless!(self[0] == 1) } + fn test_const(&const self) { fail_unless!(self[0] == 1) } } impl MyIter for &'self str { - pure fn test_imm(&self) { fail_unless!(*self == "test") } - pure fn test_const(&const self) { fail_unless!(*self == "test") } + fn test_imm(&self) { fail_unless!(*self == "test") } + fn test_const(&const self) { fail_unless!(*self == "test") } } pub fn main() { diff --git a/src/test/run-pass/binops.rs b/src/test/run-pass/binops.rs index bcc76cc35858f..3f5547df17d8f 100644 --- a/src/test/run-pass/binops.rs +++ b/src/test/run-pass/binops.rs @@ -88,7 +88,7 @@ mod test { } } -#[deriving_eq] +#[deriving(Eq)] struct p { x: int, y: int, diff --git a/src/test/run-pass/class-impl-very-parameterized-trait.rs b/src/test/run-pass/class-impl-very-parameterized-trait.rs index a0a4ea19964f7..281d520be0f60 100644 --- a/src/test/run-pass/class-impl-very-parameterized-trait.rs +++ b/src/test/run-pass/class-impl-very-parameterized-trait.rs @@ -16,10 +16,10 @@ use core::iter::BaseIter; enum cat_type { tuxedo, tabby, tortoiseshell } impl cmp::Eq for cat_type { - pure fn eq(&self, other: &cat_type) -> bool { + fn eq(&self, other: &cat_type) -> bool { ((*self) as uint) == ((*other) as uint) } - pure fn ne(&self, other: &cat_type) -> bool { !(*self).eq(other) } + fn ne(&self, other: &cat_type) -> bool { !(*self).eq(other) } } // Very silly -- this just returns the value of the name field @@ -50,7 +50,7 @@ pub impl cat { } impl BaseIter<(int, &'self T)> for cat { - pure fn each(&self, f: &fn(&(int, &'self T)) -> bool) { + fn each(&self, f: &fn(&(int, &'self T)) -> bool) { let mut n = int::abs(self.meows); while n > 0 { if !f(&(n, &self.name)) { break; } @@ -58,12 +58,12 @@ impl BaseIter<(int, &'self T)> for cat { } } - pure fn size_hint(&self) -> Option { Some(self.len()) } + fn size_hint(&self) -> Option { Some(self.len()) } } impl Container for cat { - pure fn len(&const self) -> uint { self.meows as uint } - pure fn is_empty(&const self) -> bool { self.meows == 0 } + fn len(&const self) -> uint { self.meows as uint } + fn is_empty(&const self) -> bool { self.meows == 0 } } impl Mutable for cat { @@ -71,13 +71,13 @@ impl Mutable for cat { } impl Map for cat { - pure fn contains_key(&self, k: &int) -> bool { *k <= self.meows } + fn contains_key(&self, k: &int) -> bool { *k <= self.meows } - pure fn each_key(&self, f: &fn(v: &int) -> bool) { + fn each_key(&self, f: &fn(v: &int) -> bool) { for self.each |&(k, _)| { if !f(&k) { break; } loop;}; } - pure fn each_value(&self, f: &fn(v: &T) -> bool) { + fn each_value(&self, f: &fn(v: &T) -> bool) { for self.each |&(_, v)| { if !f(v) { break; } loop;}; } @@ -90,7 +90,7 @@ impl Map for cat { true } - pure fn find(&self, k: &int) -> Option<&'self T> { + fn find(&self, k: &int) -> Option<&'self T> { if *k <= self.meows { Some(&self.name) } else { @@ -98,6 +98,8 @@ impl Map for cat { } } + fn find_mut(&mut self, k: &int) -> Option<&'self mut T> { fail!() } + fn remove(&mut self, k: &int) -> bool { if self.find(k).is_some() { self.meows -= *k; true @@ -108,14 +110,14 @@ impl Map for cat { } pub impl cat { - pure fn get(&self, k: &int) -> &'self T { + fn get(&self, k: &int) -> &'self T { match self.find(k) { Some(v) => { v } None => { fail!(~"epic fail"); } } } - static pure fn new(in_x: int, in_y: int, in_name: T) -> cat { + fn new(in_x: int, in_y: int, in_name: T) -> cat { cat{meows: in_x, how_hungry: in_y, name: in_name } } } diff --git a/src/test/run-pass/class-separate-impl.rs b/src/test/run-pass/class-separate-impl.rs index bb07597a1887c..168f2d872e737 100644 --- a/src/test/run-pass/class-separate-impl.rs +++ b/src/test/run-pass/class-separate-impl.rs @@ -51,7 +51,7 @@ fn cat(in_x : uint, in_y : int, in_name: ~str) -> cat { } impl ToStr for cat { - pure fn to_str(&self) -> ~str { + fn to_str(&self) -> ~str { // FIXME #5384: this unsafe block is to work around purity unsafe { self.name.clone() diff --git a/src/test/run-pass/close-over-big-then-small-data.rs b/src/test/run-pass/close-over-big-then-small-data.rs index 518bc48b8ae62..5a853d9fe21d9 100644 --- a/src/test/run-pass/close-over-big-then-small-data.rs +++ b/src/test/run-pass/close-over-big-then-small-data.rs @@ -16,7 +16,7 @@ struct Pair { a: A, b: B } -fn f(a: A, b: u16) -> @fn() -> (A, u16) { +fn f(a: A, b: u16) -> @fn() -> (A, u16) { let result: @fn() -> (A, u16) = || (a, b); result } diff --git a/src/test/run-pass/coerce-reborrow-imm-ptr-arg.rs b/src/test/run-pass/coerce-reborrow-imm-ptr-arg.rs index 905046756f6ee..e40272bb7a4d5 100644 --- a/src/test/run-pass/coerce-reborrow-imm-ptr-arg.rs +++ b/src/test/run-pass/coerce-reborrow-imm-ptr-arg.rs @@ -1,4 +1,4 @@ -pure fn negate(x: &int) -> int { +fn negate(x: &int) -> int { -*x } diff --git a/src/test/run-pass/coerce-reborrow-imm-ptr-rcvr.rs b/src/test/run-pass/coerce-reborrow-imm-ptr-rcvr.rs index 54d9758aa2145..12ca00fedd3f9 100644 --- a/src/test/run-pass/coerce-reborrow-imm-ptr-rcvr.rs +++ b/src/test/run-pass/coerce-reborrow-imm-ptr-rcvr.rs @@ -3,7 +3,7 @@ struct SpeechMaker { } pub impl SpeechMaker { - pure fn how_many(&const self) -> uint { self.speeches } + fn how_many(&const self) -> uint { self.speeches } } fn foo(speaker: &const SpeechMaker) -> uint { diff --git a/src/test/run-pass/coerce-reborrow-imm-vec-arg.rs b/src/test/run-pass/coerce-reborrow-imm-vec-arg.rs index a18b4a2b0c691..ad5eb50ccef30 100644 --- a/src/test/run-pass/coerce-reborrow-imm-vec-arg.rs +++ b/src/test/run-pass/coerce-reborrow-imm-vec-arg.rs @@ -1,6 +1,6 @@ // xfail-test -pure fn sum(x: &[int]) -> int { +fn sum(x: &[int]) -> int { let mut sum = 0; for x.each |y| { sum += *y; } return sum; diff --git a/src/test/run-pass/coherence-impl-in-fn.rs b/src/test/run-pass/coherence-impl-in-fn.rs index 4fb43092500b3..7643799df0637 100644 --- a/src/test/run-pass/coherence-impl-in-fn.rs +++ b/src/test/run-pass/coherence-impl-in-fn.rs @@ -11,9 +11,9 @@ pub fn main() { enum x { foo } impl ::core::cmp::Eq for x { - pure fn eq(&self, other: &x) -> bool { + fn eq(&self, other: &x) -> bool { (*self) as int == (*other) as int } - pure fn ne(&self, other: &x) -> bool { !(*self).eq(other) } + fn ne(&self, other: &x) -> bool { !(*self).eq(other) } } } diff --git a/src/test/run-pass/conditional-compile.rs b/src/test/run-pass/conditional-compile.rs index 223825f60a749..194f0e71b1733 100644 --- a/src/test/run-pass/conditional-compile.rs +++ b/src/test/run-pass/conditional-compile.rs @@ -15,9 +15,9 @@ use flippity; #[cfg(bogus)] -const b: bool = false; +static b: bool = false; -const b: bool = true; +static b: bool = true; mod rustrt { #[cfg(bogus)] @@ -102,8 +102,8 @@ fn test_in_fn_ctxt() { f(); #[cfg(bogus)] - const i: int = 0; - const i: int = 1; + static i: int = 0; + static i: int = 1; fail_unless!((i == 1)); } @@ -130,9 +130,9 @@ mod test_methods { impl Fooable for Foo { #[cfg(bogus)] - static fn what(&self) { } + fn what(&self) { } - static fn what(&self) { } + fn what(&self) { } #[cfg(bogus)] fn the(&self) { } @@ -142,9 +142,9 @@ mod test_methods { trait Fooable { #[cfg(bogus)] - static fn what(&self); + fn what(&self); - static fn what(&self); + fn what(&self); #[cfg(bogus)] fn the(&self); diff --git a/src/test/run-pass/const-autoderef-newtype.rs b/src/test/run-pass/const-autoderef-newtype.rs index cb56ab3633565..a157c46403bf3 100644 --- a/src/test/run-pass/const-autoderef-newtype.rs +++ b/src/test/run-pass/const-autoderef-newtype.rs @@ -9,8 +9,8 @@ // except according to those terms. struct S(&'static [int]); -const C0: S = S([3]); -const C1: int = C0[0]; +static C0: S = S([3]); +static C1: int = C0[0]; pub fn main() { fail_unless!(C1 == 3); diff --git a/src/test/run-pass/const-autoderef.rs b/src/test/run-pass/const-autoderef.rs index 9fb6c4aa0dbd9..fa482c38d145b 100644 --- a/src/test/run-pass/const-autoderef.rs +++ b/src/test/run-pass/const-autoderef.rs @@ -8,10 +8,10 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -const A: [u8 * 1] = ['h' as u8]; -const B: u8 = (&A)[0]; -const C: &'static &'static &'static &'static [u8 * 1] = & & & &A; -const D: u8 = (&C)[0]; +static A: [u8 * 1] = ['h' as u8]; +static B: u8 = (&A)[0]; +static C: &'static &'static &'static &'static [u8 * 1] = & & & &A; +static D: u8 = (&C)[0]; pub fn main() { fail_unless!(B == A[0]); diff --git a/src/test/run-pass/const-big-enum.rs b/src/test/run-pass/const-big-enum.rs index a7d1739a56b9c..97544da41c024 100644 --- a/src/test/run-pass/const-big-enum.rs +++ b/src/test/run-pass/const-big-enum.rs @@ -14,7 +14,7 @@ enum Foo { Quux(u64, u16) } -const X: Foo = Baz; +static X: Foo = Baz; pub fn main() { match X { @@ -34,5 +34,5 @@ pub fn main() { } } -const Y: Foo = Bar(2654435769); -const Z: Foo = Quux(0x123456789abcdef0, 0x1234); +static Y: Foo = Bar(2654435769); +static Z: Foo = Quux(0x123456789abcdef0, 0x1234); diff --git a/src/test/run-pass/const-cast-ptr-int.rs b/src/test/run-pass/const-cast-ptr-int.rs index 2d7dc349c0085..eefd1aa642e1c 100644 --- a/src/test/run-pass/const-cast-ptr-int.rs +++ b/src/test/run-pass/const-cast-ptr-int.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -const a: *u8 = 0 as *u8; +static a: *u8 = 0 as *u8; fn main() { fail_unless!(a == ptr::null()); diff --git a/src/test/run-pass/const-cast.rs b/src/test/run-pass/const-cast.rs index 64c6f368f2bfb..83f365a632018 100644 --- a/src/test/run-pass/const-cast.rs +++ b/src/test/run-pass/const-cast.rs @@ -10,10 +10,10 @@ extern fn foo() {} -const x: *u8 = foo; -const y: *libc::c_void = x as *libc::c_void; -const a: &'static int = &10; -const b: *int = a as *int; +static x: *u8 = foo; +static y: *libc::c_void = x as *libc::c_void; +static a: &'static int = &10; +static b: *int = a as *int; fn main() { fail_unless!(x as *libc::c_void == y); diff --git a/src/test/run-pass/const-const.rs b/src/test/run-pass/const-const.rs index 142bcb7f9a8e2..3f8a7da4c149d 100644 --- a/src/test/run-pass/const-const.rs +++ b/src/test/run-pass/const-const.rs @@ -8,8 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -const a: int = 1; -const b: int = a + 2; +static a: int = 1; +static b: int = a + 2; pub fn main() { fail_unless!(b == 3); diff --git a/src/test/run-pass/const-contents.rs b/src/test/run-pass/const-contents.rs index 72db11c64e885..379089cc2a2d2 100644 --- a/src/test/run-pass/const-contents.rs +++ b/src/test/run-pass/const-contents.rs @@ -10,12 +10,12 @@ // Issue #570 -const lsl : int = 1 << 2; -const add : int = 1 + 2; -const addf : float = 1.0f + 2.0f; -const not : int = !0; -const notb : bool = !true; -const neg : int = -(1); +static lsl : int = 1 << 2; +static add : int = 1 + 2; +static addf : float = 1.0f + 2.0f; +static not : int = !0; +static notb : bool = !true; +static neg : int = -(1); pub fn main() { fail_unless!((lsl == 4)); diff --git a/src/test/run-pass/const-cross-crate-const.rs b/src/test/run-pass/const-cross-crate-const.rs index e01519ae8a547..130f43cfddd34 100644 --- a/src/test/run-pass/const-cross-crate-const.rs +++ b/src/test/run-pass/const-cross-crate-const.rs @@ -12,9 +12,9 @@ // aux-build:cci_const.rs extern mod cci_const; -const foo: &'static str = cci_const::foopy; -const a: uint = cci_const::uint_val; -const b: uint = cci_const::uint_expr + 5; +static foo: &'static str = cci_const::foopy; +static a: uint = cci_const::uint_val; +static b: uint = cci_const::uint_expr + 5; fn main() { fail_unless!(a == 12); diff --git a/src/test/run-pass/const-cross-crate-extern.rs b/src/test/run-pass/const-cross-crate-extern.rs index e1a4fc634bae8..723835a46d849 100644 --- a/src/test/run-pass/const-cross-crate-extern.rs +++ b/src/test/run-pass/const-cross-crate-extern.rs @@ -13,7 +13,7 @@ extern mod cci_const; use cci_const::bar; -const foo: *u8 = bar; +static foo: *u8 = bar; fn main() { fail_unless!(foo == cci_const::bar); diff --git a/src/test/run-pass/const-deref.rs b/src/test/run-pass/const-deref.rs index 71ae273aaa3b2..a69ca9cb93979 100644 --- a/src/test/run-pass/const-deref.rs +++ b/src/test/run-pass/const-deref.rs @@ -8,11 +8,11 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -const C: &'static int = &1000; -const D: int = *C; +static C: &'static int = &1000; +static D: int = *C; struct S(&'static int); -const E: &'static S = &S(C); -const F: int = ***E; +static E: &'static S = &S(C); +static F: int = ***E; pub fn main() { fail_unless!(D == 1000); diff --git a/src/test/run-pass/const-enum-byref-self.rs b/src/test/run-pass/const-enum-byref-self.rs index 57cfdd2f9d470..c4e1ea727e47e 100644 --- a/src/test/run-pass/const-enum-byref-self.rs +++ b/src/test/run-pass/const-enum-byref-self.rs @@ -9,7 +9,7 @@ // except according to those terms. enum E { V, VV(int) } -const C: E = V; +static C: E = V; pub impl E { fn method(&self) { diff --git a/src/test/run-pass/const-enum-byref.rs b/src/test/run-pass/const-enum-byref.rs index a8d24dc300a85..83fafad4f99bb 100644 --- a/src/test/run-pass/const-enum-byref.rs +++ b/src/test/run-pass/const-enum-byref.rs @@ -9,7 +9,7 @@ // except according to those terms. enum E { V, VV(int) } -const C: E = V; +static C: E = V; fn f(a: &E) { match *a { diff --git a/src/test/run-pass/const-enum-cast.rs b/src/test/run-pass/const-enum-cast.rs index ac0bbfda20d9b..20d7a94ccacf6 100644 --- a/src/test/run-pass/const-enum-cast.rs +++ b/src/test/run-pass/const-enum-cast.rs @@ -12,10 +12,10 @@ enum A { A1, A2 } enum B { B1=0, B2=2 } fn main () { - const c1: int = A2 as int; - const c2: int = B2 as int; - const c3: float = A2 as float; - const c4: float = B2 as float; + static c1: int = A2 as int; + static c2: int = B2 as int; + static c3: float = A2 as float; + static c4: float = B2 as float; let a1 = A2 as int; let a2 = B2 as int; let a3 = A2 as float; diff --git a/src/test/run-pass/const-enum-ptr.rs b/src/test/run-pass/const-enum-ptr.rs index 594350d29885c..c1e3889d613d9 100644 --- a/src/test/run-pass/const-enum-ptr.rs +++ b/src/test/run-pass/const-enum-ptr.rs @@ -9,7 +9,7 @@ // except according to those terms. enum E { V0, V1(int) } -const C: &'static E = &V0; +static C: &'static E = &V0; pub fn main() { match *C { diff --git a/src/test/run-pass/const-enum-struct.rs b/src/test/run-pass/const-enum-struct.rs index 8ab470461eb61..7da171cc00653 100644 --- a/src/test/run-pass/const-enum-struct.rs +++ b/src/test/run-pass/const-enum-struct.rs @@ -10,7 +10,7 @@ enum E { V16(u16), V32(u32) } struct S { a: E, b: u16, c: u16 } -const C: S = S { a: V16(0xDEAD), b: 0x600D, c: 0xBAD }; +static C: S = S { a: V16(0xDEAD), b: 0x600D, c: 0xBAD }; pub fn main() { let n = C.b; diff --git a/src/test/run-pass/const-enum-struct2.rs b/src/test/run-pass/const-enum-struct2.rs index 49078b8efe2f2..c24db8414c416 100644 --- a/src/test/run-pass/const-enum-struct2.rs +++ b/src/test/run-pass/const-enum-struct2.rs @@ -10,7 +10,7 @@ enum E { V0, V16(u16) } struct S { a: E, b: u16, c: u16 } -const C: S = S { a: V0, b: 0x600D, c: 0xBAD }; +static C: S = S { a: V0, b: 0x600D, c: 0xBAD }; pub fn main() { let n = C.b; diff --git a/src/test/run-pass/const-enum-structlike.rs b/src/test/run-pass/const-enum-structlike.rs index 3faad1fee7e5e..86640bcc408e1 100644 --- a/src/test/run-pass/const-enum-structlike.rs +++ b/src/test/run-pass/const-enum-structlike.rs @@ -13,7 +13,7 @@ enum E { S1 { u: uint } } -const C: E = S1 { u: 23 }; +static C: E = S1 { u: 23 }; fn main() { match C { diff --git a/src/test/run-pass/const-enum-tuple.rs b/src/test/run-pass/const-enum-tuple.rs index d46207ea8123b..acefd4ff878b8 100644 --- a/src/test/run-pass/const-enum-tuple.rs +++ b/src/test/run-pass/const-enum-tuple.rs @@ -9,7 +9,7 @@ // except according to those terms. enum E { V16(u16), V32(u32) } -const C: (E, u16, u16) = (V16(0xDEAD), 0x600D, 0xBAD); +static C: (E, u16, u16) = (V16(0xDEAD), 0x600D, 0xBAD); pub fn main() { let (_, n, _) = C; diff --git a/src/test/run-pass/const-enum-tuple2.rs b/src/test/run-pass/const-enum-tuple2.rs index 08007b5b67d0e..63f1f41d9ab5a 100644 --- a/src/test/run-pass/const-enum-tuple2.rs +++ b/src/test/run-pass/const-enum-tuple2.rs @@ -9,7 +9,7 @@ // except according to those terms. enum E { V0, V16(u16) } -const C: (E, u16, u16) = (V0, 0x600D, 0xBAD); +static C: (E, u16, u16) = (V0, 0x600D, 0xBAD); pub fn main() { let (_, n, _) = C; diff --git a/src/test/run-pass/const-enum-tuplestruct.rs b/src/test/run-pass/const-enum-tuplestruct.rs index a88bbca7919d3..b0d321abb09e7 100644 --- a/src/test/run-pass/const-enum-tuplestruct.rs +++ b/src/test/run-pass/const-enum-tuplestruct.rs @@ -10,7 +10,7 @@ enum E { V16(u16), V32(u32) } struct S(E, u16, u16); -const C: S = S(V16(0xDEAD), 0x600D, 0xBAD); +static C: S = S(V16(0xDEAD), 0x600D, 0xBAD); pub fn main() { let S(_, n, _) = C; diff --git a/src/test/run-pass/const-enum-tuplestruct2.rs b/src/test/run-pass/const-enum-tuplestruct2.rs index 4bbadd40574b5..7fa04af3f9a58 100644 --- a/src/test/run-pass/const-enum-tuplestruct2.rs +++ b/src/test/run-pass/const-enum-tuplestruct2.rs @@ -10,7 +10,7 @@ enum E { V0, V16(u16) } struct S(E, u16, u16); -const C: S = S(V0, 0x600D, 0xBAD); +static C: S = S(V0, 0x600D, 0xBAD); pub fn main() { let S(_, n, _) = C; diff --git a/src/test/run-pass/const-enum-vec-index.rs b/src/test/run-pass/const-enum-vec-index.rs index 6dde7cc41ec7c..fd11fc422726f 100644 --- a/src/test/run-pass/const-enum-vec-index.rs +++ b/src/test/run-pass/const-enum-vec-index.rs @@ -9,9 +9,9 @@ // except according to those terms. enum E { V1(int), V0 } -const C: &'static [E] = &[V0, V1(0xDEADBEE)]; -const C0: E = C[0]; -const C1: E = C[1]; +static C: &'static [E] = &[V0, V1(0xDEADBEE)]; +static C0: E = C[0]; +static C1: E = C[1]; pub fn main() { match C0 { diff --git a/src/test/run-pass/const-enum-vec-ptr.rs b/src/test/run-pass/const-enum-vec-ptr.rs index b398bfbf0d5c1..8d152dca54c31 100644 --- a/src/test/run-pass/const-enum-vec-ptr.rs +++ b/src/test/run-pass/const-enum-vec-ptr.rs @@ -9,7 +9,7 @@ // except according to those terms. enum E { V1(int), V0 } -const C: &'static [E] = &[V0, V1(0xDEADBEE), V0]; +static C: &'static [E] = &[V0, V1(0xDEADBEE), V0]; pub fn main() { match C[1] { diff --git a/src/test/run-pass/const-enum-vector.rs b/src/test/run-pass/const-enum-vector.rs index 48b3c774e3969..db7982c451fa0 100644 --- a/src/test/run-pass/const-enum-vector.rs +++ b/src/test/run-pass/const-enum-vector.rs @@ -9,7 +9,7 @@ // except according to those terms. enum E { V1(int), V0 } -const C: [E * 3] = [V0, V1(0xDEADBEE), V0]; +static C: [E * 3] = [V0, V1(0xDEADBEE), V0]; pub fn main() { match C[1] { diff --git a/src/test/run-pass/const-expr-in-fixed-length-vec.rs b/src/test/run-pass/const-expr-in-fixed-length-vec.rs index aa5c4cbbc1d0f..69585c9d31c9e 100644 --- a/src/test/run-pass/const-expr-in-fixed-length-vec.rs +++ b/src/test/run-pass/const-expr-in-fixed-length-vec.rs @@ -13,7 +13,7 @@ fn main() { - const FOO: int = 2; + static FOO: int = 2; let _v: [int * FOO*3]; } diff --git a/src/test/run-pass/const-expr-in-vec-repeat.rs b/src/test/run-pass/const-expr-in-vec-repeat.rs index 76952ef730fa1..a04c588c07bc1 100644 --- a/src/test/run-pass/const-expr-in-vec-repeat.rs +++ b/src/test/run-pass/const-expr-in-vec-repeat.rs @@ -12,7 +12,7 @@ fn main() { - const FOO: int = 2; + static FOO: int = 2; let _v = [0, ..FOO*3*2/2]; } diff --git a/src/test/run-pass/const-extern-function.rs b/src/test/run-pass/const-extern-function.rs index 6b6a3e4d0a4e8..5e7ac4e4518ae 100644 --- a/src/test/run-pass/const-extern-function.rs +++ b/src/test/run-pass/const-extern-function.rs @@ -10,8 +10,8 @@ extern fn foopy() {} -const f: *u8 = foopy; -const s: S = S { f: foopy }; +static f: *u8 = foopy; +static s: S = S { f: foopy }; struct S { f: *u8 diff --git a/src/test/run-pass/const-fields-and-indexing.rs b/src/test/run-pass/const-fields-and-indexing.rs index c13215bb23621..a3611c5eb2658 100644 --- a/src/test/run-pass/const-fields-and-indexing.rs +++ b/src/test/run-pass/const-fields-and-indexing.rs @@ -8,22 +8,21 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -const x : [int * 4] = [1,2,3,4]; -const p : int = x[2]; -const y : &'static [int] = &[1,2,3,4]; -const q : int = y[2]; +static x : [int * 4] = [1,2,3,4]; +static p : int = x[2]; +static y : &'static [int] = &[1,2,3,4]; +static q : int = y[2]; struct S {a: int, b: int} -const s : S = S {a: 10, b: 20}; -const t : int = s.b; +static s : S = S {a: 10, b: 20}; +static t : int = s.b; struct K {a: int, b: int, c: D} struct D { d: int, e: int } -const k : K = K {a: 10, b: 20, c: D {d: 30, - e: 40}}; -const m : int = k.c.e; +static k : K = K {a: 10, b: 20, c: D {d: 30, e: 40}}; +static m : int = k.c.e; pub fn main() { io::println(fmt!("%?", p)); diff --git a/src/test/run-pass/const-fn-val.rs b/src/test/run-pass/const-fn-val.rs index c3d09a58b5b7b..b3667d4f81ebe 100644 --- a/src/test/run-pass/const-fn-val.rs +++ b/src/test/run-pass/const-fn-val.rs @@ -14,7 +14,7 @@ fn foo() -> int { struct Bar { f: &'self fn() -> int } -const b : Bar/&static = Bar { f: foo }; +static b : Bar<'static> = Bar { f: foo }; pub fn main() { fail_unless!((b.f)() == 0xca7f000d); diff --git a/src/test/run-pass/const-negative.rs b/src/test/run-pass/const-negative.rs index a255082933165..e2add6409f75d 100644 --- a/src/test/run-pass/const-negative.rs +++ b/src/test/run-pass/const-negative.rs @@ -10,7 +10,7 @@ // Issue #358 -const toplevel_mod: int = -1; +static toplevel_mod: int = -1; pub fn main() { fail_unless!(toplevel_mod == -1); diff --git a/src/test/run-pass/const-nullary-enum.rs b/src/test/run-pass/const-nullary-enum.rs index cbc862185a8d8..bc61c8e9aecf5 100644 --- a/src/test/run-pass/const-nullary-enum.rs +++ b/src/test/run-pass/const-nullary-enum.rs @@ -14,7 +14,7 @@ enum Foo { Boo, } -const X: Foo = Bar; +static X: Foo = Bar; pub fn main() { match X { @@ -27,4 +27,4 @@ pub fn main() { } } -const Y: Foo = Baz; +static Y: Foo = Baz; diff --git a/src/test/run-pass/const-nullary-univariant-enum.rs b/src/test/run-pass/const-nullary-univariant-enum.rs index 184a9da6fb791..75fd2774095c1 100644 --- a/src/test/run-pass/const-nullary-univariant-enum.rs +++ b/src/test/run-pass/const-nullary-univariant-enum.rs @@ -12,11 +12,11 @@ enum Foo { Bar = 0xDEADBEE } -const X: Foo = Bar; +static X: Foo = Bar; pub fn main() { fail_unless!(((X as uint) == 0xDEADBEE)); fail_unless!(((Y as uint) == 0xDEADBEE)); } -const Y: Foo = Bar; +static Y: Foo = Bar; diff --git a/src/test/run-pass/const-rec-and-tup.rs b/src/test/run-pass/const-rec-and-tup.rs index ff1f3338e444a..77d4521e70943 100644 --- a/src/test/run-pass/const-rec-and-tup.rs +++ b/src/test/run-pass/const-rec-and-tup.rs @@ -12,11 +12,11 @@ struct Pair { a: float, b: float } struct AnotherPair { x: (i64, i64), y: Pair } -const x : (i32,i32) = (0xfeedf00dd,0xca11ab1e); -const y : AnotherPair = AnotherPair{ x: (0xf0f0f0f0_f0f0f0f0, - 0xabababab_abababab), - y: Pair { a: 3.14159265358979323846, - b: 2.7182818284590452354 }}; +static x : (i32,i32) = (0xfeedf00dd,0xca11ab1e); +static y : AnotherPair = AnotherPair{ x: (0xf0f0f0f0_f0f0f0f0, + 0xabababab_abababab), + y: Pair { a: 3.14159265358979323846, + b: 2.7182818284590452354 }}; pub fn main() { let (p, _) = y.x; diff --git a/src/test/run-pass/const-region-ptrs-noncopy.rs b/src/test/run-pass/const-region-ptrs-noncopy.rs index 078ae7661cff4..23d1d63f18996 100644 --- a/src/test/run-pass/const-region-ptrs-noncopy.rs +++ b/src/test/run-pass/const-region-ptrs-noncopy.rs @@ -10,8 +10,8 @@ type Big = [u64 * 8]; struct Pair { a: int, b: &'self Big } -const x: &'static Big = &([13, 14, 10, 13, 11, 14, 14, 15]); -const y: &'static Pair<'static> = &Pair {a: 15, b: x}; +static x: &'static Big = &([13, 14, 10, 13, 11, 14, 14, 15]); +static y: &'static Pair<'static> = &Pair {a: 15, b: x}; pub fn main() { fail_unless!(ptr::addr_of(x) == ptr::addr_of(y.b)); diff --git a/src/test/run-pass/const-region-ptrs.rs b/src/test/run-pass/const-region-ptrs.rs index dbb3abe7dafb1..32c5f65bf3ade 100644 --- a/src/test/run-pass/const-region-ptrs.rs +++ b/src/test/run-pass/const-region-ptrs.rs @@ -11,9 +11,9 @@ struct Pair { a: int, b: &'self int } -const x: &'static int = &10; +static x: &'static int = &10; -const y: &'static Pair<'static> = &Pair {a: 15, b: x}; +static y: &'static Pair<'static> = &Pair {a: 15, b: x}; pub fn main() { io::println(fmt!("x = %?", *x)); diff --git a/src/test/run-pass/const-str-ptr.rs b/src/test/run-pass/const-str-ptr.rs index a1637f6ebb831..2560431b53209 100644 --- a/src/test/run-pass/const-str-ptr.rs +++ b/src/test/run-pass/const-str-ptr.rs @@ -8,9 +8,9 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -const a: [u8 * 3] = ['h' as u8, 'i' as u8, 0 as u8]; -const c: &'static [u8 * 3] = &a; -const b: *u8 = c as *u8; +static a: [u8 * 3] = ['h' as u8, 'i' as u8, 0 as u8]; +static c: &'static [u8 * 3] = &a; +static b: *u8 = c as *u8; fn main() { let foo = &a as *u8; diff --git a/src/test/run-pass/const-struct.rs b/src/test/run-pass/const-struct.rs index b210b20458ca9..a826f7bf564cd 100644 --- a/src/test/run-pass/const-struct.rs +++ b/src/test/run-pass/const-struct.rs @@ -12,17 +12,17 @@ struct foo { a: int, b: int, c: int } impl cmp::Eq for foo { - pure fn eq(&self, other: &foo) -> bool { + fn eq(&self, other: &foo) -> bool { (*self).a == (*other).a && (*self).b == (*other).b && (*self).c == (*other).c } - pure fn ne(&self, other: &foo) -> bool { !(*self).eq(other) } + fn ne(&self, other: &foo) -> bool { !(*self).eq(other) } } -const x : foo = foo { a:1, b:2, c: 3 }; -const y : foo = foo { b:2, c:3, a: 1 }; -const z : &'static foo = &foo { a: 10, b: 22, c: 12 }; +static x : foo = foo { a:1, b:2, c: 3 }; +static y : foo = foo { b:2, c:3, a: 1 }; +static z : &'static foo = &foo { a: 10, b: 22, c: 12 }; pub fn main() { fail_unless!(x.b == 2); diff --git a/src/test/run-pass/const-tuple-struct.rs b/src/test/run-pass/const-tuple-struct.rs index 9a25a2eb1aa89..857997b29d264 100644 --- a/src/test/run-pass/const-tuple-struct.rs +++ b/src/test/run-pass/const-tuple-struct.rs @@ -10,7 +10,7 @@ struct Bar(int, int); -const X: Bar = Bar(1, 2); +static X: Bar = Bar(1, 2); pub fn main() { match X { diff --git a/src/test/run-pass/const-unit-struct.rs b/src/test/run-pass/const-unit-struct.rs index bc996314e0335..b4acde098baf3 100644 --- a/src/test/run-pass/const-unit-struct.rs +++ b/src/test/run-pass/const-unit-struct.rs @@ -10,7 +10,7 @@ struct Foo; -const X: Foo = Foo; +static X: Foo = Foo; pub fn main() { match X { diff --git a/src/test/run-pass/const-vec-of-fns.rs b/src/test/run-pass/const-vec-of-fns.rs index 5598756ac75a6..deb1a0769f73c 100644 --- a/src/test/run-pass/const-vec-of-fns.rs +++ b/src/test/run-pass/const-vec-of-fns.rs @@ -9,16 +9,16 @@ // except according to those terms. /*! - * Try to double-check that const fns have the right size (with or + * Try to double-check that static fns have the right size (with or * without dummy env ptr, as appropriate) by iterating a size-2 array. - * If the const size differs from the runtime size, the second element + * If the static size differs from the runtime size, the second element * should be read as a null or otherwise wrong pointer and crash. */ fn f() { } -const bare_fns: &'static [extern fn()] = &[f, f]; +static bare_fns: &'static [extern fn()] = &[f, f]; struct S<'self>(&'self fn()); -const closures: &'static [S<'static>] = &[S(f), S(f)]; +static closures: &'static [S<'static>] = &[S(f), S(f)]; pub fn main() { for bare_fns.each |&bare_fn| { bare_fn() } diff --git a/src/test/run-pass/const-vecs-and-slices.rs b/src/test/run-pass/const-vecs-and-slices.rs index 1e86ff3515b4f..736335464b24d 100644 --- a/src/test/run-pass/const-vecs-and-slices.rs +++ b/src/test/run-pass/const-vecs-and-slices.rs @@ -8,8 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -const x : [int * 4] = [1,2,3,4]; -const y : &'static [int] = &[1,2,3,4]; +static x : [int * 4] = [1,2,3,4]; +static y : &'static [int] = &[1,2,3,4]; pub fn main() { io::println(fmt!("%?", x[1])); diff --git a/src/test/run-pass/const.rs b/src/test/run-pass/const.rs index e935a2cd434d9..d9d84c3fd5048 100644 --- a/src/test/run-pass/const.rs +++ b/src/test/run-pass/const.rs @@ -10,6 +10,6 @@ -const i: int = 10; +static i: int = 10; pub fn main() { debug!("%i", i); } diff --git a/src/test/run-pass/consts-in-patterns.rs b/src/test/run-pass/consts-in-patterns.rs index e68414958806a..5e79838c4b7a3 100644 --- a/src/test/run-pass/consts-in-patterns.rs +++ b/src/test/run-pass/consts-in-patterns.rs @@ -8,8 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -const FOO: int = 10; -const BAR: int = 3; +static FOO: int = 10; +static BAR: int = 3; pub fn main() { let x: int = 3; diff --git a/src/test/run-pass/cross-crate-const-pat.rs b/src/test/run-pass/cross-crate-const-pat.rs new file mode 100644 index 0000000000000..0a0e2356f4443 --- /dev/null +++ b/src/test/run-pass/cross-crate-const-pat.rs @@ -0,0 +1,22 @@ +// Copyright 2013 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// xfail-fast +// aux-build:cci_const.rs + +extern mod cci_const; + +fn main() { + let x = cci_const::uint_val; + match x { + cci_const::uint_val => {} + _ => {} + } +} diff --git a/src/test/run-pass/deriving-clone-enum.rs b/src/test/run-pass/deriving-clone-enum.rs index bad83f41bac65..ee294cb594230 100644 --- a/src/test/run-pass/deriving-clone-enum.rs +++ b/src/test/run-pass/deriving-clone-enum.rs @@ -1,4 +1,4 @@ -#[deriving_clone] +#[deriving(Clone)] enum E { A, B(()), diff --git a/src/test/run-pass/deriving-clone-generic-enum.rs b/src/test/run-pass/deriving-clone-generic-enum.rs index c70e644e2a860..a868db2425cc2 100644 --- a/src/test/run-pass/deriving-clone-generic-enum.rs +++ b/src/test/run-pass/deriving-clone-generic-enum.rs @@ -1,4 +1,4 @@ -#[deriving_clone] +#[deriving(Clone)] enum E { A(T), B(T,U), diff --git a/src/test/run-pass/deriving-clone-generic-struct.rs b/src/test/run-pass/deriving-clone-generic-struct.rs index 73fb3ad8d6477..92721c5343573 100644 --- a/src/test/run-pass/deriving-clone-generic-struct.rs +++ b/src/test/run-pass/deriving-clone-generic-struct.rs @@ -1,4 +1,4 @@ -#[deriving_clone] +#[deriving(Clone)] struct S { foo: (), bar: (), diff --git a/src/test/run-pass/deriving-clone-generic-tuple-struct.rs b/src/test/run-pass/deriving-clone-generic-tuple-struct.rs index d7b15d63280d0..aeaa9ed726d2b 100644 --- a/src/test/run-pass/deriving-clone-generic-tuple-struct.rs +++ b/src/test/run-pass/deriving-clone-generic-tuple-struct.rs @@ -1,4 +1,4 @@ -#[deriving_clone] +#[deriving(Clone)] struct S(T, ()); fn main() {} diff --git a/src/test/run-pass/deriving-clone-struct.rs b/src/test/run-pass/deriving-clone-struct.rs index 07830e7ee096b..4dcbadbb3ef92 100644 --- a/src/test/run-pass/deriving-clone-struct.rs +++ b/src/test/run-pass/deriving-clone-struct.rs @@ -1,4 +1,4 @@ -#[deriving_clone] +#[deriving(Clone)] struct S { _int: int, _i8: i8, diff --git a/src/test/run-pass/deriving-clone-tuple-struct.rs b/src/test/run-pass/deriving-clone-tuple-struct.rs index a1a79613d401f..04ddb439485fd 100644 --- a/src/test/run-pass/deriving-clone-tuple-struct.rs +++ b/src/test/run-pass/deriving-clone-tuple-struct.rs @@ -1,4 +1,4 @@ -#[deriving_clone] +#[deriving(Clone)] struct S((), ()); fn main() {} diff --git a/src/test/run-pass/deriving-enum-single-variant.rs b/src/test/run-pass/deriving-enum-single-variant.rs index 7b86a6299f6f7..ebbdc157c7d13 100644 --- a/src/test/run-pass/deriving-enum-single-variant.rs +++ b/src/test/run-pass/deriving-enum-single-variant.rs @@ -1,6 +1,6 @@ type task_id = int; -#[deriving_eq] +#[deriving(Eq)] pub enum Task { TaskHandle(task_id) } diff --git a/src/test/run-pass/deriving-via-extension-c-enum.rs b/src/test/run-pass/deriving-via-extension-c-enum.rs index 9431e6b8343ca..47d088cfc6f26 100644 --- a/src/test/run-pass/deriving-via-extension-c-enum.rs +++ b/src/test/run-pass/deriving-via-extension-c-enum.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#[deriving_eq] +#[deriving(Eq)] enum Foo { Bar, Baz, diff --git a/src/test/run-pass/deriving-via-extension-enum.rs b/src/test/run-pass/deriving-via-extension-enum.rs index 35575285e7a7d..32f693abf2555 100644 --- a/src/test/run-pass/deriving-via-extension-enum.rs +++ b/src/test/run-pass/deriving-via-extension-enum.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#[deriving_eq] +#[deriving(Eq)] enum Foo { Bar(int, int), Baz(float, float) diff --git a/src/test/run-pass/deriving-via-extension-iter-bytes-enum.rs b/src/test/run-pass/deriving-via-extension-iter-bytes-enum.rs index b41d41192fedb..5ceb8c48750d9 100644 --- a/src/test/run-pass/deriving-via-extension-iter-bytes-enum.rs +++ b/src/test/run-pass/deriving-via-extension-iter-bytes-enum.rs @@ -10,13 +10,13 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#[deriving_iter_bytes] +#[deriving(IterBytes)] enum Foo { Bar(int, char), Baz(char, int) } -#[deriving_iter_bytes] +#[deriving(IterBytes)] enum A { B, C, diff --git a/src/test/run-pass/deriving-via-extension-iter-bytes-struct.rs b/src/test/run-pass/deriving-via-extension-iter-bytes-struct.rs index 18336d74c7e19..9f18cb6ac58a7 100644 --- a/src/test/run-pass/deriving-via-extension-iter-bytes-struct.rs +++ b/src/test/run-pass/deriving-via-extension-iter-bytes-struct.rs @@ -10,7 +10,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#[deriving_iter_bytes] +#[deriving(IterBytes)] struct Foo { x: int, y: int, diff --git a/src/test/run-pass/deriving-via-extension-struct-empty.rs b/src/test/run-pass/deriving-via-extension-struct-empty.rs index 4c8c81d5312f9..09ee83870a0e2 100644 --- a/src/test/run-pass/deriving-via-extension-struct-empty.rs +++ b/src/test/run-pass/deriving-via-extension-struct-empty.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#[deriving_eq] +#[deriving(Eq)] struct Foo; pub fn main() { diff --git a/src/test/run-pass/deriving-via-extension-struct-like-enum-variant.rs b/src/test/run-pass/deriving-via-extension-struct-like-enum-variant.rs index 0f44f7b7cf980..c349600eb9998 100644 --- a/src/test/run-pass/deriving-via-extension-struct-like-enum-variant.rs +++ b/src/test/run-pass/deriving-via-extension-struct-like-enum-variant.rs @@ -1,4 +1,4 @@ -#[deriving_eq] +#[deriving(Eq)] enum S { X { x: int, y: int }, Y diff --git a/src/test/run-pass/deriving-via-extension-struct-tuple.rs b/src/test/run-pass/deriving-via-extension-struct-tuple.rs index ab68d50249100..35c20c13e9371 100644 --- a/src/test/run-pass/deriving-via-extension-struct-tuple.rs +++ b/src/test/run-pass/deriving-via-extension-struct-tuple.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#[deriving_eq] +#[deriving(Eq)] struct Foo(int, int, ~str); pub fn main() { diff --git a/src/test/run-pass/deriving-via-extension-struct.rs b/src/test/run-pass/deriving-via-extension-struct.rs index f1d50e4e824ea..f5cc85c638250 100644 --- a/src/test/run-pass/deriving-via-extension-struct.rs +++ b/src/test/run-pass/deriving-via-extension-struct.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#[deriving_eq] +#[deriving(Eq)] struct Foo { x: int, y: int, diff --git a/src/test/run-pass/deriving-via-extension-type-params.rs b/src/test/run-pass/deriving-via-extension-type-params.rs index 07c09dc7fd4f6..298e30f7ec1e7 100644 --- a/src/test/run-pass/deriving-via-extension-type-params.rs +++ b/src/test/run-pass/deriving-via-extension-type-params.rs @@ -10,8 +10,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#[deriving_eq] -#[deriving_iter_bytes] +#[deriving(Eq)] +#[deriving(IterBytes)] struct Foo { x: int, y: T, diff --git a/src/test/run-pass/do-pure.rs b/src/test/run-pass/do-pure.rs index 41686cf5b3736..08056f59acd3f 100644 --- a/src/test/run-pass/do-pure.rs +++ b/src/test/run-pass/do-pure.rs @@ -8,10 +8,10 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -pure fn f(f: &fn()) { +fn f(f: &fn()) { } -pure fn g() { +fn g() { // `f || { }` is considered pure, so `do f { }` should be too do f { } } diff --git a/src/test/run-pass/drop-trait-generic.rs b/src/test/run-pass/drop-trait-generic.rs index 270137c2fd292..21b85084117c4 100644 --- a/src/test/run-pass/drop-trait-generic.rs +++ b/src/test/run-pass/drop-trait-generic.rs @@ -12,6 +12,7 @@ struct S { x: T } +#[unsafe_destructor] impl ::core::ops::Drop for S { fn finalize(&self) { io::println("bye"); diff --git a/src/test/run-pass/empty-tag.rs b/src/test/run-pass/empty-tag.rs index ca81489e0bdb7..0589ffc79e054 100644 --- a/src/test/run-pass/empty-tag.rs +++ b/src/test/run-pass/empty-tag.rs @@ -11,10 +11,10 @@ enum chan { chan_t, } impl cmp::Eq for chan { - pure fn eq(&self, other: &chan) -> bool { + fn eq(&self, other: &chan) -> bool { ((*self) as uint) == ((*other) as uint) } - pure fn ne(&self, other: &chan) -> bool { !(*self).eq(other) } + fn ne(&self, other: &chan) -> bool { !(*self).eq(other) } } fn wrapper3(i: chan) { diff --git a/src/test/run-pass/explicit-self-generic.rs b/src/test/run-pass/explicit-self-generic.rs index 16c4986fc5345..e22e739f570ff 100644 --- a/src/test/run-pass/explicit-self-generic.rs +++ b/src/test/run-pass/explicit-self-generic.rs @@ -15,8 +15,8 @@ extern mod std; * * The hash should concentrate entropy in the lower bits. */ -type HashFn = ~pure fn(K) -> uint; -type EqFn = ~pure fn(K, K) -> bool; +type HashFn = ~fn(K) -> uint; +type EqFn = ~fn(K, K) -> bool; struct LM { resize_at: uint, size: uint } diff --git a/src/test/run-pass/explicit-self.rs b/src/test/run-pass/explicit-self.rs index 1a21fa0a5d759..3e48b8f05baee 100644 --- a/src/test/run-pass/explicit-self.rs +++ b/src/test/run-pass/explicit-self.rs @@ -9,7 +9,7 @@ // except according to those terms. -const tau: float = 2.0*3.14159265358979323; +static tau: float = 2.0*3.14159265358979323; struct Point {x: float, y: float} struct Size {w: float, h: float} diff --git a/src/test/run-pass/export-glob-imports-target.rs b/src/test/run-pass/export-glob-imports-target.rs index ae17d6ca8b3d5..6b97c9031f0a9 100644 --- a/src/test/run-pass/export-glob-imports-target.rs +++ b/src/test/run-pass/export-glob-imports-target.rs @@ -18,7 +18,7 @@ mod foo { use foo::bar::*; pub mod bar { - pub const a : int = 10; + pub static a : int = 10; } pub fn zum() { let b = a; diff --git a/src/test/run-pass/export-unexported-dep.rs b/src/test/run-pass/export-unexported-dep.rs index 36483f883777d..4634cc4ef1101 100644 --- a/src/test/run-pass/export-unexported-dep.rs +++ b/src/test/run-pass/export-unexported-dep.rs @@ -16,10 +16,10 @@ mod foo { enum t { t1, t2, } impl cmp::Eq for t { - pure fn eq(&self, other: &t) -> bool { + fn eq(&self, other: &t) -> bool { ((*self) as uint) == ((*other) as uint) } - pure fn ne(&self, other: &t) -> bool { !(*self).eq(other) } + fn ne(&self, other: &t) -> bool { !(*self).eq(other) } } pub fn f() -> t { return t1; } diff --git a/src/test/run-pass/expr-alt-struct.rs b/src/test/run-pass/expr-alt-struct.rs index 564fb1a912cfc..03358f2511bb6 100644 --- a/src/test/run-pass/expr-alt-struct.rs +++ b/src/test/run-pass/expr-alt-struct.rs @@ -24,10 +24,10 @@ fn test_rec() { enum mood { happy, sad, } impl cmp::Eq for mood { - pure fn eq(&self, other: &mood) -> bool { + fn eq(&self, other: &mood) -> bool { ((*self) as uint) == ((*other) as uint) } - pure fn ne(&self, other: &mood) -> bool { !(*self).eq(other) } + fn ne(&self, other: &mood) -> bool { !(*self).eq(other) } } fn test_tag() { diff --git a/src/test/run-pass/expr-if-struct.rs b/src/test/run-pass/expr-if-struct.rs index d37a67d922e61..1421234783575 100644 --- a/src/test/run-pass/expr-if-struct.rs +++ b/src/test/run-pass/expr-if-struct.rs @@ -25,10 +25,10 @@ fn test_rec() { enum mood { happy, sad, } impl cmp::Eq for mood { - pure fn eq(&self, other: &mood) -> bool { + fn eq(&self, other: &mood) -> bool { ((*self) as uint) == ((*other) as uint) } - pure fn ne(&self, other: &mood) -> bool { !(*self).eq(other) } + fn ne(&self, other: &mood) -> bool { !(*self).eq(other) } } fn test_tag() { diff --git a/src/test/run-pass/extern-pass-TwoU64s-ref.rs b/src/test/run-pass/extern-pass-TwoU64s-ref.rs index 00754afa703b2..f04e9d086e94f 100644 --- a/src/test/run-pass/extern-pass-TwoU64s-ref.rs +++ b/src/test/run-pass/extern-pass-TwoU64s-ref.rs @@ -12,7 +12,7 @@ // xfail-test --- broken on 32-bit ABIs! (#5347) -#[deriving_eq] +#[deriving(Eq)] struct TwoU64s { one: u64, two: u64 } diff --git a/src/test/run-pass/extern-pass-TwoU64s.rs b/src/test/run-pass/extern-pass-TwoU64s.rs index 2baf383ce545f..1937ddaa9f42a 100644 --- a/src/test/run-pass/extern-pass-TwoU64s.rs +++ b/src/test/run-pass/extern-pass-TwoU64s.rs @@ -13,7 +13,7 @@ // xfail-test --- broken on 32-bit ABIs! (#5347) -#[deriving_eq] +#[deriving(Eq)] struct TwoU64s { one: u64, two: u64 } diff --git a/src/test/run-pass/fixed-point-bind-unique.rs b/src/test/run-pass/fixed-point-bind-unique.rs index fcd3b2e0a18bc..d79cd36d8fc07 100644 --- a/src/test/run-pass/fixed-point-bind-unique.rs +++ b/src/test/run-pass/fixed-point-bind-unique.rs @@ -10,11 +10,11 @@ // xfail-fast -fn fix_help(f: extern fn(@fn(A) -> B, A) -> B, x: A) -> B { +fn fix_help(f: extern fn(@fn(A) -> B, A) -> B, x: A) -> B { return f(|a| fix_help(f, a), x); } -fn fix(f: extern fn(@fn(A) -> B, A) -> B) -> @fn(A) -> B { +fn fix(f: extern fn(@fn(A) -> B, A) -> B) -> @fn(A) -> B { return |a| fix_help(f, a); } diff --git a/src/test/run-pass/foreign-mod-unused-const.rs b/src/test/run-pass/foreign-mod-unused-const.rs index f66ffbd0e0e65..430da7a3f608b 100644 --- a/src/test/run-pass/foreign-mod-unused-const.rs +++ b/src/test/run-pass/foreign-mod-unused-const.rs @@ -11,7 +11,7 @@ mod foo { #[nolink] pub extern { - pub const errno: int; + pub static errno: int; } } diff --git a/src/test/run-pass/if-check.rs b/src/test/run-pass/if-check.rs index 3ee0808fa95a4..5c72de87ccbef 100644 --- a/src/test/run-pass/if-check.rs +++ b/src/test/run-pass/if-check.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -pure fn even(x: uint) -> bool { +fn even(x: uint) -> bool { if x < 2u { return false; } else if x == 2u { return true; } else { return even(x - 2u); } diff --git a/src/test/run-pass/init-res-into-things.rs b/src/test/run-pass/init-res-into-things.rs index 50b31361ceed8..5db8e34c7b5ca 100644 --- a/src/test/run-pass/init-res-into-things.rs +++ b/src/test/run-pass/init-res-into-things.rs @@ -17,9 +17,12 @@ struct r { struct Box { x: r } +#[unsafe_destructor] impl Drop for r { fn finalize(&self) { - *(self.i) = *(self.i) + 1; + unsafe { + *(self.i) = *(self.i) + 1; + } } } diff --git a/src/test/run-pass/issue-1660.rs b/src/test/run-pass/issue-1660.rs index da8dfbf679224..5c8b4be0cee1a 100644 --- a/src/test/run-pass/issue-1660.rs +++ b/src/test/run-pass/issue-1660.rs @@ -9,5 +9,5 @@ // except according to those terms. pub fn main() { - const _x: int = 1<<2; + static _x: int = 1<<2; } diff --git a/src/test/run-pass/issue-2190-1.rs b/src/test/run-pass/issue-2190-1.rs index c769c33390fa5..f3a81771c2137 100644 --- a/src/test/run-pass/issue-2190-1.rs +++ b/src/test/run-pass/issue-2190-1.rs @@ -9,7 +9,7 @@ // except according to those terms. // xfail-test -const generations: uint = 1024+256+128+49; +static generations: uint = 1024+256+128+49; fn child_no(x: uint) -> ~fn() { || { diff --git a/src/test/run-pass/issue-2428.rs b/src/test/run-pass/issue-2428.rs index 766bc23173c60..a571c49c438b7 100644 --- a/src/test/run-pass/issue-2428.rs +++ b/src/test/run-pass/issue-2428.rs @@ -10,7 +10,7 @@ pub fn main() { let foo = 100; - const quux: int = 5; + static quux: int = 5; enum Stuff { Bar = quux diff --git a/src/test/run-pass/issue-2502.rs b/src/test/run-pass/issue-2502.rs index cfae757aee82e..6dd8e3d83de87 100644 --- a/src/test/run-pass/issue-2502.rs +++ b/src/test/run-pass/issue-2502.rs @@ -12,13 +12,13 @@ struct font { fontbuf: &'self ~[u8], } -pub impl font/&self { +pub impl<'self> font<'self> { fn buf(&self) -> &'self ~[u8] { self.fontbuf } } -fn font(fontbuf: &'r ~[u8]) -> font/&r { +fn font(fontbuf: &'r ~[u8]) -> font<'r> { font { fontbuf: fontbuf } diff --git a/src/test/run-pass/issue-2718.rs b/src/test/run-pass/issue-2718.rs index ae927ff791810..cc4f10ca347b4 100644 --- a/src/test/run-pass/issue-2718.rs +++ b/src/test/run-pass/issue-2718.rs @@ -20,7 +20,7 @@ pub mod pipes { payload: Option } - #[deriving_eq] + #[deriving(Eq)] pub enum state { empty, full, @@ -155,6 +155,7 @@ pub mod pipes { p: Option<*packet>, } + #[unsafe_destructor] impl Drop for send_packet { fn finalize(&self) { unsafe { @@ -187,6 +188,7 @@ pub mod pipes { p: Option<*packet>, } + #[unsafe_destructor] impl Drop for recv_packet { fn finalize(&self) { unsafe { diff --git a/src/test/run-pass/issue-2734.rs b/src/test/run-pass/issue-2734.rs index 35c3d6a88ee33..7125e89287cbd 100644 --- a/src/test/run-pass/issue-2734.rs +++ b/src/test/run-pass/issue-2734.rs @@ -11,7 +11,7 @@ trait hax { } impl hax for A { } -fn perform_hax(x: @T) -> @hax { +fn perform_hax(x: @T) -> @hax { @x as @hax } diff --git a/src/test/run-pass/issue-2735-2.rs b/src/test/run-pass/issue-2735-2.rs index 4c8559f0552d6..3f13b9f9e67ad 100644 --- a/src/test/run-pass/issue-2735-2.rs +++ b/src/test/run-pass/issue-2735-2.rs @@ -13,13 +13,16 @@ struct defer { b: &'self mut bool, } -impl Drop for defer/&self { +#[unsafe_destructor] +impl<'self> Drop for defer<'self> { fn finalize(&self) { - *(self.b) = true; + unsafe { + *(self.b) = true; + } } } -fn defer(b: &'r mut bool) -> defer/&r { +fn defer<'r>(b: &'r mut bool) -> defer<'r> { defer { b: b } diff --git a/src/test/run-pass/issue-2735-3.rs b/src/test/run-pass/issue-2735-3.rs index 9fa1d56406a93..40c71eec4d38a 100644 --- a/src/test/run-pass/issue-2735-3.rs +++ b/src/test/run-pass/issue-2735-3.rs @@ -13,13 +13,16 @@ struct defer { b: &'self mut bool, } -impl Drop for defer/&self { +#[unsafe_destructor] +impl<'self> Drop for defer<'self> { fn finalize(&self) { - *(self.b) = true; + unsafe { + *(self.b) = true; + } } } -fn defer(b: &'r mut bool) -> defer/&r { +fn defer(b: &'r mut bool) -> defer<'r> { defer { b: b } diff --git a/src/test/run-pass/issue-2735.rs b/src/test/run-pass/issue-2735.rs index ef6363043eed4..9a5a366c74473 100644 --- a/src/test/run-pass/issue-2735.rs +++ b/src/test/run-pass/issue-2735.rs @@ -11,7 +11,7 @@ trait hax { } impl hax for A { } -fn perform_hax(x: @T) -> @hax { +fn perform_hax(x: @T) -> @hax { @x as @hax } diff --git a/src/test/run-pass/issue-2748-a.rs b/src/test/run-pass/issue-2748-a.rs index f36b364aadda4..8a0f64b32d497 100644 --- a/src/test/run-pass/issue-2748-a.rs +++ b/src/test/run-pass/issue-2748-a.rs @@ -12,7 +12,7 @@ struct CMap { buf: &'self [u8], } -fn CMap(buf: &'r [u8]) -> CMap/&r { +fn CMap<'r>(buf: &'r [u8]) -> CMap<'r> { CMap { buf: buf } diff --git a/src/test/run-pass/issue-2904.rs b/src/test/run-pass/issue-2904.rs index 9538ebc554ccf..8a7e2b8a9a9bf 100644 --- a/src/test/run-pass/issue-2904.rs +++ b/src/test/run-pass/issue-2904.rs @@ -28,7 +28,7 @@ enum square { } impl to_str::ToStr for square { - pure fn to_str(&self) -> ~str { + fn to_str(&self) -> ~str { match *self { bot => { ~"R" } wall => { ~"#" } @@ -59,7 +59,7 @@ fn square_from_char(c: char) -> square { } } -fn read_board_grid(+in: rdr) -> ~[~[square]] { +fn read_board_grid(+in: rdr) -> ~[~[square]] { let in = @in as @io::Reader; let mut grid = ~[]; for in.each_line |line| { diff --git a/src/test/run-pass/issue-3149.rs b/src/test/run-pass/issue-3149.rs index df102f93c2bb7..e433141c44dbd 100644 --- a/src/test/run-pass/issue-3149.rs +++ b/src/test/run-pass/issue-3149.rs @@ -8,11 +8,11 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -pure fn Matrix4(m11: T, m12: T, m13: T, m14: T, - m21: T, m22: T, m23: T, m24: T, - m31: T, m32: T, m33: T, m34: T, - m41: T, m42: T, m43: T, m44: T) - -> Matrix4 { +fn Matrix4(m11: T, m12: T, m13: T, m14: T, + m21: T, m22: T, m23: T, m24: T, + m31: T, m32: T, m33: T, m34: T, + m41: T, m42: T, m43: T, m44: T) + -> Matrix4 { Matrix4 { m11: m11, m12: m12, m13: m13, m14: m14, diff --git a/src/test/run-pass/issue-3480.rs b/src/test/run-pass/issue-3480.rs index e813cde7c2760..aaff822398d6f 100644 --- a/src/test/run-pass/issue-3480.rs +++ b/src/test/run-pass/issue-3480.rs @@ -13,13 +13,12 @@ type IMap = ~[(K, V)]; trait ImmutableMap { - pure fn contains_key(key: K) -> bool; + fn contains_key(key: K) -> bool; } impl IMap : ImmutableMap { - pure fn contains_key(key: K) -> bool - { + fn contains_key(key: K) -> bool { vec::find(self, |e| {e.first() == key}).is_some() } } diff --git a/src/test/run-pass/issue-3563-3.rs b/src/test/run-pass/issue-3563-3.rs index ad6cae0bff9b2..fdbd7ec304edd 100644 --- a/src/test/run-pass/issue-3563-3.rs +++ b/src/test/run-pass/issue-3563-3.rs @@ -111,8 +111,7 @@ impl AsciiArt // Allows AsciiArt to be converted to a string using the libcore ToStr trait. // Note that the %s fmt! specifier will not call this automatically. impl ToStr for AsciiArt { - pure fn to_str(&self) -> ~str - { + fn to_str(&self) -> ~str { // Convert each line into a string. let lines = do self.lines.map |line| {str::from_chars(*line)}; diff --git a/src/test/run-pass/issue-3874.rs b/src/test/run-pass/issue-3874.rs index 8d62da9efad42..f54d2f9fafc4e 100644 --- a/src/test/run-pass/issue-3874.rs +++ b/src/test/run-pass/issue-3874.rs @@ -11,7 +11,7 @@ // xfail-test enum PureCounter { PureCounter(uint) } -pure fn each(self: PureCounter, blk: &fn(v: &uint)) { +fn each(self: PureCounter, blk: &fn(v: &uint)) { let PureCounter(ref x) = self; blk(x); } diff --git a/src/test/run-pass/issue-3935.rs b/src/test/run-pass/issue-3935.rs index e0832bc74b2f3..626932850cf42 100644 --- a/src/test/run-pass/issue-3935.rs +++ b/src/test/run-pass/issue-3935.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#[deriving_eq] +#[deriving(Eq)] struct Bike { name: ~str, } diff --git a/src/test/run-pass/issue-4120.rs b/src/test/run-pass/issue-4120.rs new file mode 100644 index 0000000000000..82bd48c4aa084 --- /dev/null +++ b/src/test/run-pass/issue-4120.rs @@ -0,0 +1,21 @@ +// xfail-test + +// XFAIL'd due to Valgrind complaining about TLS loss. + +// Copyright 2013 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +fn main() +{ + unsafe { + libc::exit(0); + } + error!("ack"); +} diff --git a/src/test/run-pass/issue-979.rs b/src/test/run-pass/issue-979.rs index d46f62c6ae0df..d5184efa4c3db 100644 --- a/src/test/run-pass/issue-979.rs +++ b/src/test/run-pass/issue-979.rs @@ -12,9 +12,12 @@ struct r { b: @mut int, } +#[unsafe_destructor] impl Drop for r { fn finalize(&self) { - *(self.b) += 1; + unsafe { + *(self.b) += 1; + } } } diff --git a/src/test/run-pass/item-attributes.rs b/src/test/run-pass/item-attributes.rs index 5de3e88acc0e4..24fe671337287 100644 --- a/src/test/run-pass/item-attributes.rs +++ b/src/test/run-pass/item-attributes.rs @@ -29,7 +29,7 @@ mod test_first_item_in_file_mod {} mod test_single_attr_outer { #[attr = "val"] - pub const x: int = 10; + pub static x: int = 10; #[attr = "val"] pub fn f() { } @@ -47,7 +47,7 @@ mod test_single_attr_outer { mod test_multi_attr_outer { #[attr1 = "val"] #[attr2 = "val"] - pub const x: int = 10; + pub static x: int = 10; #[attr1 = "val"] #[attr2 = "val"] @@ -72,7 +72,7 @@ mod test_multi_attr_outer { mod test_stmt_single_attr_outer { pub fn f() { #[attr = "val"] - const x: int = 10; + static x: int = 10; #[attr = "val"] fn f() { } @@ -95,7 +95,7 @@ mod test_stmt_multi_attr_outer { #[attr1 = "val"] #[attr2 = "val"] - const x: int = 10; + static x: int = 10; #[attr1 = "val"] #[attr2 = "val"] diff --git a/src/test/run-pass/mod-merge-hack-inst.rs b/src/test/run-pass/mod-merge-hack-inst.rs index e8cf244c6b18c..999c6ac2a71d5 100644 --- a/src/test/run-pass/mod-merge-hack-inst.rs +++ b/src/test/run-pass/mod-merge-hack-inst.rs @@ -12,5 +12,5 @@ mod inst { pub type T = i32; - pub const bits: uint = 32; + pub static bits: uint = 32; } diff --git a/src/test/run-pass/mod-merge-hack-template.rs b/src/test/run-pass/mod-merge-hack-template.rs index 94edb596b5f73..7f7dd33dc099f 100644 --- a/src/test/run-pass/mod-merge-hack-template.rs +++ b/src/test/run-pass/mod-merge-hack-template.rs @@ -12,5 +12,5 @@ use T = self::inst::T; -pub const bits: uint = inst::bits; -pub pure fn min(x: T, y: T) -> T { if x < y { x } else { y } } +pub static bits: uint = inst::bits; +pub fn min(x: T, y: T) -> T { if x < y { x } else { y } } diff --git a/src/test/run-pass/new-impl-syntax.rs b/src/test/run-pass/new-impl-syntax.rs index aad7ded42d3d0..12b41fc91485e 100644 --- a/src/test/run-pass/new-impl-syntax.rs +++ b/src/test/run-pass/new-impl-syntax.rs @@ -4,7 +4,7 @@ struct Thingy { } impl ToStr for Thingy { - pure fn to_str(&self) -> ~str { + fn to_str(&self) -> ~str { fmt!("{ x: %d, y: %d }", self.x, self.y) } } @@ -14,7 +14,7 @@ struct PolymorphicThingy { } impl ToStr for PolymorphicThingy { - pure fn to_str(&self) -> ~str { + fn to_str(&self) -> ~str { self.x.to_str() } } diff --git a/src/test/run-pass/non-boolean-pure-fns.rs b/src/test/run-pass/non-boolean-pure-fns.rs index 83273a7aae6fc..ae241e458fc15 100644 --- a/src/test/run-pass/non-boolean-pure-fns.rs +++ b/src/test/run-pass/non-boolean-pure-fns.rs @@ -14,13 +14,13 @@ extern mod std; use std::list::*; -pure fn pure_length_go(ls: @List, acc: uint) -> uint { +fn pure_length_go(ls: @List, acc: uint) -> uint { match *ls { Nil => { acc } Cons(_, tl) => { pure_length_go(tl, acc + 1u) } } } -pure fn pure_length(ls: @List) -> uint { pure_length_go(ls, 0u) } +fn pure_length(ls: @List) -> uint { pure_length_go(ls, 0u) } -pure fn nonempty_list(ls: @List) -> bool { pure_length(ls) > 0u } +fn nonempty_list(ls: @List) -> bool { pure_length(ls) > 0u } fn safe_head(ls: @List) -> T { fail_unless!(!is_empty(ls)); diff --git a/src/test/run-pass/operator-overloading.rs b/src/test/run-pass/operator-overloading.rs index 3873cdf615b88..9299e3e365e33 100644 --- a/src/test/run-pass/operator-overloading.rs +++ b/src/test/run-pass/operator-overloading.rs @@ -16,40 +16,40 @@ struct Point { } impl ops::Add for Point { - pure fn add(&self, other: &Point) -> Point { + fn add(&self, other: &Point) -> Point { Point {x: self.x + (*other).x, y: self.y + (*other).y} } } impl ops::Sub for Point { - pure fn sub(&self, other: &Point) -> Point { + fn sub(&self, other: &Point) -> Point { Point {x: self.x - (*other).x, y: self.y - (*other).y} } } impl ops::Neg for Point { - pure fn neg(&self) -> Point { + fn neg(&self) -> Point { Point {x: -self.x, y: -self.y} } } impl ops::Not for Point { - pure fn not(&self) -> Point { + fn not(&self) -> Point { Point {x: !self.x, y: !self.y } } } impl ops::Index for Point { - pure fn index(&self, +x: bool) -> int { + fn index(&self, +x: bool) -> int { if x { self.x } else { self.y } } } impl cmp::Eq for Point { - pure fn eq(&self, other: &Point) -> bool { + fn eq(&self, other: &Point) -> bool { (*self).x == (*other).x && (*self).y == (*other).y } - pure fn ne(&self, other: &Point) -> bool { !(*self).eq(other) } + fn ne(&self, other: &Point) -> bool { !(*self).eq(other) } } pub fn main() { diff --git a/src/test/run-pass/option-unwrap.rs b/src/test/run-pass/option-unwrap.rs index d2e5911111db7..207428c2cec78 100644 --- a/src/test/run-pass/option-unwrap.rs +++ b/src/test/run-pass/option-unwrap.rs @@ -13,10 +13,13 @@ struct dtor { } +#[unsafe_destructor] impl Drop for dtor { fn finalize(&self) { // abuse access to shared mutable state to write this code - *self.x -= 1; + unsafe { + *self.x -= 1; + } } } diff --git a/src/test/run-pass/pred-not-bool.rs b/src/test/run-pass/pred-not-bool.rs index 4b90b99cb31b5..127b845ad4ce4 100644 --- a/src/test/run-pass/pred-not-bool.rs +++ b/src/test/run-pass/pred-not-bool.rs @@ -11,6 +11,6 @@ // this checks that a pred with a non-bool return // type is rejected, even if the pred is never used -pure fn bad(a: int) -> int { return 37; } //~ ERROR Non-boolean return type +fn bad(a: int) -> int { return 37; } //~ ERROR Non-boolean return type pub fn main() { } diff --git a/src/test/run-pass/pure-fmt.rs b/src/test/run-pass/pure-fmt.rs index b65c33939c878..424a5e4e8efa6 100644 --- a/src/test/run-pass/pure-fmt.rs +++ b/src/test/run-pass/pure-fmt.rs @@ -13,7 +13,7 @@ struct Big { b: @~str, c: uint, d: int, e: char, f: float, g: bool } -pure fn foo() { +fn foo() { let a = Big { b: @~"hi", c: 0, diff --git a/src/test/run-pass/pure-sum.rs b/src/test/run-pass/pure-sum.rs index cac6b4ef34932..6327a3f238d41 100644 --- a/src/test/run-pass/pure-sum.rs +++ b/src/test/run-pass/pure-sum.rs @@ -8,9 +8,9 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// Check that pure functions can modify local state. +// Check that functions can modify local state. -pure fn sums_to(v: ~[int], sum: int) -> bool { +fn sums_to(v: ~[int], sum: int) -> bool { let mut i = 0u, sum0 = 0; while i < v.len() { sum0 += v[i]; @@ -19,7 +19,7 @@ pure fn sums_to(v: ~[int], sum: int) -> bool { return sum0 == sum; } -pure fn sums_to_using_uniq(v: ~[int], sum: int) -> bool { +fn sums_to_using_uniq(v: ~[int], sum: int) -> bool { let mut i = 0u, sum0 = ~0; while i < v.len() { *sum0 += v[i]; @@ -28,7 +28,7 @@ pure fn sums_to_using_uniq(v: ~[int], sum: int) -> bool { return *sum0 == sum; } -pure fn sums_to_using_rec(v: ~[int], sum: int) -> bool { +fn sums_to_using_rec(v: ~[int], sum: int) -> bool { let mut i = 0u, sum0 = F {f: 0}; while i < v.len() { sum0.f += v[i]; @@ -39,7 +39,7 @@ pure fn sums_to_using_rec(v: ~[int], sum: int) -> bool { struct F { f: T } -pure fn sums_to_using_uniq_rec(v: ~[int], sum: int) -> bool { +fn sums_to_using_uniq_rec(v: ~[int], sum: int) -> bool { let mut i = 0u, sum0 = F {f: ~0}; while i < v.len() { *sum0.f += v[i]; diff --git a/src/test/run-pass/purity-infer.rs b/src/test/run-pass/purity-infer.rs index ce9b3b78a9cda..debde77b21128 100644 --- a/src/test/run-pass/purity-infer.rs +++ b/src/test/run-pass/purity-infer.rs @@ -9,7 +9,7 @@ // except according to those terms. -fn something(f: &pure fn()) { f(); } +fn something(f: &fn()) { f(); } pub fn main() { something(|| error!("hi!") ); } diff --git a/src/test/run-pass/regions-copy-closure.rs b/src/test/run-pass/regions-copy-closure.rs index 6bd42769cec0a..0fc8cb49f0777 100644 --- a/src/test/run-pass/regions-copy-closure.rs +++ b/src/test/run-pass/regions-copy-closure.rs @@ -12,7 +12,7 @@ struct closure_box { cl: &'self fn(), } -fn box_it(+x: &'r fn()) -> closure_box/&r { +fn box_it<'r>(+x: &'r fn()) -> closure_box<'r> { closure_box {cl: x} } diff --git a/src/test/run-pass/regions-infer-contravariance.rs b/src/test/run-pass/regions-infer-contravariance.rs index 7d966b06e3532..ef2be398b64d1 100644 --- a/src/test/run-pass/regions-infer-contravariance.rs +++ b/src/test/run-pass/regions-infer-contravariance.rs @@ -20,7 +20,7 @@ fn with(bi: &'r boxed_int) { // Here, the upcast is allowed because the `boxed_int` type is // contravariant with respect to `&r`. See also // compile-fail/regions-infer-invariance-due-to-mutability.rs - let bi: &'blk boxed_int/&blk = bi; + let bi: &'blk boxed_int<'blk> = bi; fail_unless!(*get(bi) == 22); } diff --git a/src/test/run-pass/regions-mock-trans.rs b/src/test/run-pass/regions-mock-trans.rs index b249a4470cb9e..717588ab4cb9d 100644 --- a/src/test/run-pass/regions-mock-trans.rs +++ b/src/test/run-pass/regions-mock-trans.rs @@ -26,7 +26,7 @@ struct Ccx { fn alloc(_bcx : &'a arena) -> &'a Bcx<'a> { unsafe { return cast::reinterpret_cast( - &libc::malloc(sys::size_of::() as libc::size_t)); + &libc::malloc(sys::size_of::>() as libc::size_t)); } } diff --git a/src/test/run-pass/regions-static-closure.rs b/src/test/run-pass/regions-static-closure.rs index 0351f031e0937..5673a1e50f070 100644 --- a/src/test/run-pass/regions-static-closure.rs +++ b/src/test/run-pass/regions-static-closure.rs @@ -16,7 +16,7 @@ fn box_it(+x: &'r fn()) -> closure_box<'r> { closure_box {cl: x} } -fn call_static_closure(cl: closure_box/&static) { +fn call_static_closure(cl: closure_box<'static>) { (cl.cl)(); } diff --git a/src/test/run-pass/repeated-vector-syntax.rs b/src/test/run-pass/repeated-vector-syntax.rs index 49d0c49b3967e..a22384a6b53d0 100644 --- a/src/test/run-pass/repeated-vector-syntax.rs +++ b/src/test/run-pass/repeated-vector-syntax.rs @@ -9,8 +9,15 @@ // except according to those terms. pub fn main() { + struct Foo { a: ~str } + + let v = [ ~Foo { a: ~"Hello!" }, ..129 ]; + let w = [ ~"Hello!", ..129 ]; let x = [ @[true], ..512 ]; let y = [ 0, ..1 ]; + + error!("%?", v); + error!("%?", w); error!("%?", x); error!("%?", y); } diff --git a/src/test/run-pass/resolve-issue-2428.rs b/src/test/run-pass/resolve-issue-2428.rs index 20cda911cdd47..799db4ed2125a 100644 --- a/src/test/run-pass/resolve-issue-2428.rs +++ b/src/test/run-pass/resolve-issue-2428.rs @@ -10,6 +10,6 @@ // xfail-test -const foo: int = 4 >> 1; +static foo: int = 4 >> 1; enum bs { thing = foo } pub fn main() { fail_unless!((thing as int == foo)); } diff --git a/src/test/run-pass/resource-assign-is-not-copy.rs b/src/test/run-pass/resource-assign-is-not-copy.rs index df084c134277f..7d9c01cd2e34f 100644 --- a/src/test/run-pass/resource-assign-is-not-copy.rs +++ b/src/test/run-pass/resource-assign-is-not-copy.rs @@ -12,9 +12,12 @@ struct r { i: @mut int, } +#[unsafe_destructor] impl Drop for r { fn finalize(&self) { - *(self.i) += 1; + unsafe { + *(self.i) += 1; + } } } diff --git a/src/test/run-pass/resource-destruct.rs b/src/test/run-pass/resource-destruct.rs index db444f08fab47..cc9a27fd9e4d1 100644 --- a/src/test/run-pass/resource-destruct.rs +++ b/src/test/run-pass/resource-destruct.rs @@ -12,9 +12,12 @@ struct shrinky_pointer { i: @@mut int, } +#[unsafe_destructor] impl Drop for shrinky_pointer { fn finalize(&self) { - error!(~"Hello!"); **(self.i) -= 1; + unsafe { + error!(~"Hello!"); **(self.i) -= 1; + } } } diff --git a/src/test/run-pass/resource-generic.rs b/src/test/run-pass/resource-generic.rs index e43b90c30b026..4ce6a37956c52 100644 --- a/src/test/run-pass/resource-generic.rs +++ b/src/test/run-pass/resource-generic.rs @@ -16,9 +16,12 @@ struct finish { arg: Arg } +#[unsafe_destructor] impl Drop for finish { fn finalize(&self) { - (self.arg.fin)(self.arg.val); + unsafe { + (self.arg.fin)(self.arg.val); + } } } diff --git a/src/test/run-pass/resource-in-struct.rs b/src/test/run-pass/resource-in-struct.rs index 53c76680bdec5..9eb680ed7cc03 100644 --- a/src/test/run-pass/resource-in-struct.rs +++ b/src/test/run-pass/resource-in-struct.rs @@ -18,9 +18,12 @@ struct close_res { } +#[unsafe_destructor] impl Drop for close_res { fn finalize(&self) { - *(self.i) = false; + unsafe { + *(self.i) = false; + } } } diff --git a/src/test/run-pass/shift.rs b/src/test/run-pass/shift.rs index c6165c1530a22..cea32fc745eca 100644 --- a/src/test/run-pass/shift.rs +++ b/src/test/run-pass/shift.rs @@ -54,28 +54,28 @@ fn test_expr() { } fn test_const() { - const r1_1: uint = 10u >> 2u8; - const r2_1: uint = 10u << 4u8; + static r1_1: uint = 10u >> 2u8; + static r2_1: uint = 10u << 4u8; fail_unless!(r1_1 == 2 as uint); fail_unless!(r2_1 == 160 as uint); - const r1_2: u8 = 10u8 >> 2u; - const r2_2: u8 = 10u8 << 4u; + static r1_2: u8 = 10u8 >> 2u; + static r2_2: u8 = 10u8 << 4u; fail_unless!(r1_2 == 2 as u8); fail_unless!(r2_2 == 160 as u8); - const r1_3: int = 10 >> 2i8; - const r2_3: int = 10 << 4i8; + static r1_3: int = 10 >> 2i8; + static r2_3: int = 10 << 4i8; fail_unless!(r1_3 == 2 as int); fail_unless!(r2_3 == 160 as int); - const r1_4: i8 = 10i8 >> 2; - const r2_4: i8 = 10i8 << 4; + static r1_4: i8 = 10i8 >> 2; + static r2_4: i8 = 10i8 << 4; fail_unless!(r1_4 == 2 as i8); fail_unless!(r2_4 == 160 as i8); - const r1_5: uint = 10u >> 2i8; - const r2_5: uint = 10u << 4i8; + static r1_5: uint = 10u >> 2i8; + static r2_5: uint = 10u << 4i8; fail_unless!(r1_5 == 2 as uint); fail_unless!(r2_5 == 160 as uint); } diff --git a/src/test/run-pass/static-method-in-trait-with-tps-intracrate.rs b/src/test/run-pass/static-method-in-trait-with-tps-intracrate.rs index 1146412ec4f14..1b5cb86360b20 100644 --- a/src/test/run-pass/static-method-in-trait-with-tps-intracrate.rs +++ b/src/test/run-pass/static-method-in-trait-with-tps-intracrate.rs @@ -13,11 +13,11 @@ trait Deserializer { } trait Deserializable { - static fn deserialize(&self, d: &D) -> Self; + fn deserialize(d: &D) -> Self; } impl Deserializable for int { - static fn deserialize(&self, d: &D) -> int { + fn deserialize(d: &D) -> int { return d.read_int(); } } diff --git a/src/test/run-pass/static-method-test.rs b/src/test/run-pass/static-method-test.rs index 0c6359375d306..624a38b789b1c 100644 --- a/src/test/run-pass/static-method-test.rs +++ b/src/test/run-pass/static-method-test.rs @@ -14,7 +14,7 @@ // A trait for objects that can be used to do an if-then-else // (No actual need for this to be static, but it is a simple test.) trait bool_like { - static fn select(b: Self, +x1: A, +x2: A) -> A; + fn select(b: Self, +x1: A, +x2: A) -> A; } fn andand(x1: T, x2: T) -> T { @@ -22,41 +22,38 @@ fn andand(x1: T, x2: T) -> T { } impl bool_like for bool { - static fn select(&&b: bool, +x1: A, +x2: A) -> A { + fn select(&&b: bool, +x1: A, +x2: A) -> A { if b { x1 } else { x2 } } } impl bool_like for int { - static fn select(&&b: int, +x1: A, +x2: A) -> A { + fn select(&&b: int, +x1: A, +x2: A) -> A { if b != 0 { x1 } else { x2 } } } // A trait for sequences that can be constructed imperatively. trait buildable { - static pure fn build_sized(size: uint, - builder: &fn(push: &pure fn(+v: A))) -> Self; + fn build_sized(size: uint, builder: &fn(push: &fn(+v: A))) -> Self; } impl buildable for @[A] { #[inline(always)] - static pure fn build_sized(size: uint, - builder: &fn(push: &pure fn(+v: A))) -> @[A] { + fn build_sized(size: uint, builder: &fn(push: &fn(+v: A))) -> @[A] { at_vec::build_sized(size, builder) } } impl buildable for ~[A] { #[inline(always)] - static pure fn build_sized(size: uint, - builder: &fn(push: &pure fn(+v: A))) -> ~[A] { + fn build_sized(size: uint, builder: &fn(push: &fn(+v: A))) -> ~[A] { vec::build_sized(size, builder) } } #[inline(always)] -pure fn build>(builder: &fn(push: &pure fn(+v: A))) -> B { +fn build>(builder: &fn(push: &fn(+v: A))) -> B { buildable::build_sized(4, builder) } diff --git a/src/test/run-pass/static-methods-in-traits.rs b/src/test/run-pass/static-methods-in-traits.rs index be83fe4d3ab88..24bcfcef1e745 100644 --- a/src/test/run-pass/static-methods-in-traits.rs +++ b/src/test/run-pass/static-methods-in-traits.rs @@ -10,17 +10,17 @@ mod a { pub trait Foo { - static pub fn foo() -> Self; + pub fn foo() -> Self; } impl Foo for int { - static pub fn foo() -> int { + pub fn foo() -> int { 3 } } impl Foo for uint { - static pub fn foo() -> uint { + pub fn foo() -> uint { 5u } } diff --git a/src/test/run-pass/static-methods-in-traits2.rs b/src/test/run-pass/static-methods-in-traits2.rs index 20ab9014c700b..20e6efa11f090 100644 --- a/src/test/run-pass/static-methods-in-traits2.rs +++ b/src/test/run-pass/static-methods-in-traits2.rs @@ -1,17 +1,17 @@ pub trait Number: NumConv { - static pure fn from(n: T) -> Self; + fn from(n: T) -> Self; } impl Number for float { - static pure fn from(n: T) -> float { n.to_float() } + fn from(n: T) -> float { n.to_float() } } pub trait NumConv { - pure fn to_float(&self) -> float; + fn to_float(&self) -> float; } impl NumConv for float { - pure fn to_float(&self) -> float { *self } + fn to_float(&self) -> float { *self } } pub fn main() { diff --git a/src/test/run-pass/structured-compare.rs b/src/test/run-pass/structured-compare.rs index f32fc27e3aa0c..d987203344723 100644 --- a/src/test/run-pass/structured-compare.rs +++ b/src/test/run-pass/structured-compare.rs @@ -13,10 +13,10 @@ enum foo { large, small, } impl cmp::Eq for foo { - pure fn eq(&self, other: &foo) -> bool { + fn eq(&self, other: &foo) -> bool { ((*self) as uint) == ((*other) as uint) } - pure fn ne(&self, other: &foo) -> bool { !(*self).eq(other) } + fn ne(&self, other: &foo) -> bool { !(*self).eq(other) } } pub fn main() { diff --git a/src/test/run-pass/tag-variant-disr-val.rs b/src/test/run-pass/tag-variant-disr-val.rs index 2f87142d68824..63300342bd33c 100644 --- a/src/test/run-pass/tag-variant-disr-val.rs +++ b/src/test/run-pass/tag-variant-disr-val.rs @@ -20,10 +20,10 @@ enum color { } impl cmp::Eq for color { - pure fn eq(&self, other: &color) -> bool { + fn eq(&self, other: &color) -> bool { ((*self) as uint) == ((*other) as uint) } - pure fn ne(&self, other: &color) -> bool { !(*self).eq(other) } + fn ne(&self, other: &color) -> bool { !(*self).eq(other) } } pub fn main() { diff --git a/src/test/run-pass/tag.rs b/src/test/run-pass/tag.rs index 729e11dfc6415..4e126379410be 100644 --- a/src/test/run-pass/tag.rs +++ b/src/test/run-pass/tag.rs @@ -15,7 +15,7 @@ enum colour { red(int, int), green, } impl cmp::Eq for colour { - pure fn eq(&self, other: &colour) -> bool { + fn eq(&self, other: &colour) -> bool { match *self { red(a0, b0) => { match (*other) { @@ -31,7 +31,7 @@ impl cmp::Eq for colour { } } } - pure fn ne(&self, other: &colour) -> bool { !(*self).eq(other) } + fn ne(&self, other: &colour) -> bool { !(*self).eq(other) } } fn f() { let x = red(1, 2); let y = green; fail_unless!((x != y)); } diff --git a/src/test/run-pass/task-comm-16.rs b/src/test/run-pass/task-comm-16.rs index c50dfe7916988..89dad2d462cca 100644 --- a/src/test/run-pass/task-comm-16.rs +++ b/src/test/run-pass/task-comm-16.rs @@ -52,7 +52,7 @@ enum t { } impl cmp::Eq for t { - pure fn eq(&self, other: &t) -> bool { + fn eq(&self, other: &t) -> bool { match *self { tag1 => { match (*other) { @@ -75,7 +75,7 @@ impl cmp::Eq for t { } } } - pure fn ne(&self, other: &t) -> bool { !(*self).eq(other) } + fn ne(&self, other: &t) -> bool { !(*self).eq(other) } } fn test_tag() { diff --git a/src/test/run-pass/task-killjoin-rsrc.rs b/src/test/run-pass/task-killjoin-rsrc.rs index 39651f86e227b..042ae1785d1be 100644 --- a/src/test/run-pass/task-killjoin-rsrc.rs +++ b/src/test/run-pass/task-killjoin-rsrc.rs @@ -20,15 +20,18 @@ struct notify { ch: Chan, v: @mut bool, } +#[unsafe_destructor] impl Drop for notify { fn finalize(&self) { - error!("notify: task=%? v=%x unwinding=%b b=%b", - task::get_task(), - ptr::addr_of(&(*(self.v))) as uint, - task::failing(), - *(self.v)); - let b = *(self.v); - self.ch.send(b); + unsafe { + error!("notify: task=%? v=%x unwinding=%b b=%b", + task::get_task(), + ptr::addr_of(&(*(self.v))) as uint, + task::failing(), + *(self.v)); + let b = *(self.v); + self.ch.send(b); + } } } diff --git a/src/test/run-pass/trait-inheritance-num0.rs b/src/test/run-pass/trait-inheritance-num0.rs index 7f0d4d77b6264..aae430dc4cdf9 100644 --- a/src/test/run-pass/trait-inheritance-num0.rs +++ b/src/test/run-pass/trait-inheritance-num0.rs @@ -15,7 +15,7 @@ use core::num::NumCast::from; trait Num { - static fn from_int(i: int) -> Self; + fn from_int(i: int) -> Self; fn gt(&self, other: &Self) -> bool; } diff --git a/src/test/run-pass/trait-inheritance-overloading-simple.rs b/src/test/run-pass/trait-inheritance-overloading-simple.rs index ce370854a41fe..283ed8ae2c188 100644 --- a/src/test/run-pass/trait-inheritance-overloading-simple.rs +++ b/src/test/run-pass/trait-inheritance-overloading-simple.rs @@ -15,8 +15,8 @@ trait MyNum : Eq { } struct MyInt { val: int } impl Eq for MyInt { - pure fn eq(&self, other: &MyInt) -> bool { self.val == other.val } - pure fn ne(&self, other: &MyInt) -> bool { !self.eq(other) } + fn eq(&self, other: &MyInt) -> bool { self.val == other.val } + fn ne(&self, other: &MyInt) -> bool { !self.eq(other) } } impl MyNum for MyInt; @@ -25,7 +25,7 @@ fn f(x: T, y: T) -> bool { return x == y; } -pure fn mi(v: int) -> MyInt { MyInt { val: v } } +fn mi(v: int) -> MyInt { MyInt { val: v } } pub fn main() { let (x, y, z) = (mi(3), mi(5), mi(3)); diff --git a/src/test/run-pass/trait-inheritance-overloading-xc-exe.rs b/src/test/run-pass/trait-inheritance-overloading-xc-exe.rs index f97412f420718..d4d16f2b43ebd 100644 --- a/src/test/run-pass/trait-inheritance-overloading-xc-exe.rs +++ b/src/test/run-pass/trait-inheritance-overloading-xc-exe.rs @@ -18,7 +18,7 @@ fn f(x: T, y: T) -> (T, T, T) { return (x + y, x - y, x * y); } -pure fn mi(v: int) -> MyInt { MyInt { val: v } } +fn mi(v: int) -> MyInt { MyInt { val: v } } pub fn main() { let (x, y) = (mi(3), mi(5)); diff --git a/src/test/run-pass/trait-inheritance-overloading.rs b/src/test/run-pass/trait-inheritance-overloading.rs index aadc065095850..d4f8d50b92b64 100644 --- a/src/test/run-pass/trait-inheritance-overloading.rs +++ b/src/test/run-pass/trait-inheritance-overloading.rs @@ -15,20 +15,20 @@ trait MyNum : Add + Sub + Mul + Eq { } struct MyInt { val: int } impl Add for MyInt { - pure fn add(&self, other: &MyInt) -> MyInt { mi(self.val + other.val) } + fn add(&self, other: &MyInt) -> MyInt { mi(self.val + other.val) } } impl Sub for MyInt { - pure fn sub(&self, other: &MyInt) -> MyInt { mi(self.val - other.val) } + fn sub(&self, other: &MyInt) -> MyInt { mi(self.val - other.val) } } impl Mul for MyInt { - pure fn mul(&self, other: &MyInt) -> MyInt { mi(self.val * other.val) } + fn mul(&self, other: &MyInt) -> MyInt { mi(self.val * other.val) } } impl Eq for MyInt { - pure fn eq(&self, other: &MyInt) -> bool { self.val == other.val } - pure fn ne(&self, other: &MyInt) -> bool { !self.eq(other) } + fn eq(&self, other: &MyInt) -> bool { self.val == other.val } + fn ne(&self, other: &MyInt) -> bool { !self.eq(other) } } impl MyNum for MyInt; @@ -37,7 +37,7 @@ fn f(x: T, y: T) -> (T, T, T) { return (x + y, x - y, x * y); } -pure fn mi(v: int) -> MyInt { MyInt { val: v } } +fn mi(v: int) -> MyInt { MyInt { val: v } } pub fn main() { let (x, y) = (mi(3), mi(5)); diff --git a/src/test/run-pass/trait-inheritance-static.rs b/src/test/run-pass/trait-inheritance-static.rs index 1d11870b21ab5..f3adea18ecdc1 100644 --- a/src/test/run-pass/trait-inheritance-static.rs +++ b/src/test/run-pass/trait-inheritance-static.rs @@ -9,7 +9,7 @@ // except according to those terms. trait MyNum { - static fn from_int(int) -> Self; + fn from_int(int) -> Self; } pub trait NumExt: MyNum { } @@ -17,7 +17,7 @@ pub trait NumExt: MyNum { } struct S { v: int } impl MyNum for S { - static fn from_int(i: int) -> S { + fn from_int(i: int) -> S { S { v: i } diff --git a/src/test/run-pass/trait-inheritance-static2.rs b/src/test/run-pass/trait-inheritance-static2.rs index 30fefa7501f74..45369d4ec19d5 100644 --- a/src/test/run-pass/trait-inheritance-static2.rs +++ b/src/test/run-pass/trait-inheritance-static2.rs @@ -11,7 +11,7 @@ trait MyEq { } trait MyNum { - static fn from_int(int) -> Self; + fn from_int(int) -> Self; } pub trait NumExt: MyEq + MyNum { } @@ -21,7 +21,7 @@ struct S { v: int } impl MyEq for S { } impl MyNum for S { - static fn from_int(i: int) -> S { + fn from_int(i: int) -> S { S { v: i } diff --git a/src/test/run-pass/trait-inheritance-subst.rs b/src/test/run-pass/trait-inheritance-subst.rs index c1ee7a2c00a22..9d0e5fa1f13d4 100644 --- a/src/test/run-pass/trait-inheritance-subst.rs +++ b/src/test/run-pass/trait-inheritance-subst.rs @@ -9,7 +9,7 @@ // except according to those terms. pub trait Add { - pure fn add(&self, rhs: &RHS) -> Result; + fn add(&self, rhs: &RHS) -> Result; } trait MyNum : Add { } @@ -17,7 +17,7 @@ trait MyNum : Add { } struct MyInt { val: int } impl Add for MyInt { - pure fn add(&self, other: &MyInt) -> MyInt { mi(self.val + other.val) } + fn add(&self, other: &MyInt) -> MyInt { mi(self.val + other.val) } } impl MyNum for MyInt; @@ -26,7 +26,7 @@ fn f(x: T, y: T) -> T { return x.add(&y); } -pure fn mi(v: int) -> MyInt { MyInt { val: v } } +fn mi(v: int) -> MyInt { MyInt { val: v } } pub fn main() { let (x, y) = (mi(3), mi(5)); diff --git a/src/test/run-pass/trait-static-method-overwriting.rs b/src/test/run-pass/trait-static-method-overwriting.rs index 9565919a5d8c7..a8a579422a372 100644 --- a/src/test/run-pass/trait-static-method-overwriting.rs +++ b/src/test/run-pass/trait-static-method-overwriting.rs @@ -12,7 +12,7 @@ mod base { pub trait HasNew { - static pure fn new() -> T; + fn new() -> T; } pub struct Foo { @@ -20,7 +20,7 @@ mod base { } impl ::base::HasNew for Foo { - static pure fn new() -> Foo { + fn new() -> Foo { unsafe { io::println("Foo"); } Foo { dummy: () } } @@ -31,7 +31,7 @@ mod base { } impl ::base::HasNew for Bar { - static pure fn new() -> Bar { + fn new() -> Bar { unsafe { io::println("Bar"); } Bar { dummy: () } } diff --git a/src/test/run-pass/tstate-loop-break.rs b/src/test/run-pass/tstate-loop-break.rs index 8b626611c410c..4228f72b7caa4 100644 --- a/src/test/run-pass/tstate-loop-break.rs +++ b/src/test/run-pass/tstate-loop-break.rs @@ -10,7 +10,7 @@ // xfail-test -pure fn is_even(i: int) -> bool { (i%2) == 0 } +fn is_even(i: int) -> bool { (i%2) == 0 } fn even(i: int) : is_even(i) -> int { i } fn test() { diff --git a/src/test/run-pass/typeclasses-eq-example-static.rs b/src/test/run-pass/typeclasses-eq-example-static.rs index cd914aaa3185b..7303f5ecbdf6c 100644 --- a/src/test/run-pass/typeclasses-eq-example-static.rs +++ b/src/test/run-pass/typeclasses-eq-example-static.rs @@ -12,13 +12,13 @@ // methods! trait Equal { - static fn isEq(a: Self, b: Self) -> bool; + fn isEq(a: Self, b: Self) -> bool; } enum Color { cyan, magenta, yellow, black } impl Equal for Color { - static fn isEq(a: Color, b: Color) -> bool { + fn isEq(a: Color, b: Color) -> bool { match (a, b) { (cyan, cyan) => { true } (magenta, magenta) => { true } @@ -35,7 +35,7 @@ enum ColorTree { } impl Equal for ColorTree { - static fn isEq(a: ColorTree, b: ColorTree) -> bool { + fn isEq(a: ColorTree, b: ColorTree) -> bool { match (a, b) { (leaf(x), leaf(y)) => { Equal::isEq(x, y) } (branch(l1, r1), branch(l2, r2)) => { diff --git a/src/test/run-pass/unique-pinned-nocopy-2.rs b/src/test/run-pass/unique-pinned-nocopy-2.rs index 3fc22c9a5a538..ff22c18b02c74 100644 --- a/src/test/run-pass/unique-pinned-nocopy-2.rs +++ b/src/test/run-pass/unique-pinned-nocopy-2.rs @@ -12,9 +12,12 @@ struct r { i: @mut int, } +#[unsafe_destructor] impl Drop for r { fn finalize(&self) { - *(self.i) = *(self.i) + 1; + unsafe { + *(self.i) = *(self.i) + 1; + } } } diff --git a/src/test/run-pass/unwind-resource2.rs b/src/test/run-pass/unwind-resource2.rs index 75ce797cfc842..993acc2264f68 100644 --- a/src/test/run-pass/unwind-resource2.rs +++ b/src/test/run-pass/unwind-resource2.rs @@ -15,6 +15,7 @@ struct complainer { c: @int, } +#[unsafe_destructor] impl Drop for complainer { fn finalize(&self) {} } diff --git a/src/test/run-pass/vec-slice-drop.rs b/src/test/run-pass/vec-slice-drop.rs index 71963e073db9c..2a7c9610ad42e 100644 --- a/src/test/run-pass/vec-slice-drop.rs +++ b/src/test/run-pass/vec-slice-drop.rs @@ -13,9 +13,12 @@ struct foo { x: @mut int, } +#[unsafe_destructor] impl Drop for foo { fn finalize(&self) { - *self.x += 1; + unsafe { + *self.x += 1; + } } } diff --git a/src/test/run-pass/weird-exprs.rs b/src/test/run-pass/weird-exprs.rs index a7ac8554b3d4a..0af35a6c619e5 100644 --- a/src/test/run-pass/weird-exprs.rs +++ b/src/test/run-pass/weird-exprs.rs @@ -56,7 +56,7 @@ fn notsure() { } fn canttouchthis() -> uint { - pure fn p() -> bool { true } + fn p() -> bool { true } let _a = (fail_unless!((true)) == (fail_unless!(p()))); let _c = (fail_unless!((p())) == ()); let _b: bool = (debug!("%d", 0) == (return 0u)); diff --git a/src/test/run-pass/while-prelude-drop.rs b/src/test/run-pass/while-prelude-drop.rs index da3f28f5b7bca..082f2db259a4a 100644 --- a/src/test/run-pass/while-prelude-drop.rs +++ b/src/test/run-pass/while-prelude-drop.rs @@ -9,7 +9,7 @@ // except according to those terms. -#[deriving_eq] +#[deriving(Eq)] enum t { a, b(~str), } fn make(i: int) -> t {