diff --git a/AUTHORS.txt b/AUTHORS.txt index 628fa4c86da00..92903a26093f9 100644 --- a/AUTHORS.txt +++ b/AUTHORS.txt @@ -161,4 +161,4 @@ Wade Mealing William Ting Yasuhiro Fujii Youngsoo Son -Zack Corr +Zack Corr diff --git a/Makefile.in b/Makefile.in index e476ac1dba2d1..30aefd02cd2da 100644 --- a/Makefile.in +++ b/Makefile.in @@ -131,26 +131,29 @@ CFG_STDLIB :=$(call CFG_LIB_NAME,std) CFG_LIBRUSTC :=$(call CFG_LIB_NAME,rustc) CFG_LIBSYNTAX :=$(call CFG_LIB_NAME,syntax) CFG_LIBFUZZER :=$(call CFG_LIB_NAME,fuzzer) -CFG_LIBCARGO :=$(call CFG_LIB_NAME,cargo) +CFG_LIBRUSTPKG :=$(call CFG_LIB_NAME,rustpkg) CFG_LIBRUSTDOC :=$(call CFG_LIB_NAME,rustdoc) CFG_LIBRUSTI :=$(call CFG_LIB_NAME,rusti) +CFG_LIBRUST :=$(call CFG_LIB_NAME,rust) STDLIB_GLOB :=$(call CFG_LIB_GLOB,std) CORELIB_GLOB :=$(call CFG_LIB_GLOB,core) LIBRUSTC_GLOB :=$(call CFG_LIB_GLOB,rustc) LIBSYNTAX_GLOB :=$(call CFG_LIB_GLOB,syntax) LIBFUZZER_GLOB :=$(call CFG_LIB_GLOB,fuzzer) -LIBCARGO_GLOB :=$(call CFG_LIB_GLOB,cargo) +LIBRUSTPKG_GLOB :=$(call CFG_LIB_GLOB,rustpkg) LIBRUSTDOC_GLOB :=$(call CFG_LIB_GLOB,rustdoc) LIBRUSTI_GLOB :=$(call CFG_LIB_GLOB,rusti) +LIBRUST_GLOB :=$(call CFG_LIB_GLOB,rust) STDLIB_DSYM_GLOB :=$(call CFG_LIB_DSYM_GLOB,std) CORELIB_DSYM_GLOB :=$(call CFG_LIB_DSYM_GLOB,core) LIBRUSTC_DSYM_GLOB :=$(call CFG_LIB_DSYM_GLOB,rustc) LIBSYNTAX_DSYM_GLOB :=$(call CFG_LIB_DSYM_GLOB,syntax) LIBFUZZER_DSYM_GLOB :=$(call CFG_LIB_DSYM_GLOB,fuzzer) -LIBCARGO_DSYM_GLOB :=$(call CFG_LIB_DSYM_GLOB,cargo) +LIBRUSTPKG_DSYM_GLOB :=$(call CFG_LIB_DSYM_GLOB,rustpkg) LIBRUSTDOC_DSYM_GLOB :=$(call CFG_LIB_DSYM_GLOB,rustdoc) LIBRUSTI_DSYM_GLOB :=$(call CFG_LIB_DSYM_GLOB,rusti) +LIBRUST_DSYM_GLOB :=$(call CFG_LIB_DSYM_GLOB,rust) # version-string calculation CFG_GIT_DIR := $(CFG_SRC_DIR).git @@ -371,21 +374,24 @@ SREQ$(1)_T_$(2)_H_$(3) = \ CSREQ$(1)_T_$(2)_H_$(3) = \ $$(TSREQ$(1)_T_$(2)_H_$(3)) \ $$(HBIN$(1)_H_$(3))/fuzzer$$(X) \ - $$(HBIN$(1)_H_$(3))/cargo$$(X) \ + $$(HBIN$(1)_H_$(3))/rustpkg$$(X) \ $$(HBIN$(1)_H_$(3))/rustdoc$$(X) \ $$(HBIN$(1)_H_$(3))/rusti$$(X) \ + $$(HBIN$(1)_H_$(3))/rust$$(X) \ $$(HLIB$(1)_H_$(3))/$$(CFG_LIBFUZZER) \ - $$(HLIB$(1)_H_$(3))/$$(CFG_LIBCARGO) \ + $$(HLIB$(1)_H_$(3))/$$(CFG_LIBRUSTPKG) \ $$(HLIB$(1)_H_$(3))/$$(CFG_LIBRUSTDOC) \ $$(HLIB$(1)_H_$(3))/$$(CFG_LIBRUSTI) \ + $$(HLIB$(1)_H_$(3))/$$(CFG_LIBRUST) \ $$(TLIB$(1)_T_$(2)_H_$(3))/$$(CFG_CORELIB) \ $$(TLIB$(1)_T_$(2)_H_$(3))/$$(CFG_STDLIB) \ $$(TLIB$(1)_T_$(2)_H_$(3))/$$(CFG_LIBSYNTAX) \ $$(TLIB$(1)_T_$(2)_H_$(3))/$$(CFG_LIBRUSTC) \ $$(TLIB$(1)_T_$(2)_H_$(3))/$$(CFG_LIBFUZZER) \ - $$(TLIB$(1)_T_$(2)_H_$(3))/$$(CFG_LIBCARGO) \ + $$(TLIB$(1)_T_$(2)_H_$(3))/$$(CFG_LIBRUSTPKG) \ $$(TLIB$(1)_T_$(2)_H_$(3))/$$(CFG_LIBRUSTDOC) \ - $$(TLIB$(1)_T_$(2)_H_$(3))/$$(CFG_LIBRUSTI) + $$(TLIB$(1)_T_$(2)_H_$(3))/$$(CFG_LIBRUSTI) \ + $$(TLIB$(1)_T_$(2)_H_$(3))/$$(CFG_LIBRUST) ifeq ($(1),0) # Don't run the the stage0 compiler under valgrind - that ship has sailed diff --git a/README.md b/README.md index 27b63c1080bd4..a34f8814f020d 100644 --- a/README.md +++ b/README.md @@ -56,7 +56,7 @@ for more information on them. When complete, `make install` will place several programs into `/usr/local/bin`: `rustc`, the Rust compiler; `rustdoc`, the -API-documentation tool, and `cargo`, the Rust package manager. +API-documentation tool, and `rustpkg`, the Rust package manager and build system. [wiki-start]: https://github.com/mozilla/rust/wiki/Note-getting-started-developing-Rust [tarball]: http://static.rust-lang.org/dist/rust-0.5.tar.gz diff --git a/doc/rust.md b/doc/rust.md index 30896307aeebf..10fb203d022d6 100644 --- a/doc/rust.md +++ b/doc/rust.md @@ -213,7 +213,7 @@ else enum extern false fn for if impl let log loop -match mod move mut +match mod mut priv pub pure ref return self static struct super @@ -297,7 +297,7 @@ the following forms: num_lit : nonzero_dec [ dec_digit | '_' ] * num_suffix ? | '0' [ [ dec_digit | '_' ] + num_suffix ? | 'b' [ '1' | '0' | '_' ] + int_suffix ? - | 'x' [ hex_digit | '-' ] + int_suffix ? ] ; + | 'x' [ hex_digit | '_' ] + int_suffix ? ] ; num_suffix : int_suffix | float_suffix ; @@ -549,7 +549,7 @@ This requirement most often affects name-designator pairs when they occur at the * `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. -* `ident_to_str!` : turn the identifier argument into a string literal +* `stringify!` : turn the identifier argument into a string literal * `concat_idents!` : create a new identifier by concatenating the arguments @@ -686,15 +686,15 @@ mod math { type complex = (f64, f64); fn sin(f: f64) -> f64 { ... -# die!(); +# fail!(); } fn cos(f: f64) -> f64 { ... -# die!(); +# fail!(); } fn tan(f: f64) -> f64 { ... -# die!(); +# fail!(); } } ~~~~~~~~ @@ -986,7 +986,7 @@ output slot type would normally be. For example: ~~~~ fn my_err(s: &str) -> ! { log(info, s); - die!(); + fail!(); } ~~~~ @@ -1004,7 +1004,7 @@ were declared without the `!` annotation, the following code would not typecheck: ~~~~ -# fn my_err(s: &str) -> ! { die!() } +# fn my_err(s: &str) -> ! { fail!() } fn f(i: int) -> int { if i == 42 { @@ -1117,6 +1117,7 @@ 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 ~~~~~~~~ {.ebnf .gram} @@ -2284,9 +2285,9 @@ enum List { Nil, Cons(X, @List) } let x: List = Cons(10, @Cons(11, @Nil)); match x { - Cons(_, @Nil) => die!(~"singleton list"), + Cons(_, @Nil) => fail!(~"singleton list"), Cons(*) => return, - Nil => die!(~"empty list") + Nil => fail!(~"empty list") } ~~~~ @@ -2323,7 +2324,7 @@ match x { return; } _ => { - die!(); + fail!(); } } ~~~~ @@ -2411,7 +2412,7 @@ guard may refer to the variables bound within the pattern they follow. let message = match maybe_digit { Some(x) if x < 10 => process_digit(x), Some(x) => process_other(x), - None => die!() + None => fail!() }; ~~~~ diff --git a/doc/tutorial-borrowed-ptr.md b/doc/tutorial-borrowed-ptr.md index 939051ca6058d..c13b2528598c1 100644 --- a/doc/tutorial-borrowed-ptr.md +++ b/doc/tutorial-borrowed-ptr.md @@ -431,7 +431,7 @@ fn example5c(x: @S) -> int { let y = &v.g; ... } - x.f = move v; // Replace x.f + x.f = v; // Replace x.f ... # return 0; } diff --git a/doc/tutorial-macros.md b/doc/tutorial-macros.md index e2813e0809fc7..42bd319a2a4bd 100644 --- a/doc/tutorial-macros.md +++ b/doc/tutorial-macros.md @@ -218,7 +218,7 @@ match x { // complicated stuff goes here return result + val; }, - _ => die!(~"Didn't get good_2") + _ => fail!(~"Didn't get good_2") } } _ => return 0 // default value @@ -260,7 +260,7 @@ macro_rules! biased_match ( biased_match!((x) ~ (good_1(g1, val)) else { return 0 }; binds g1, val ) biased_match!((g1.body) ~ (good_2(result) ) - else { die!(~"Didn't get good_2") }; + else { fail!(~"Didn't get good_2") }; binds result ) // complicated stuff goes here return result + val; @@ -362,7 +362,7 @@ macro_rules! biased_match ( # fn f(x: t1) -> uint { biased_match!( (x) ~ (good_1(g1, val)) else { return 0 }; - (g1.body) ~ (good_2(result) ) else { die!(~"Didn't get good_2") }; + (g1.body) ~ (good_2(result) ) else { fail!(~"Didn't get good_2") }; binds val, result ) // complicated stuff goes here return result + val; diff --git a/doc/tutorial-tasks.md b/doc/tutorial-tasks.md index f814970375a7d..c0f9a37627065 100644 --- a/doc/tutorial-tasks.md +++ b/doc/tutorial-tasks.md @@ -157,11 +157,11 @@ concurrently: ~~~~ use task::spawn; -use pipes::{stream, Port, Chan}; +use comm::{stream, Port, Chan}; let (port, chan): (Port, Chan) = stream(); -do spawn |move chan| { +do spawn || { let result = some_expensive_computation(); chan.send(result); } @@ -178,7 +178,7 @@ stream for sending and receiving integers (the left-hand side of the `let`, a tuple into its component parts). ~~~~ -# use pipes::{stream, Chan, Port}; +# use comm::{stream, Chan, Port}; let (port, chan): (Port, Chan) = stream(); ~~~~ @@ -189,10 +189,10 @@ spawns the child task. ~~~~ # use task::{spawn}; # use task::spawn; -# use pipes::{stream, Port, Chan}; +# use comm::{stream, Port, Chan}; # fn some_expensive_computation() -> int { 42 } # let (port, chan) = stream(); -do spawn |move chan| { +do spawn || { let result = some_expensive_computation(); chan.send(result); } @@ -209,7 +209,7 @@ computation, then waits for the child's result to arrive on the port: ~~~~ -# use pipes::{stream, Port, Chan}; +# use comm::{stream, Port, Chan}; # fn some_other_expensive_computation() {} # let (port, chan) = stream::(); # chan.send(0); @@ -225,11 +225,11 @@ following program is ill-typed: ~~~ {.xfail-test} # use task::{spawn}; -# use pipes::{stream, Port, Chan}; +# use comm::{stream, Port, Chan}; # fn some_expensive_computation() -> int { 42 } let (port, chan) = stream(); -do spawn |move chan| { +do spawn { chan.send(some_expensive_computation()); } @@ -245,15 +245,15 @@ Instead we can use a `SharedChan`, a type that allows a single ~~~ # use task::spawn; -use pipes::{stream, SharedChan}; +use comm::{stream, SharedChan}; let (port, chan) = stream(); -let chan = SharedChan(move chan); +let chan = SharedChan(chan); for uint::range(0, 3) |init_val| { // Create a new channel handle to distribute to the child task let child_chan = chan.clone(); - do spawn |move child_chan| { + do spawn { child_chan.send(some_expensive_computation(init_val)); } } @@ -278,15 +278,15 @@ might look like the example below. ~~~ # use task::spawn; -# use pipes::{stream, Port, Chan}; +# use comm::{stream, Port, Chan}; // Create a vector of ports, one for each child task let ports = do vec::from_fn(3) |init_val| { let (port, chan) = stream(); - do spawn |move chan| { + do spawn { chan.send(some_expensive_computation(init_val)); } - move port + port }; // Wait on each port, accumulating the results @@ -313,7 +313,7 @@ of all tasks are intertwined: if one fails, so do all the others. # fn do_some_work() { loop { task::yield() } } # do task::try { // Create a child task that fails -do spawn { die!() } +do spawn { fail!() } // This will also fail because the task we spawned failed do_some_work(); @@ -337,7 +337,7 @@ let result: Result = do task::try { if some_condition() { calculate_result() } else { - die!(~"oops!"); + fail!(~"oops!"); } }; assert result.is_err(); @@ -370,14 +370,14 @@ proceed). Hence, you will need different _linked failure modes_. ## Failure modes By default, task failure is _bidirectionally linked_, which means that if -either task dies, it kills the other one. +either task fails, it kills the other one. ~~~ # fn sleep_forever() { loop { task::yield() } } # do task::try { do task::spawn { do task::spawn { - die!(); // All three tasks will die. + fail!(); // All three tasks will fail. } sleep_forever(); // Will get woken up by force, then fail } @@ -386,25 +386,25 @@ sleep_forever(); // Will get woken up by force, then fail ~~~ If you want parent tasks to be able to kill their children, but do not want a -parent to die automatically if one of its child task dies, you can call +parent to fail automatically if one of its child task fails, you can call `task::spawn_supervised` for _unidirectionally linked_ failure. The function `task::try`, which we saw previously, uses `spawn_supervised` internally, with additional logic to wait for the child task to finish before returning. Hence: ~~~ -# use pipes::{stream, Chan, Port}; +# use comm::{stream, Chan, Port}; # use task::{spawn, try}; # fn sleep_forever() { loop { task::yield() } } # do task::try { let (receiver, sender): (Port, Chan) = stream(); -do spawn |move receiver| { // Bidirectionally linked +do spawn { // Bidirectionally linked // Wait for the supervised child task to exist. let message = receiver.recv(); // Kill both it and the parent task. assert message != 42; } -do try |move sender| { // Unidirectionally linked +do try { // Unidirectionally linked sender.send(42); sleep_forever(); // Will get woken up by force } @@ -432,7 +432,7 @@ do task::spawn_supervised { // Intermediate task immediately exits } wait_for_a_while(); -die!(); // Will kill grandchild even if child has already exited +fail!(); // Will kill grandchild even if child has already exited # }; ~~~ @@ -446,10 +446,10 @@ other at all, using `task::spawn_unlinked` for _isolated failure_. let (time1, time2) = (random(), random()); do task::spawn_unlinked { sleep_for(time2); // Won't get forced awake - die!(); + fail!(); } sleep_for(time1); // Won't get forced awake -die!(); +fail!(); // It will take MAX(time1,time2) for the program to finish. # }; ~~~ @@ -468,7 +468,7 @@ Here is the function that implements the child task: ~~~~ # use std::comm::DuplexStream; -# use pipes::{Port, Chan}; +# use comm::{Port, Chan}; fn stringifier(channel: &DuplexStream<~str, uint>) { let mut value: uint; loop { @@ -491,7 +491,7 @@ Here is the code for the parent task: ~~~~ # use std::comm::DuplexStream; -# use pipes::{Port, Chan}; +# use comm::{Port, Chan}; # use task::spawn; # fn stringifier(channel: &DuplexStream<~str, uint>) { # let mut value: uint; @@ -505,7 +505,7 @@ Here is the code for the parent task: let (from_child, to_child) = DuplexStream(); -do spawn |move to_child| { +do spawn { stringifier(&to_child); }; diff --git a/doc/tutorial.md b/doc/tutorial.md index a825b7f535f72..41895ebed7c59 100644 --- a/doc/tutorial.md +++ b/doc/tutorial.md @@ -114,8 +114,9 @@ for more information on them. When complete, `make install` will place several programs into `/usr/local/bin`: `rustc`, the Rust compiler; `rustdoc`, the -API-documentation tool; `cargo`, the Rust package manager; -and `rusti`, the Rust REPL. +API-documentation tool; `rustpkg`, the Rust package manager; +`rusti`, the Rust REPL; and `rust`, a tool which acts both as a unified +interface for them, and for a few common command line scenarios. [wiki-start]: https://github.com/mozilla/rust/wiki/Note-getting-started-developing-Rust [tarball]: http://static.rust-lang.org/dist/rust-0.5.tar.gz @@ -154,6 +155,22 @@ declaration to appear at the top level of the file: all statements must live inside a function. Rust programs can also be compiled as libraries, and included in other programs. +## Using the rust tool + +While using `rustc` directly to generate your executables, and then +running them manually is a perfectly valid way to test your code, +for smaller projects, prototypes, or if you're a beginner, it might be +more convenient to use the `rust` tool. + +The `rust` tool provides central access to the other rust tools, +as well as handy shortcuts for directly running source files. +For example, if you have a file `foo.rs` in your current directory, +`rust run foo.rs` would attempt to compile it and, if successful, +directly run the resulting binary. + +To get a list of all available commands, simply call `rust` without any +argument. + ## Editing Rust code There are vim highlighting and indentation scripts in the Rust source @@ -1260,7 +1277,7 @@ Moving it into a mutable slot makes the elements assignable. let crayons: ~[Crayon] = ~[BananaMania, Beaver, Bittersweet]; // Put the vector into a mutable slot -let mut mutable_crayons = move crayons; +let mut mutable_crayons = crayons; // Now it's mutable to the bone mutable_crayons[0] = Apricot; @@ -2055,12 +2072,12 @@ on values of type `T` inside the function. It will also cause a compile-time error when anyone tries to call `print_all` on an array whose element type does not have a `Printable` implementation. -Type parameters can have multiple bounds by separating them with spaces, +Type parameters can have multiple bounds by separating them with `+`, as in this version of `print_all` that copies elements. ~~~ # trait Printable { fn print(&self); } -fn print_all(printable_things: ~[T]) { +fn print_all(printable_things: ~[T]) { let mut i = 0; while i < printable_things.len() { let copy_of_thing = printable_things[i]; @@ -2184,7 +2201,7 @@ impl Circle for CircleStruct { } impl Shape for CircleStruct { fn area(&self) -> float { pi * square(self.radius) } -} +} ~~~~ Notice that methods of `Circle` can call methods on `Shape`, as our diff --git a/man/rustc.1 b/man/rustc.1 index bb6457dd493e7..14d2cad86d017 100644 --- a/man/rustc.1 +++ b/man/rustc.1 @@ -1,9 +1,9 @@ -.TH RUSTC "1" "October 2012" "rustc 0.4" "User Commands" +.TH RUSTC "1" "February 2013" "rustc 0.6" "User Commands" .SH NAME rustc \- rust compiler .SH SYNOPSIS .B rustc -[\fIoptions\fR] \fI\fR +[\fIOPTIONS\fR] \fIINPUT\fR .SH DESCRIPTION This program is a compiler for the Rust language, available at @@ -18,88 +18,134 @@ Compile an executable crate (default) \fB\-c\fR Compile and assemble, but do not link .TP -\fB\-\-cfg\fR +\fB\-\-cfg\fR SPEC Configure the compilation environment .TP \fB\-\-emit\-llvm\fR Produce an LLVM bitcode file .TP -\fB\-g\fR -Produce debug info (experimental) -.TP -\fB\-\-gc\fR -Garbage collect shared data (experimental/temporary) -.TP -\fB\-h\fR \fB\-\-help\fR +\fB\-h\fR, \fB\-\-help\fR Display this message .TP -\fB\-L\fR +\fB\-L\fR PATH Add a directory to the library search path .TP \fB\-\-lib\fR Compile a library crate .TP \fB\-\-ls\fR -List the symbols defined by a compiled library crate -.TP -\fB\-\-jit\fR -Execute using JIT (experimental) +List the symbols defined by a library crate .TP \fB\-\-no\-trans\fR Run all passes except translation; no output .TP \fB\-O\fR -Equivalent to \fB\-\-opt\-level\fR=\fI2\fR +Equivalent to \fI\-\-opt\-level=2\fR .TP -\fB\-o\fR +\fB\-o\fR FILENAME Write output to .TP -\fB\-\-opt\-level\fR -Optimize with possible levels 0\-3 +\fB\-\-opt\-level\fR LEVEL +Optimize with possible levels 0-3 .TP -\fB\-\-out\-dir\fR -Write output to compiler\-chosen filename in +\fB\-\-out\-dir\fR DIR +Write output to compiler-chosen filename in .TP \fB\-\-parse\-only\fR Parse only; do not compile, assemble, or link .TP -\fB\-\-pretty\fR [type] -Pretty\-print the input instead of compiling; -valid types are: normal (un\-annotated source), -expanded (crates expanded), typed (crates expanded, -with type annotations), or identified (fully -parenthesized, AST nodes and blocks with IDs) +\fB\-\-pretty\fR [TYPE] +Pretty-print the input instead of compiling; valid types are: normal +(un-annotated source), expanded (crates expanded), typed (crates +expanded, with type annotations), or identified (fully parenthesized, +AST nodes and blocks with IDs) .TP \fB\-S\fR Compile only; do not assemble or link .TP \fB\-\-save\-temps\fR -Write intermediate files (.bc, .opt.bc, .o) -in addition to normal output +Write intermediate files (.bc, .opt.bc, .o) in addition to normal output .TP -\fB\-\-static\fR -Use or produce static libraries or binaries -(experimental) -.TP -\fB\-\-sysroot\fR +\fB\-\-sysroot\fR PATH Override the system root .TP \fB\-\-test\fR Build a test harness .TP -\fB\-\-target\fR -Target cpu\-manufacturer\-kernel[\-os] to compile for -(default: host triple) -(see http://sources.redhat.com/autobook/autobook/ -autobook_17.html for detail) +\fB\-\-target\fR TRIPLE +Target triple cpu-manufacturer-kernel[-os] to compile for (see +http://sources.redhat.com/autobook/autobook/autobook_17.html +for detail) .TP -\fB\-W help\fR +\fB\-W\fR help Print 'lint' options and default settings .TP -\fB\-Z help\fR -Print internal options for debugging rustc +\fB\-W\fR OPT, \fB\-\-warn\fR OPT +Set lint warnings +.TP +\fB\-A\fR OPT, \fB\-\-allow\fR OPT +Set lint allowed .TP -\fB\-v\fR \fB\-\-version\fR +\fB\-D\fR OPT, \fB\-\-deny\fR OPT +Set lint denied +.TP +\fB\-F\fR OPT, \fB\-\-forbid\fR OPT +Set lint forbidden +.TP +\fB\-Z\fR FLAG +Set internal debugging options. Use "-Z help" to print available options. + +Available debug flags are: +.RS +.IP \[bu] +\fBverbose\fR - in general, enable more debug printouts +.IP \[bu] +\fBtime\-passes\fR - measure time of each rustc pass +.IP \[bu] +\fBcount\-llvm\-insns\fR - count where LLVM instrs originate +.IP \[bu] +\fBtime\-llvm\-passes\fR - measure time of each LLVM pass +.IP \[bu] +\fBtrans\-stats\fR - gather trans statistics +.IP \[bu] +\fBno\-asm\-comments\fR - omit comments when using \fI\-S\fR +.IP \[bu] +\fBno\-verify\fR - skip LLVM verification +.IP \[bu] +\fBtrace\fR - emit trace logs +.IP \[bu] +\fBcoherence\fR - perform coherence checking +.IP \[bu] +\fBborrowck\-stats\fR - gather borrowck statistics +.IP \[bu] +\fBborrowck\-note\-pure\fR - note where purity is req'd +.IP \[bu] +\fBborrowck\-note\-loan\fR - note where loans are req'd +.IP \[bu] +\fBno\-landing\-pads\fR - omit landing pads for unwinding +.IP \[bu] +\fBdebug\-llvm\fR - enable debug output from LLVM +.IP \[bu] +\fBcount\-type\-sizes\fR - count the sizes of aggregate types +.IP \[bu] +\fBmeta\-stats\fR - gather metadata statistics +.IP \[bu] +\fBno\-opt\fR - do not optimize, even if \fI\-O\fR is passed +.IP \[bu] +\fBno\-monomorphic\-collapse\fR - do not collapse template instantiations +.IP \[bu] +\fBgc\fR - Garbage collect shared data (experimental) +.IP \[bu] +\fBjit\fR - Execute using JIT (experimental) +.IP \[bu] +\fBextra\-debug\-info\fR - Extra debugging info (experimental) +.IP \[bu] +\fBdebug\-info\fR - Produce debug info (experimental) +.IP \[bu] +\fBstatic\fR - Use or produce static libraries or binaries (experimental) +.RE +.TP +\fB\-v\fR, \fB\-\-version\fR Print version info and exit .SH "EXAMPLES" @@ -112,6 +158,10 @@ To build a library from a source file: To build either with a crate (.rc) file: $ rustc hello.rc +To build an executable with debug info (experimental): + $ rustc -Z debug-info -o hello hello.rs + + .SH "BUGS" See <\fBhttps://github.com/mozilla/rust/issues\fR> for issues. diff --git a/mk/clean.mk b/mk/clean.mk index 57c14b0afc8a2..f02e2427a0c96 100644 --- a/mk/clean.mk +++ b/mk/clean.mk @@ -64,12 +64,13 @@ define CLEAN_HOST_STAGE_N clean$(1)_H_$(2): $(Q)rm -f $$(HBIN$(1)_H_$(2))/rustc$(X) $(Q)rm -f $$(HBIN$(1)_H_$(2))/fuzzer$(X) - $(Q)rm -f $$(HBIN$(1)_H_$(2))/cargo$(X) + $(Q)rm -f $$(HBIN$(1)_H_$(2))/rustpkg$(X) $(Q)rm -f $$(HBIN$(1)_H_$(2))/serializer$(X) $(Q)rm -f $$(HBIN$(1)_H_$(2))/rustdoc$(X) $(Q)rm -f $$(HBIN$(1)_H_$(2))/rusti$(X) + $(Q)rm -f $$(HBIN$(1)_H_$(2))/rust$(X) $(Q)rm -f $$(HLIB$(1)_H_$(2))/$(CFG_LIBFUZZER) - $(Q)rm -f $$(HLIB$(1)_H_$(2))/$(CFG_LIBCARGO) + $(Q)rm -f $$(HLIB$(1)_H_$(2))/$(CFG_LIBRUSTPKG) $(Q)rm -f $$(HLIB$(1)_H_$(2))/$(CFG_LIBRUSTDOC) $(Q)rm -f $$(HLIB$(1)_H_$(2))/$(CFG_RUNTIME) $(Q)rm -f $$(HLIB$(1)_H_$(2))/$(CFG_CORELIB) @@ -77,14 +78,16 @@ clean$(1)_H_$(2): $(Q)rm -f $$(HLIB$(1)_H_$(2))/$(CFG_LIBRUSTC) $(Q)rm -f $$(HLIB$(1)_H_$(2))/$(CFG_LIBSYNTAX) $(Q)rm -f $$(HLIB$(1)_H_$(2))/$(CFG_LIBRUSTI) + $(Q)rm -f $$(HLIB$(1)_H_$(2))/$(CFG_LIBRUST) $(Q)rm -f $$(HLIB$(1)_H_$(2))/$(CORELIB_GLOB) $(Q)rm -f $$(HLIB$(1)_H_$(2))/$(STDLIB_GLOB) $(Q)rm -f $$(HLIB$(1)_H_$(2))/$(LIBRUSTC_GLOB) $(Q)rm -f $$(HLIB$(1)_H_$(2))/$(LIBSYNTAX_GLOB) $(Q)rm -f $$(HLIB$(1)_H_$(2))/$(LIBFUZZER_GLOB) - $(Q)rm -f $$(HLIB$(1)_H_$(2))/$(LIBCARGO_GLOB) + $(Q)rm -f $$(HLIB$(1)_H_$(2))/$(LIBRUSTPKG_GLOB) $(Q)rm -f $$(HLIB$(1)_H_$(2))/$(LIBRUSTDOC_GLOB) $(Q)rm -f $$(HLIB$(1)_H_$(2))/$(LIBRUSTI_GLOB) + $(Q)rm -f $$(HLIB$(1)_H_$(2))/$(LIBRUST_GLOB) $(Q)rm -f $$(HLIB$(1)_H_$(2))/$(CFG_RUSTLLVM) $(Q)rm -f $$(HLIB$(1)_H_$(2))/libstd.rlib @@ -99,11 +102,11 @@ define CLEAN_TARGET_STAGE_N clean$(1)_T_$(2)_H_$(3): $(Q)rm -f $$(TBIN$(1)_T_$(2)_H_$(3))/rustc$(X) $(Q)rm -f $$(TBIN$(1)_T_$(2)_H_$(3))/fuzzer$(X) - $(Q)rm -f $$(TBIN$(1)_T_$(2)_H_$(3))/cargo$(X) + $(Q)rm -f $$(TBIN$(1)_T_$(2)_H_$(3))/rustpkg$(X) $(Q)rm -f $$(TBIN$(1)_T_$(2)_H_$(3))/serializer$(X) $(Q)rm -f $$(TBIN$(1)_T_$(2)_H_$(3))/rustdoc$(X) $(Q)rm -f $$(TLIB$(1)_T_$(2)_H_$(3))/$(CFG_LIBFUZZER) - $(Q)rm -f $$(TLIB$(1)_T_$(2)_H_$(3))/$(CFG_LIBCARGO) + $(Q)rm -f $$(TLIB$(1)_T_$(2)_H_$(3))/$(CFG_LIBRUSTPKG) $(Q)rm -f $$(TLIB$(1)_T_$(2)_H_$(3))/$(CFG_LIBRUSTDOC) $(Q)rm -f $$(TLIB$(1)_T_$(2)_H_$(3))/$(CFG_RUNTIME) $(Q)rm -f $$(TLIB$(1)_T_$(2)_H_$(3))/$(CFG_CORELIB) @@ -115,7 +118,7 @@ clean$(1)_T_$(2)_H_$(3): $(Q)rm -f $$(TLIB$(1)_T_$(2)_H_$(3))/$(LIBRUSTC_GLOB) $(Q)rm -f $$(TLIB$(1)_T_$(2)_H_$(3))/$(LIBSYNTAX_GLOB) $(Q)rm -f $$(TLIB$(1)_T_$(2)_H_$(3))/$(LIBFUZZER_GLOB) - $(Q)rm -f $$(TLIB$(1)_T_$(2)_H_$(3))/$(LIBCARGO_GLOB) + $(Q)rm -f $$(TLIB$(1)_T_$(2)_H_$(3))/$(LIBRUSTPKG_GLOB) $(Q)rm -f $$(TLIB$(1)_T_$(2)_H_$(3))/$(LIBRUSTDOC_GLOB) $(Q)rm -f $$(TLIB$(1)_T_$(2)_H_$(3))/$(CFG_RUSTLLVM) $(Q)rm -f $$(TLIB$(1)_T_$(2)_H_$(3))/libstd.rlib diff --git a/mk/dist.mk b/mk/dist.mk index dd9b201170781..3684b9c45441f 100644 --- a/mk/dist.mk +++ b/mk/dist.mk @@ -25,8 +25,9 @@ PKG_FILES := \ $(addprefix $(S)src/, \ README.txt \ driver \ - libcargo \ + librustpkg \ librusti \ + librust \ librustc \ compiletest \ etc \ diff --git a/mk/install.mk b/mk/install.mk index 555b28e96976b..ebbe5f007f157 100644 --- a/mk/install.mk +++ b/mk/install.mk @@ -55,11 +55,13 @@ install-target-$(1)-host-$(2): $$(CSREQ$$(ISTAGE)_T_$(1)_H_$(2)) $$(Q)$$(call INSTALL_LIB, \ $$(TL$(1)$(2)),$$(PTL$(1)$(2)),$$(LIBSYNTAX_GLOB)) $$(Q)$$(call INSTALL_LIB, \ - $$(TL$(1)$(2)),$$(PTL$(1)$(2)),$$(LIBCARGO_GLOB)) + $$(TL$(1)$(2)),$$(PTL$(1)$(2)),$$(LIBRUSTPKG_GLOB)) $$(Q)$$(call INSTALL_LIB, \ $$(TL$(1)$(2)),$$(PTL$(1)$(2)),$$(LIBRUSTDOC_GLOB)) $$(Q)$$(call INSTALL_LIB, \ $$(TL$(1)$(2)),$$(PTL$(1)$(2)),$$(LIBRUSTI_GLOB)) + $$(Q)$$(call INSTALL_LIB, \ + $$(TL$(1)$(2)),$$(PTL$(1)$(2)),$$(LIBRUST_GLOB)) $$(Q)$$(call INSTALL,$$(TL$(1)$(2)),$$(PTL$(1)$(2)),libmorestack.a) endef @@ -87,18 +89,21 @@ install-host: $(CSREQ$(ISTAGE)_T_$(CFG_HOST_TRIPLE)_H_$(CFG_HOST_TRIPLE)) $(Q)mkdir -p $(PREFIX_LIB) $(Q)mkdir -p $(PREFIX_ROOT)/share/man/man1 $(Q)$(call INSTALL,$(HB2),$(PHB),rustc$(X)) - $(Q)$(call INSTALL,$(HB2),$(PHB),cargo$(X)) + $(Q)$(call INSTALL,$(HB2),$(PHB),rustpkg$(X)) $(Q)$(call INSTALL,$(HB2),$(PHB),rustdoc$(X)) $(Q)$(call INSTALL,$(HB2),$(PHB),rusti$(X)) + $(Q)$(call INSTALL,$(HB2),$(PHB),rust$(X)) $(Q)$(call INSTALL,$(HL),$(PHL),$(CFG_LIBRUSTC)) - $(Q)$(call INSTALL,$(HL),$(PHL),$(CFG_LIBCARGO)) + $(Q)$(call INSTALL,$(HL),$(PHL),$(CFG_LIBRUSTPKG)) $(Q)$(call INSTALL,$(HL),$(PHL),$(CFG_LIBRUSTDOC)) $(Q)$(call INSTALL,$(HL),$(PHL),$(CFG_LIBRUSTI)) + $(Q)$(call INSTALL,$(HL),$(PHL),$(CFG_LIBRUST)) $(Q)$(call INSTALL_LIB,$(HL),$(PHL),$(CORELIB_GLOB)) $(Q)$(call INSTALL_LIB,$(HL),$(PHL),$(STDLIB_GLOB)) $(Q)$(call INSTALL_LIB,$(HL),$(PHL),$(LIBRUSTC_GLOB)) $(Q)$(call INSTALL_LIB,$(HL),$(PHL),$(LIBSYNTAX_GLOB)) $(Q)$(call INSTALL_LIB,$(HL),$(PHL),$(LIBRUSTI_GLOB)) + $(Q)$(call INSTALL_LIB,$(HL),$(PHL),$(LIBRUST_GLOB)) $(Q)$(call INSTALL,$(HL),$(PHL),$(CFG_RUNTIME)) $(Q)$(call INSTALL,$(HL),$(PHL),$(CFG_RUSTLLVM)) $(Q)$(call INSTALL,$(S)/man, \ @@ -112,23 +117,26 @@ HOST_LIB_FROM_HL_GLOB = \ uninstall: $(Q)rm -f $(PHB)/rustc$(X) - $(Q)rm -f $(PHB)/cargo$(X) + $(Q)rm -f $(PHB)/rustpkg$(X) $(Q)rm -f $(PHB)/rusti$(X) + $(Q)rm -f $(PHB)/rust$(X) $(Q)rm -f $(PHB)/rustdoc$(X) $(Q)rm -f $(PHL)/$(CFG_RUSTLLVM) - $(Q)rm -f $(PHL)/$(CFG_LIBCARGO) + $(Q)rm -f $(PHL)/$(CFG_LIBRUSTPKG) $(Q)rm -f $(PHL)/$(CFG_LIBRUSTC) $(Q)rm -f $(PHL)/$(CFG_LIBRUSTDOC) $(Q)rm -f $(PHL)/$(CFG_LIBRUSTI) + $(Q)rm -f $(PHL)/$(CFG_LIBRUST) $(Q)rm -f $(PHL)/$(CFG_RUNTIME) $(Q)for i in \ $(call HOST_LIB_FROM_HL_GLOB,$(CORELIB_GLOB)) \ $(call HOST_LIB_FROM_HL_GLOB,$(STDLIB_GLOB)) \ $(call HOST_LIB_FROM_HL_GLOB,$(LIBRUSTC_GLOB)) \ $(call HOST_LIB_FROM_HL_GLOB,$(LIBSYNTAX_GLOB)) \ - $(call HOST_LIB_FROM_HL_GLOB,$(LIBCARGO_GLOB)) \ + $(call HOST_LIB_FROM_HL_GLOB,$(LIBRUSTPKG_GLOB)) \ $(call HOST_LIB_FROM_HL_GLOB,$(LIBRUSTDOC_GLOB)) \ $(call HOST_LIB_FROM_HL_GLOB,$(LIBRUSTI_GLOB)) \ + $(call HOST_LIB_FROM_HL_GLOB,$(LIBRUST_GLOB)) \ ; \ do rm -f $$i ; \ done diff --git a/mk/pp.mk b/mk/pp.mk index 4d8baa2ea32c2..653cabfce5f88 100644 --- a/mk/pp.mk +++ b/mk/pp.mk @@ -18,8 +18,9 @@ else $(wildcard $(S)src/test/*/*.rs \ $(S)src/test/*/*/*.rs) \ $(wildcard $(S)src/fuzzer/*.rs) \ - $(wildcard $(S)src/cargo/*.rs) \ - $(wildcard $(S)src/rusti/*.rs) + $(wildcard $(S)src/rustpkg/*.rs) \ + $(wildcard $(S)src/rusti/*.rs) \ + $(wildcard $(S)src/rust/*.rs) PP_INPUTS_FILTERED = $(shell echo $(PP_INPUTS) | xargs grep -L \ "no-reformat\|xfail-pretty\|xfail-test") diff --git a/mk/rt.mk b/mk/rt.mk index 23dc64dbca52e..e6e0f1e0cd759 100644 --- a/mk/rt.mk +++ b/mk/rt.mk @@ -50,6 +50,7 @@ RUNTIME_CXXS_$(1) := \ rt/rust_builtin.cpp \ rt/rust_run_program.cpp \ rt/rust_env.cpp \ + rt/rust_rng.cpp \ rt/rust_sched_loop.cpp \ rt/rust_sched_launcher.cpp \ rt/rust_sched_driver.cpp \ diff --git a/mk/tests.mk b/mk/tests.mk index abe9ba60ecda4..116f6ffe56804 100644 --- a/mk/tests.mk +++ b/mk/tests.mk @@ -14,7 +14,7 @@ ###################################################################### # The names of crates that must be tested -TEST_CRATES = core std syntax rustc rustdoc rusti cargo +TEST_CRATES = core std syntax rustc rustdoc rusti rust rustpkg # Markdown files under doc/ that should have their code extracted and run DOC_TEST_NAMES = tutorial tutorial-ffi tutorial-macros tutorial-borrowed-ptr tutorial-tasks rust @@ -229,8 +229,8 @@ $(3)/test/rustctest.stage$(1)-$(2)$$(X): \ @$$(call E, compile_and_link: $$@) $$(STAGE$(1)_T_$(2)_H_$(3)) -o $$@ $$< --test -$(3)/test/cargotest.stage$(1)-$(2)$$(X): \ - $$(CARGO_LIB) $$(CARGO_INPUTS) \ +$(3)/test/rustpkgtest.stage$(1)-$(2)$$(X): \ + $$(RUSTPKG_LIB) $$(RUSTPKG_INPUTS) \ $$(TLIB$(1)_T_$(2)_H_$(3))/$$(CFG_LIBRUSTC) @$$(call E, compile_and_link: $$@) $$(STAGE$(1)_T_$(2)_H_$(3)) -o $$@ $$< --test @@ -241,6 +241,12 @@ $(3)/test/rustitest.stage$(1)-$(2)$$(X): \ @$$(call E, compile_and_link: $$@) $$(STAGE$(1)_T_$(2)_H_$(3)) -o $$@ $$< --test +$(3)/test/rusttest.stage$(1)-$(2)$$(X): \ + $$(RUST_LIB) $$(RUST_INPUTS) \ + $$(TLIB$(1)_T_$(2)_H_$(3))/$$(CFG_LIBRUSTC) + @$$(call E, compile_and_link: $$@) + $$(STAGE$(1)_T_$(2)_H_$(3)) -o $$@ $$< --test + $(3)/test/rustdoctest.stage$(1)-$(2)$$(X): \ $$(RUSTDOC_LIB) $$(RUSTDOC_INPUTS) \ $$(TLIB$(1)_T_$(2)_H_$(3))/$$(CFG_LIBRUSTC) @@ -464,20 +470,20 @@ $(foreach host,$(CFG_TARGET_TRIPLES), \ define DEF_RUN_DOC_TEST -DOC_TEST_ARGS$(1)-T-$(2)-H-$(3)-$(4) := \ +DOC_TEST_ARGS$(1)-T-$(2)-H-$(3)-doc-$(4) := \ $$(CTEST_COMMON_ARGS$(1)-T-$(2)-H-$(3)) \ --src-base $(3)/test/doc-$(4)/ \ --build-base $(3)/test/doc-$(4)/ \ --mode run-pass -check-stage$(1)-T-$(2)-H-$(3)-doc-$(4)-exec: $$(call TEST_OK_FILE,$(1),$(2),$(3),$(4)) +check-stage$(1)-T-$(2)-H-$(3)-doc-$(4)-exec: $$(call TEST_OK_FILE,$(1),$(2),$(3),doc-$(4)) -$$(call TEST_OK_FILE,$(1),$(2),$(3),$(4)): \ +$$(call TEST_OK_FILE,$(1),$(2),$(3),doc-$(4)): \ $$(TEST_SREQ$(1)_T_$(2)_H_$(3)) \ doc-$(4)-extract$(3) @$$(call E, run doc-$(4): $$<) $$(Q)$$(call CFG_RUN_CTEST,$(1),$$<,$(3)) \ - $$(DOC_TEST_ARGS$(1)-T-$(2)-H-$(3)-$(4)) \ + $$(DOC_TEST_ARGS$(1)-T-$(2)-H-$(3)-doc-$(4)) \ --logfile $$(call TEST_LOG_FILE,$(1),$(2),$(3),doc-$(4)) \ && touch $$@ diff --git a/mk/tools.mk b/mk/tools.mk index 31956eda24686..22f109be47feb 100644 --- a/mk/tools.mk +++ b/mk/tools.mk @@ -14,13 +14,13 @@ FUZZER_LIB := $(S)src/libfuzzer/fuzzer.rc FUZZER_INPUTS := $(wildcard $(addprefix $(S)src/libfuzzer/, *.rs)) -# The test runner that runs the cfail/rfail/rpass and bench tests +# The test runner that runs the cfail/rfail/rpass and bxench tests COMPILETEST_CRATE := $(S)src/compiletest/compiletest.rc COMPILETEST_INPUTS := $(wildcard $(S)src/compiletest/*rs) -# Cargo, the package manager -CARGO_LIB := $(S)src/libcargo/cargo.rc -CARGO_INPUTS := $(wildcard $(S)src/libcargo/*rs) +# Rustpkg, the package manager and build system +RUSTPKG_LIB := $(S)src/librustpkg/rustpkg.rc +RUSTPKG_INPUTS := $(wildcard $(S)src/librustpkg/*rs) # Rustdoc, the documentation tool RUSTDOC_LIB := $(S)src/librustdoc/rustdoc.rc @@ -30,6 +30,10 @@ RUSTDOC_INPUTS := $(wildcard $(S)src/librustdoc/*.rs) RUSTI_LIB := $(S)src/librusti/rusti.rc RUSTI_INPUTS := $(wildcard $(S)src/librusti/*.rs) +# Rust, the convenience tool +RUST_LIB := $(S)src/librust/rust.rc +RUST_INPUTS := $(wildcard $(S)src/librust/*.rs) + # FIXME: These are only built for the host arch. Eventually we'll # have tools that need to built for other targets. define TOOLS_STAGE_N_TARGET @@ -57,8 +61,8 @@ $$(TBIN$(1)_T_$(4)_H_$(3))/compiletest$$(X): \ @$$(call E, compile_and_link: $$@) $$(STAGE$(1)_T_$(4)_H_$(3)) -o $$@ $$< -$$(TLIB$(1)_T_$(4)_H_$(3))/$$(CFG_LIBCARGO): \ - $$(CARGO_LIB) $$(CARGO_INPUTS) \ +$$(TLIB$(1)_T_$(4)_H_$(3))/$$(CFG_LIBRUSTPKG): \ + $$(RUSTPKG_LIB) $$(RUSTPKG_INPUTS) \ $$(TSREQ$(1)_T_$(4)_H_$(3)) \ $$(TLIB$(1)_T_$(4)_H_$(3))/$$(CFG_CORELIB) \ $$(TLIB$(1)_T_$(4)_H_$(3))/$$(CFG_STDLIB) \ @@ -66,11 +70,11 @@ $$(TLIB$(1)_T_$(4)_H_$(3))/$$(CFG_LIBCARGO): \ @$$(call E, compile_and_link: $$@) $$(STAGE$(1)_T_$(4)_H_$(3)) -o $$@ $$< && touch $$@ -$$(TBIN$(1)_T_$(4)_H_$(3))/cargo$$(X): \ +$$(TBIN$(1)_T_$(4)_H_$(3))/rustpkg$$(X): \ $$(DRIVER_CRATE) \ - $$(TLIB$(1)_T_$(4)_H_$(3))/$$(CFG_LIBCARGO) + $$(TLIB$(1)_T_$(4)_H_$(3))/$$(CFG_LIBRUSTPKG) @$$(call E, compile_and_link: $$@) - $$(STAGE$(1)_T_$(4)_H_$(3)) --cfg cargo -o $$@ $$< + $$(STAGE$(1)_T_$(4)_H_$(3)) --cfg rustpkg -o $$@ $$< $$(TLIB$(1)_T_$(4)_H_$(3))/$$(CFG_LIBRUSTDOC): \ $$(RUSTDOC_LIB) $$(RUSTDOC_INPUTS) \ @@ -102,6 +106,21 @@ $$(TBIN$(1)_T_$(4)_H_$(3))/rusti$$(X): \ @$$(call E, compile_and_link: $$@) $$(STAGE$(1)_T_$(4)_H_$(3)) --cfg rusti -o $$@ $$< +$$(TLIB$(1)_T_$(4)_H_$(3))/$$(CFG_LIBRUST): \ + $$(RUST_LIB) $$(RUST_INPUTS) \ + $$(TSREQ$(1)_T_$(4)_H_$(3)) \ + $$(TLIB$(1)_T_$(4)_H_$(3))/$$(CFG_CORELIB) \ + $$(TLIB$(1)_T_$(4)_H_$(3))/$$(CFG_STDLIB) \ + $$(TLIB$(1)_T_$(4)_H_$(3))/$$(CFG_LIBRUSTC) + @$$(call E, compile_and_link: $$@) + $$(STAGE$(1)_T_$(4)_H_$(3)) -o $$@ $$< && touch $$@ + +$$(TBIN$(1)_T_$(4)_H_$(3))/rust$$(X): \ + $$(DRIVER_CRATE) \ + $$(TLIB$(1)_T_$(4)_H_$(3))/$$(CFG_LIBRUST) + @$$(call E, compile_and_link: $$@) + $$(STAGE$(1)_T_$(4)_H_$(3)) --cfg rust -o $$@ $$< + endef define TOOLS_STAGE_N_HOST @@ -134,19 +153,19 @@ $$(HBIN$(2)_H_$(4))/compiletest$$(X): \ $$(Q)cp $$< $$@ -$$(HLIB$(2)_H_$(4))/$$(CFG_LIBCARGO): \ - $$(TLIB$(1)_T_$(4)_H_$(3))/$$(CFG_LIBCARGO) \ +$$(HLIB$(2)_H_$(4))/$$(CFG_LIBRUSTPKG): \ + $$(TLIB$(1)_T_$(4)_H_$(3))/$$(CFG_LIBRUSTPKG) \ $$(HLIB$(2)_H_$(4))/$$(CFG_LIBRUSTC) \ $$(HSREQ$(2)_H_$(4)) @$$(call E, cp: $$@) $$(Q)cp $$< $$@ - $$(Q)cp -R $$(TLIB$(1)_T_$(4)_H_$(3))/$(LIBCARGO_GLOB) \ - $$(wildcard $$(TLIB$(1)_T_$(4)_H_$(3))/$(LIBCARGO_DSYM_GLOB)) \ + $$(Q)cp -R $$(TLIB$(1)_T_$(4)_H_$(3))/$(LIBRUSTPKG_GLOB) \ + $$(wildcard $$(TLIB$(1)_T_$(4)_H_$(3))/$(LIBRUSTPKG_DSYM_GLOB)) \ $$(HLIB$(2)_H_$(4)) -$$(HBIN$(2)_H_$(4))/cargo$$(X): \ - $$(TBIN$(1)_T_$(4)_H_$(3))/cargo$$(X) \ - $$(HLIB$(2)_H_$(4))/$$(CFG_LIBCARGO) \ +$$(HBIN$(2)_H_$(4))/rustpkg$$(X): \ + $$(TBIN$(1)_T_$(4)_H_$(3))/rustpkg$$(X) \ + $$(HLIB$(2)_H_$(4))/$$(CFG_LIBRUSTPKG) \ $$(HSREQ$(2)_H_$(4)) @$$(call E, cp: $$@) $$(Q)cp $$< $$@ @@ -185,6 +204,23 @@ $$(HBIN$(2)_H_$(4))/rusti$$(X): \ @$$(call E, cp: $$@) $$(Q)cp $$< $$@ +$$(HLIB$(2)_H_$(4))/$$(CFG_LIBRUST): \ + $$(TLIB$(1)_T_$(4)_H_$(3))/$$(CFG_LIBRUST) \ + $$(HLIB$(2)_H_$(4))/$$(CFG_LIBRUSTC) \ + $$(HSREQ$(2)_H_$(4)) + @$$(call E, cp: $$@) + $$(Q)cp $$< $$@ + $$(Q)cp -R $$(TLIB$(1)_T_$(4)_H_$(3))/$(LIBRUST_GLOB) \ + $$(wildcard $$(TLIB$(1)_T_$(4)_H_$(3))/$(LIBRUST_DSYM_GLOB)) \ + $$(HLIB$(2)_H_$(4)) + +$$(HBIN$(2)_H_$(4))/rust$$(X): \ + $$(TBIN$(1)_T_$(4)_H_$(3))/rust$$(X) \ + $$(HLIB$(2)_H_$(4))/$$(CFG_LIBRUST) \ + $$(HSREQ$(2)_H_$(4)) + @$$(call E, cp: $$@) + $$(Q)cp $$< $$@ + endef $(foreach host,$(CFG_TARGET_TRIPLES), \ diff --git a/src/README.txt b/src/README.txt index c8029098cfaf4..1b06c4259fc6f 100644 --- a/src/README.txt +++ b/src/README.txt @@ -29,7 +29,7 @@ test/auxiliary - Dependencies of tests compiletest/ The test runner -libcargo/ The package manager +librustpkg/ The package manager and build system librusti/ The JIT REPL diff --git a/src/compiletest/common.rs b/src/compiletest/common.rs index 679f9ab93bf08..0facf9d63c340 100644 --- a/src/compiletest/common.rs +++ b/src/compiletest/common.rs @@ -21,7 +21,7 @@ pub enum mode { mode_debug_info, } -pub type config = { +pub struct config { // The library paths required for running the compiler compile_lib_path: ~str, @@ -68,4 +68,4 @@ pub type config = { // Explain what's going on verbose: bool -}; +} diff --git a/src/compiletest/compiletest.rc b/src/compiletest/compiletest.rc index 5557b1131766b..6748edb9dbdf8 100644 --- a/src/compiletest/compiletest.rc +++ b/src/compiletest/compiletest.rc @@ -11,7 +11,6 @@ #[crate_type = "bin"]; #[no_core]; -#[legacy_records]; #[allow(vecs_implicitly_copyable)]; #[allow(non_camel_case_types)]; @@ -77,26 +76,28 @@ pub fn parse_config(args: ~[~str]) -> config { Path(getopts::opt_str(m, nm)) } - return {compile_lib_path: getopts::opt_str(matches, ~"compile-lib-path"), - run_lib_path: getopts::opt_str(matches, ~"run-lib-path"), - rustc_path: opt_path(matches, ~"rustc-path"), - src_base: opt_path(matches, ~"src-base"), - build_base: opt_path(matches, ~"build-base"), - aux_base: opt_path(matches, ~"aux-base"), - stage_id: getopts::opt_str(matches, ~"stage-id"), - mode: str_mode(getopts::opt_str(matches, ~"mode")), - run_ignored: getopts::opt_present(matches, ~"ignored"), - filter: + config { + compile_lib_path: getopts::opt_str(matches, ~"compile-lib-path"), + run_lib_path: getopts::opt_str(matches, ~"run-lib-path"), + rustc_path: opt_path(matches, ~"rustc-path"), + src_base: opt_path(matches, ~"src-base"), + build_base: opt_path(matches, ~"build-base"), + aux_base: opt_path(matches, ~"aux-base"), + stage_id: getopts::opt_str(matches, ~"stage-id"), + mode: str_mode(getopts::opt_str(matches, ~"mode")), + run_ignored: getopts::opt_present(matches, ~"ignored"), + filter: if vec::len(matches.free) > 0u { option::Some(matches.free[0]) } else { option::None }, - logfile: option::map(&getopts::opt_maybe_str(matches, + logfile: option::map(&getopts::opt_maybe_str(matches, ~"logfile"), - |s| Path(*s)), - runtool: getopts::opt_maybe_str(matches, ~"runtool"), - rustcflags: getopts::opt_maybe_str(matches, ~"rustcflags"), - jit: getopts::opt_present(matches, ~"jit"), - verbose: getopts::opt_present(matches, ~"verbose")}; + |s| Path(*s)), + runtool: getopts::opt_maybe_str(matches, ~"runtool"), + rustcflags: getopts::opt_maybe_str(matches, ~"rustcflags"), + jit: getopts::opt_present(matches, ~"jit"), + verbose: getopts::opt_present(matches, ~"verbose") + } } pub fn log_config(config: config) { @@ -177,7 +178,7 @@ pub fn make_tests(config: config) -> ~[test::TestDescAndFn] { tests.push(make_test(config, file)) } } - move tests + tests } pub fn is_test(config: config, testfile: &Path) -> bool { diff --git a/src/compiletest/procsrv.rs b/src/compiletest/procsrv.rs index 304266f0f7966..6c8bd7ea44269 100644 --- a/src/compiletest/procsrv.rs +++ b/src/compiletest/procsrv.rs @@ -76,14 +76,14 @@ pub fn run(lib_path: ~str, writeclose(pipe_in.out, input); - let p = pipes::PortSet(); + let p = comm::PortSet(); let ch = p.chan(); - do task::spawn_sched(task::SingleThreaded) |move ch| { + do task::spawn_sched(task::SingleThreaded) || { let errput = readclose(pipe_err.in); ch.send((2, errput)); } let ch = p.chan(); - do task::spawn_sched(task::SingleThreaded) |move ch| { + do task::spawn_sched(task::SingleThreaded) || { let output = readclose(pipe_out.in); ch.send((1, output)); } diff --git a/src/compiletest/runtest.rs b/src/compiletest/runtest.rs index fe03ccbb3f8e8..3213a11cbb51c 100644 --- a/src/compiletest/runtest.rs +++ b/src/compiletest/runtest.rs @@ -570,7 +570,8 @@ fn make_run_args(config: config, _props: TestProps, testfile: &Path) -> }; let args = toolargs + ~[make_exe_name(config, testfile).to_str()]; - return ProcArgs {prog: args[0], args: vec::slice(args, 1, args.len())}; + return ProcArgs {prog: args[0], + args: vec::slice(args, 1, args.len()).to_vec()}; } fn split_maybe_args(argstr: Option<~str>) -> ~[~str] { diff --git a/src/driver/driver.rs b/src/driver/driver.rs index 0c1cc566fe2ec..2fc50eb6e7579 100644 --- a/src/driver/driver.rs +++ b/src/driver/driver.rs @@ -11,8 +11,8 @@ #[no_core]; extern mod core(vers = "0.6"); -#[cfg(cargo)] -extern mod this(name = "cargo", vers = "0.6"); +#[cfg(rustpkg)] +extern mod this(name = "rustpkg", vers = "0.6"); #[cfg(fuzzer)] extern mod this(name = "fuzzer", vers = "0.6"); @@ -23,6 +23,9 @@ extern mod this(name = "rustdoc", vers = "0.6"); #[cfg(rusti)] extern mod this(name = "rusti", vers = "0.6"); +#[cfg(rust)] +extern mod this(name = "rust", vers = "0.6"); + #[cfg(rustc)] extern mod this(name = "rustc", vers = "0.6"); diff --git a/src/etc/emacs/rust-mode.el b/src/etc/emacs/rust-mode.el index ef98fa669e346..5fbd2ab67c29d 100644 --- a/src/etc/emacs/rust-mode.el +++ b/src/etc/emacs/rust-mode.el @@ -7,7 +7,6 @@ (require 'cm-mode) (require 'cc-mode) -(eval-when-compile (require 'cl)) (defun rust-electric-brace (arg) (interactive "*P") @@ -17,6 +16,12 @@ '(font-lock-comment-face font-lock-string-face)))) (cm-indent))) +(defcustom rust-capitalized-idents-are-types t + "If non-nil, capitalized identifiers will be treated as types for the purposes of font-lock mode" + :type 'boolean + :require 'rust-mode + :group 'rust-mode) + (defvar rust-indent-unit 4) (defvar rust-syntax-table (let ((table (make-syntax-table))) (c-populate-syntax-table table) @@ -101,14 +106,7 @@ (rust-push-context st 'string (current-column) t) (setf (rust-state-tokenize st) 'rust-token-string) (rust-token-string st)) - (def ?\' (forward-char) - (setf rust-tcat 'atom) - (let ((is-escape (eq (char-after) ?\\)) - (start (point))) - (if (not (rust-eat-until-unescaped ?\')) - 'font-lock-warning-face - (if (or is-escape (= (point) (+ start 2))) - 'font-lock-string-face 'font-lock-warning-face)))) + (def ?\' (rust-single-quote)) (def ?/ (forward-char) (case (char-after) (?/ (end-of-line) 'font-lock-comment-face) @@ -122,12 +120,7 @@ ((rust-eat-re "[a-z_]+") (setf rust-tcat 'macro))) 'font-lock-preprocessor-face) (def ((?a . ?z) (?A . ?Z) ?_) - (rust-eat-re "[a-zA-Z_][a-zA-Z0-9_]*") - (setf rust-tcat 'ident) - (if (and (eq (char-after) ?:) (eq (char-after (+ (point) 1)) ?:) - (not (eq (char-after (+ (point) 2)) ?:))) - (progn (forward-char 2) 'font-lock-builtin-face) - (match-string 0))) + (rust-token-identifier)) (def ((?0 . ?9)) (rust-eat-re "0x[0-9a-fA-F_]+\\|0b[01_]+\\|[0-9_]+\\(\\.[0-9_]+\\)?\\(e[+\\-]?[0-9_]+\\)?") (setf rust-tcat 'atom) @@ -150,6 +143,31 @@ (setf rust-tcat 'op) nil) table))) +(defun rust-token-identifier () + (rust-eat-re "[a-zA-Z_][a-zA-Z0-9_]*") + (setf rust-tcat 'ident) + (if (and (eq (char-after) ?:) (eq (char-after (+ (point) 1)) ?:) + (not (eq (char-after (+ (point) 2)) ?:))) + (progn (forward-char 2) 'font-lock-builtin-face) + (match-string 0))) + +(defun rust-single-quote () + (forward-char) + (setf rust-tcat 'atom) + ; Is this a lifetime? + (if (or (looking-at "[a-zA-Z_]$") + (looking-at "[a-zA-Z_][^']")) + ; If what we see is 'abc, use font-lock-builtin-face: + (progn (rust-eat-re "[a-zA-Z_][a-zA-Z_0-9]*") + 'font-lock-builtin-face) + ; Otherwise, handle as a character constant: + (let ((is-escape (eq (char-after) ?\\)) + (start (point))) + (if (not (rust-eat-until-unescaped ?\')) + 'font-lock-warning-face + (if (or is-escape (= (point) (+ start 2))) + 'font-lock-string-face 'font-lock-warning-face))))) + (defun rust-token-base (st) (funcall (char-table-range rust-char-table (char-after)) st)) @@ -190,6 +208,10 @@ (dolist (cx (rust-state-context st)) (when (eq (rust-context-type cx) ?\}) (return (rust-context-info cx))))) +(defun rust-is-capitalized (string) + (let ((case-fold-search nil)) + (string-match-p "[A-Z]" string))) + (defun rust-token (st) (let ((cx (car (rust-state-context st)))) (when (bolp) @@ -206,6 +228,8 @@ (setf tok (cond ((eq tok-id 'atom) 'font-lock-constant-face) (tok-id 'font-lock-keyword-face) ((equal (rust-state-last-token st) 'def) 'font-lock-function-name-face) + ((and rust-capitalized-idents-are-types + (rust-is-capitalized tok)) 'font-lock-type-face) (t nil)))) (when rust-tcat (when (eq (rust-context-align cx) 'unset) diff --git a/src/etc/licenseck.py b/src/etc/licenseck.py index 5e53eef7ef2b8..973b7deb960db 100644 --- a/src/etc/licenseck.py +++ b/src/etc/licenseck.py @@ -8,7 +8,8 @@ # option. This file may not be copied, modified, or distributed # except according to those terms. -license0 = """// Copyright 2012-2013 The Rust Project Developers. See the +license0 = """\ +// 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. // @@ -19,7 +20,8 @@ // except according to those terms. """ -license1 = """// Copyright 2012 The Rust Project Developers. See the COPYRIGHT +license1 = """\ +// 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. // @@ -30,7 +32,8 @@ // except according to those terms. """ -license2 = """// Copyright 2013 The Rust Project Developers. See the COPYRIGHT +license2 = """\ +// 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. // @@ -41,7 +44,8 @@ // except according to those terms. """ -license3 = """# Copyright 2013 The Rust Project Developers. See the COPYRIGHT +license3 = """\ +# 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. # @@ -52,7 +56,19 @@ # except according to those terms. """ -licenses = [license0, license1, license2, license3] +license4 = """\ +// 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. +""" + +licenses = [license0, license1, license2, license3, license4] exceptions = [ "rt/rust_android_dummy.cpp", # BSD, chromium diff --git a/src/etc/vim/after/ftplugin/rust.vim b/src/etc/vim/after/ftplugin/rust.vim new file mode 100644 index 0000000000000..56616de6aa84d --- /dev/null +++ b/src/etc/vim/after/ftplugin/rust.vim @@ -0,0 +1,5 @@ +"Highlight the 78th text column +"Feature became available in v7.3 +if version >= 703 + set colorcolumn=78 +endif diff --git a/src/etc/vim/syntax/rust.vim b/src/etc/vim/syntax/rust.vim index 4ff7783888f8d..f811fbf585542 100644 --- a/src/etc/vim/syntax/rust.vim +++ b/src/etc/vim/syntax/rust.vim @@ -14,7 +14,7 @@ syn match rustAssert "\ syn match rustFloat display "\<[0-9][0-9_]*\.[0-9_]\+\%([eE][+-]\=[0-9_]\+\)\>" syn match rustFloat display "\<[0-9][0-9_]*\.[0-9_]\+\%([eE][+-]\=[0-9_]\+\)\(f\|f32\|f64\)\>" +"rustLifetime must appear before rustCharacter, or chars will get the lifetime highlighting +syn match rustLifetime display "\'\%([^[:cntrl:][:space:][:punct:][:digit:]]\|_\)\%([^[:cntrl:][:punct:][:space:]]\|_\)*" syn match rustCharacter "'\([^'\\]\|\\\(['nrt\\\"]\|x\x\{2}\|u\x\{4}\|U\x\{8}\)\)'" syn region rustComment start="/\*" end="\*/" contains=rustComment,rustTodo syn region rustComment start="//" skip="\\$" end="$" contains=rustTodo keepend -syn keyword rustTodo TODO FIXME XXX NB + +syn keyword rustTodo TODO FIXME XXX NB unsafe hi def link rustHexNumber rustNumber hi def link rustBinNumber rustNumber @@ -134,6 +137,7 @@ hi def link rustType Type hi def link rustTodo Todo hi def link rustAttribute PreProc hi def link rustStorage StorageClass +hi def link rustLifetime Special " Other Suggestions: " hi rustAssert ctermfg=yellow diff --git a/src/etc/x86.supp b/src/etc/x86.supp index 03d2f300e90be..16a3144c01717 100644 --- a/src/etc/x86.supp +++ b/src/etc/x86.supp @@ -366,6 +366,62 @@ ... } +{ + enum-instruction-scheduling-1 + Memcheck:Cond + fun:*fold_mod* + ... +} + +{ + enum-instruction-scheduling-2 + Memcheck:Cond + fun:*fold_nmod* + ... +} + +{ + enum-instruction-scheduling-3 + Memcheck:Cond + fun:*fold_crate* + ... +} + +{ + enum-instruction-scheduling-4 + Memcheck:Cond + fun:*fold_enum* + ... +} + +{ + enum-instruction-scheduling-5 + Memcheck:Cond + fun:*write_variant* + ... +} + +{ + enum-instruction-scheduling-6 + Memcheck:Cond + fun:*merge_method_attrs* + ... +} + +{ + enum-instruction-scheduling-7 + Memcheck:Cond + fun:*parse_config_* + ... +} + +{ + enum-instruction-scheduling-8 + Memcheck:Cond + fun:*should_set_output_format_to_markdown_if_requested* + ... +} + { llvm-user-new-leak Memcheck:Leak diff --git a/src/libcargo/cargo.rc b/src/libcargo/cargo.rc deleted file mode 100644 index 782878e05c70f..0000000000000 --- a/src/libcargo/cargo.rc +++ /dev/null @@ -1,1981 +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. - - -// cargo.rs - Rust package manager - -// Local Variables: -// fill-column: 78; -// indent-tabs-mode: nil -// c-basic-offset: 4 -// buffer-file-coding-system: utf-8-unix -// End: - -#[link(name = "cargo", - vers = "0.6", - uuid = "9ff87a04-8fed-4295-9ff8-f99bb802650b", - url = "https://github.com/mozilla/rust/tree/master/src/cargo")]; - -#[crate_type = "lib"]; - -#[no_core]; - -#[legacy_modes]; - -#[allow(vecs_implicitly_copyable, - non_implicitly_copyable_typarams)]; -#[allow(non_camel_case_types)]; -#[allow(deprecated_mode)]; -#[allow(deprecated_pattern)]; -#[allow(deprecated_self)]; - -extern mod core(vers = "0.6"); -extern mod std(vers = "0.6"); -extern mod rustc(vers = "0.6"); -extern mod syntax(vers = "0.6"); - -mod pgp; - -use rustc::metadata::filesearch::{get_cargo_root, get_cargo_root_nearest}; -use rustc::metadata::filesearch::{get_cargo_sysroot, libdir}; - -use core::*; - -use core::dvec::DVec; -use core::io::WriterUtil; -use core::result::{Ok, Err}; -use core::hashmap::linear::LinearMap; -use std::getopts::{optflag, optopt, opt_present}; -use std::oldmap::HashMap; -use std::{oldmap, json, tempfile, term, sort, getopts}; -use syntax::codemap::span; -use syntax::diagnostic::span_handler; -use syntax::diagnostic; -use syntax::{ast, codemap, parse, visit, attr}; - -pub struct Package { - name: ~str, - uuid: ~str, - url: ~str, - method: ~str, - description: ~str, - reference: Option<~str>, - tags: ~[~str], - versions: ~[(~str, ~str)] -} - -pub impl Package : cmp::Ord { - pure fn lt(&self, other: &Package) -> bool { - if (*self).name.lt(&(*other).name) { return true; } - if (*other).name.lt(&(*self).name) { return false; } - if (*self).uuid.lt(&(*other).uuid) { return true; } - if (*other).uuid.lt(&(*self).uuid) { return false; } - if (*self).url.lt(&(*other).url) { return true; } - if (*other).url.lt(&(*self).url) { return false; } - if (*self).method.lt(&(*other).method) { return true; } - if (*other).method.lt(&(*self).method) { return false; } - if (*self).description.lt(&(*other).description) { return true; } - if (*other).description.lt(&(*self).description) { return false; } - if (*self).tags.lt(&(*other).tags) { return true; } - if (*other).tags.lt(&(*self).tags) { return false; } - if (*self).versions.lt(&(*other).versions) { return true; } - return false; - } - pure fn le(&self, other: &Package) -> bool { !(*other).lt(&(*self)) } - pure fn ge(&self, other: &Package) -> bool { !(*self).lt(other) } - pure fn gt(&self, other: &Package) -> bool { (*other).lt(&(*self)) } -} - -pub struct Source { - name: ~str, - mut url: ~str, - mut method: ~str, - mut key: Option<~str>, - mut keyfp: Option<~str>, - packages: DVec -} - -pub struct Cargo { - pgp: bool, - root: Path, - installdir: Path, - bindir: Path, - libdir: Path, - workdir: Path, - sourcedir: Path, - sources: oldmap::HashMap<~str, @Source>, - mut current_install: ~str, - dep_cache: oldmap::HashMap<~str, bool>, - opts: Options -} - -pub struct Crate { - name: ~str, - vers: ~str, - uuid: ~str, - desc: Option<~str>, - sigs: Option<~str>, - crate_type: Option<~str>, - deps: ~[~str] -} - -pub struct Options { - test: bool, - mode: Mode, - free: ~[~str], - help: bool, -} - -#[deriving_eq] -pub enum Mode { SystemMode, UserMode, LocalMode } - -pub fn opts() -> ~[getopts::Opt] { - ~[optflag(~"g"), optflag(~"G"), optflag(~"test"), - optflag(~"h"), optflag(~"help")] -} - -pub fn info(msg: ~str) { - let out = io::stdout(); - - if term::color_supported() { - term::fg(out, term::color_green); - out.write_str(~"info: "); - term::reset(out); - out.write_line(msg); - } else { out.write_line(~"info: " + msg); } -} - -pub fn warn(msg: ~str) { - let out = io::stdout(); - - if term::color_supported() { - term::fg(out, term::color_yellow); - out.write_str(~"warning: "); - term::reset(out); - out.write_line(msg); - }else { out.write_line(~"warning: " + msg); } -} - -pub fn error(msg: ~str) { - let out = io::stdout(); - - if term::color_supported() { - term::fg(out, term::color_red); - out.write_str(~"error: "); - term::reset(out); - out.write_line(msg); - } - else { out.write_line(~"error: " + msg); } -} - -pub fn is_uuid(id: ~str) -> bool { - let parts = str::split_str(id, ~"-"); - if vec::len(parts) == 5u { - let mut correct = 0u; - for vec::eachi(parts) |i, part| { - fn is_hex_digit(+ch: char) -> bool { - ('0' <= ch && ch <= '9') || - ('a' <= ch && ch <= 'f') || - ('A' <= ch && ch <= 'F') - } - - if !part.all(is_hex_digit) { - return false; - } - - match i { - 0u => { - if part.len() == 8u { - correct += 1u; - } - } - 1u | 2u | 3u => { - if part.len() == 4u { - correct += 1u; - } - } - 4u => { - if part.len() == 12u { - correct += 1u; - } - } - _ => { } - } - } - if correct >= 5u { - return true; - } - } - return false; -} - -#[test] -pub fn test_is_uuid() { - assert is_uuid(~"aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaafAF09"); - assert !is_uuid(~"aaaaaaaa-aaaa-aaaa-aaaaa-aaaaaaaaaaaa"); - assert !is_uuid(~""); - assert !is_uuid(~"aaaaaaaa-aaa -aaaa-aaaa-aaaaaaaaaaaa"); - assert !is_uuid(~"aaaaaaaa-aaa!-aaaa-aaaa-aaaaaaaaaaaa"); - assert !is_uuid(~"aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa-a"); - assert !is_uuid(~"aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaป"); -} - -// FIXME (#2661): implement url/URL parsing so we don't have to resort -// to weak checks - -pub fn has_archive_extension(p: ~str) -> bool { - str::ends_with(p, ~".tar") || - str::ends_with(p, ~".tar.gz") || - str::ends_with(p, ~".tar.bz2") || - str::ends_with(p, ~".tar.Z") || - str::ends_with(p, ~".tar.lz") || - str::ends_with(p, ~".tar.xz") || - str::ends_with(p, ~".tgz") || - str::ends_with(p, ~".tbz") || - str::ends_with(p, ~".tbz2") || - str::ends_with(p, ~".tb2") || - str::ends_with(p, ~".taz") || - str::ends_with(p, ~".tlz") || - str::ends_with(p, ~".txz") -} - -pub fn is_archive_path(u: ~str) -> bool { - has_archive_extension(u) && os::path_exists(&Path(u)) -} - -pub fn is_archive_url(u: ~str) -> bool { - // FIXME (#2661): this requires the protocol bit - if we had proper - // url parsing, we wouldn't need it - - match str::find_str(u, ~"://") { - option::Some(_) => has_archive_extension(u), - _ => false - } -} - -pub fn is_git_url(url: ~str) -> bool { - if str::ends_with(url, ~"/") { str::ends_with(url, ~".git/") } - else { - str::starts_with(url, ~"git://") || str::ends_with(url, ~".git") - } -} - -pub fn assume_source_method(url: ~str) -> ~str { - if is_git_url(url) { - return ~"git"; - } - if str::starts_with(url, ~"file://") || os::path_exists(&Path(url)) { - return ~"file"; - } - - ~"curl" -} - -pub fn load_link(mis: ~[@ast::meta_item]) -> (Option<~str>, - Option<~str>, - Option<~str>) { - let mut name = None; - let mut vers = None; - let mut uuid = None; - for mis.each |a| { - match a.node { - ast::meta_name_value(v, codemap::spanned { node: ast::lit_str(s), - _ }) => { - match v { - ~"name" => name = Some(*s), - ~"vers" => vers = Some(*s), - ~"uuid" => uuid = Some(*s), - _ => { } - } - } - _ => fail!(~"load_link: meta items must be name-values") - } - } - (name, vers, uuid) -} - -pub fn load_crate(filename: &Path) -> Option { - let sess = parse::new_parse_sess(None); - let c = parse::parse_crate_from_file(filename, ~[], sess); - - let mut name = None; - let mut vers = None; - let mut uuid = None; - let mut desc = None; - let mut sigs = None; - let mut crate_type = None; - - for c.node.attrs.each |a| { - match a.node.value.node { - ast::meta_name_value(v, codemap::spanned { node: ast::lit_str(_), - _ }) => { - match v { - ~"desc" => desc = Some(v), - ~"sigs" => sigs = Some(v), - ~"crate_type" => crate_type = Some(v), - _ => { } - } - } - ast::meta_list(v, mis) => { - if v == ~"link" { - let (n, v, u) = load_link(mis); - name = n; - vers = v; - uuid = u; - } - } - _ => { - fail!(~"crate attributes may not contain " + - ~"meta_words"); - } - } - } - - struct Env { - mut deps: ~[~str] - } - - fn goto_view_item(ps: syntax::parse::parse_sess, e: @Env, - i: @ast::view_item) { - match i.node { - ast::view_item_use(ident, metas, _) => { - let name_items = - attr::find_meta_items_by_name(metas, ~"name"); - let m = if name_items.is_empty() { - metas + ~[attr::mk_name_value_item_str( - ~"name", *ps.interner.get(ident))] - } else { - metas - }; - let mut attr_name = ident; - let mut attr_vers = ~""; - let mut attr_from = ~""; - - for m.each |item| { - match attr::get_meta_item_value_str(*item) { - Some(value) => { - let name = attr::get_meta_item_name(*item); - - match name { - ~"vers" => attr_vers = value, - ~"from" => attr_from = value, - _ => () - } - } - None => () - } - } - - let query = if !str::is_empty(attr_from) { - attr_from - } else { - if !str::is_empty(attr_vers) { - ps.interner.get(attr_name) + ~"@" + attr_vers - } else { *ps.interner.get(attr_name) } - }; - - match *ps.interner.get(attr_name) { - ~"std" | ~"core" => (), - _ => e.deps.push(query) - } - } - _ => () - } - } - fn goto_item(_e: @Env, _i: @ast::item) { - } - - let e = @Env { - mut deps: ~[] - }; - let v = visit::mk_simple_visitor(@visit::SimpleVisitor { - visit_view_item: |a| goto_view_item(sess, e, a), - visit_item: |a| goto_item(e, a), - .. *visit::default_simple_visitor() - }); - - visit::visit_crate(*c, (), v); - - let deps = copy e.deps; - - match (name, vers, uuid) { - (Some(name0), Some(vers0), Some(uuid0)) => { - Some(Crate { - name: name0, - vers: vers0, - uuid: uuid0, - desc: desc, - sigs: sigs, - crate_type: crate_type, - deps: deps }) - } - _ => return None - } -} - -pub fn print(s: ~str) { - io::stdout().write_line(s); -} - -pub fn rest(s: ~str, start: uint) -> ~str { - if (start >= str::len(s)) { - ~"" - } else { - str::slice(s, start, str::len(s)) - } -} - -pub fn need_dir(s: &Path) { - if os::path_is_dir(s) { return; } - if !os::make_dir(s, 493_i32 /* oct: 755 */) { - fail!(fmt!("can't make_dir %s", s.to_str())); - } -} - -pub fn valid_pkg_name(s: &str) -> bool { - fn is_valid_digit(+c: char) -> bool { - ('0' <= c && c <= '9') || - ('a' <= c && c <= 'z') || - ('A' <= c && c <= 'Z') || - c == '-' || - c == '_' - } - - s.all(is_valid_digit) -} - -pub fn parse_source(name: ~str, j: &json::Json) -> @Source { - if !valid_pkg_name(name) { - fail!(fmt!("'%s' is an invalid source name", name)); - } - - match *j { - json::Object(ref j) => { - let mut url = match j.find(&~"url") { - Some(&json::String(u)) => copy u, - _ => fail!(~"needed 'url' field in source") - }; - let method = match j.find(&~"method") { - Some(&json::String(u)) => copy u, - _ => assume_source_method(url) - }; - let key = match j.find(&~"key") { - Some(&json::String(u)) => Some(copy u), - _ => None - }; - let keyfp = match j.find(&~"keyfp") { - Some(&json::String(u)) => Some(copy u), - _ => None - }; - if method == ~"file" { - url = os::make_absolute(&Path(url)).to_str(); - } - return @Source { - name: name, - mut url: url, - mut method: method, - mut key: key, - mut keyfp: keyfp, - packages: DVec() }; - } - _ => fail!(~"needed dict value in source") - }; -} - -pub fn try_parse_sources(filename: &Path, - sources: oldmap::HashMap<~str, @Source>) { - if !os::path_exists(filename) { return; } - let c = io::read_whole_file_str(filename); - match json::from_str(c.get()) { - Ok(json::Object(j)) => { - for j.each |&(k, v)| { - sources.insert(copy *k, parse_source(*k, v)); - debug!("source: %s", *k); - } - } - Ok(_) => fail!(~"malformed sources.json"), - Err(e) => fail!(fmt!("%s:%s", filename.to_str(), e.to_str())) - } -} - -pub fn load_one_source_package(src: @Source, p: &json::Object) { - let name = match p.find(&~"name") { - Some(&json::String(n)) => { - if !valid_pkg_name(n) { - warn(~"malformed source json: " - + src.name + ~", '" + n + ~"'"+ - ~" is an invalid name (alphanumeric, underscores and" + - ~" dashes only)"); - return; - } - n - } - _ => { - warn(~"malformed source json: " + src.name + ~" (missing name)"); - return; - } - }; - - let uuid = match p.find(&~"uuid") { - Some(&json::String(n)) => { - if !is_uuid(n) { - warn(~"malformed source json: " - + src.name + ~", '" + n + ~"'"+ - ~" is an invalid uuid"); - return; - } - copy n - } - _ => { - warn(~"malformed source json: " + src.name + ~" (missing uuid)"); - return; - } - }; - - let url = match p.find(&~"url") { - Some(&json::String(n)) => copy n, - _ => { - warn(~"malformed source json: " + src.name + ~" (missing url)"); - return; - } - }; - - let method = match p.find(&~"method") { - Some(&json::String(n)) => copy n, - _ => { - warn(~"malformed source json: " - + src.name + ~" (missing method)"); - return; - } - }; - - let reference = match p.find(&~"ref") { - Some(&json::String(n)) => Some(copy n), - _ => None - }; - - let mut tags = ~[]; - match p.find(&~"tags") { - Some(&json::List(ref js)) => { - for js.each |j| { - match *j { - json::String(ref j) => tags.grow(1u, j), - _ => () - } - } - } - _ => () - } - - let description = match p.find(&~"description") { - Some(&json::String(n)) => copy n, - _ => { - warn(~"malformed source json: " + src.name - + ~" (missing description)"); - return; - } - }; - - let newpkg = Package { - name: name, - uuid: uuid, - url: url, - method: method, - description: description, - reference: reference, - tags: tags, - versions: ~[] - }; - - match src.packages.position(|pkg| pkg.uuid == uuid) { - Some(idx) => { - src.packages.set_elt(idx, newpkg); - log(debug, ~" updated package: " + src.name + ~"/" + name); - } - None => { - src.packages.push(newpkg); - } - } - - log(debug, ~" loaded package: " + src.name + ~"/" + name); -} - -pub fn load_source_info(c: &Cargo, src: @Source) { - let dir = c.sourcedir.push(src.name); - let srcfile = dir.push("source.json"); - if !os::path_exists(&srcfile) { return; } - let srcstr = io::read_whole_file_str(&srcfile); - match json::from_str(srcstr.get()) { - Ok(ref json @ json::Object(_)) => { - let o = parse_source(src.name, json); - - src.key = o.key; - src.keyfp = o.keyfp; - } - Ok(_) => { - warn(~"malformed source.json: " + src.name + - ~"(source info is not a dict)"); - } - Err(e) => { - warn(fmt!("%s:%s", src.name, e.to_str())); - } - }; -} -pub fn load_source_packages(c: &Cargo, src: @Source) { - log(debug, ~"loading source: " + src.name); - let dir = c.sourcedir.push(src.name); - let pkgfile = dir.push("packages.json"); - if !os::path_exists(&pkgfile) { return; } - let pkgstr = io::read_whole_file_str(&pkgfile); - match json::from_str(pkgstr.get()) { - Ok(json::List(ref js)) => { - for js.each |j| { - match *j { - json::Object(ref p) => { - load_one_source_package(src, *p); - } - _ => { - warn(~"malformed source json: " + src.name + - ~" (non-dict pkg)"); - } - } - } - } - Ok(_) => { - warn(~"malformed packages.json: " + src.name + - ~"(packages is not a list)"); - } - Err(e) => { - warn(fmt!("%s:%s", src.name, e.to_str())); - } - }; -} - -pub fn build_cargo_options(argv: ~[~str]) -> Options { - let matches = &match getopts::getopts(argv, opts()) { - result::Ok(m) => m, - result::Err(f) => { - fail!(fmt!("%s", getopts::fail_str(f))); - } - }; - - let test = opt_present(matches, ~"test"); - let G = opt_present(matches, ~"G"); - let g = opt_present(matches, ~"g"); - let help = opt_present(matches, ~"h") || opt_present(matches, ~"help"); - let len = vec::len(matches.free); - - let is_install = len > 1u && matches.free[1] == ~"install"; - let is_uninstall = len > 1u && matches.free[1] == ~"uninstall"; - - if G && g { fail!(~"-G and -g both provided"); } - - if !is_install && !is_uninstall && (g || G) { - fail!(~"-g and -G are only valid for `install` and `uninstall|rm`"); - } - - let mode = - if (!is_install && !is_uninstall) || g { UserMode } - else if G { SystemMode } - else { LocalMode }; - - Options {test: test, mode: mode, free: matches.free, help: help} -} - -pub fn configure(opts: Options) -> Cargo { - let home = match get_cargo_root() { - Ok(home) => home, - Err(_err) => get_cargo_sysroot().get() - }; - - let get_cargo_dir = match opts.mode { - SystemMode => get_cargo_sysroot, - UserMode => get_cargo_root, - LocalMode => get_cargo_root_nearest - }; - - let p = get_cargo_dir().get(); - - let sources = HashMap(); - try_parse_sources(&home.push("sources.json"), sources); - try_parse_sources(&home.push("local-sources.json"), sources); - - let dep_cache = HashMap(); - - let mut c = Cargo { - pgp: pgp::supported(), - root: home, - installdir: p, - bindir: p.push("bin"), - libdir: p.push("lib"), - workdir: p.push("work"), - sourcedir: home.push("sources"), - sources: sources, - mut current_install: ~"", - dep_cache: dep_cache, - opts: opts - }; - - need_dir(&c.root); - need_dir(&c.installdir); - need_dir(&c.sourcedir); - need_dir(&c.workdir); - need_dir(&c.libdir); - need_dir(&c.bindir); - - for sources.each_key |&k| { - let mut s = sources.get(&k); - load_source_packages(&c, s); - sources.insert(k, s); - } - - if c.pgp { - pgp::init(&c.root); - } else { - warn(~"command `gpg` was not found"); - warn(~"you have to install gpg from source " + - ~" or package manager to get it to work correctly"); - } - - move c -} - -pub fn for_each_package(c: &Cargo, b: fn(s: @Source, p: &Package)) { - for c.sources.each_value |&v| { - for v.packages.each |p| { - b(v, p); - } - } -} - -// Runs all programs in directory -pub fn run_programs(buildpath: &Path) { - let newv = os::list_dir_path(buildpath); - for newv.each |ct| { - run::run_program(ct.to_str(), ~[]); - } -} - -// Runs rustc in with the given flags -// and returns -pub fn run_in_buildpath(what: &str, path: &Path, subdir: &Path, cf: &Path, - extra_flags: ~[~str]) -> Option { - let buildpath = path.push_rel(subdir); - need_dir(&buildpath); - debug!("%s: %s -> %s", what, cf.to_str(), buildpath.to_str()); - let p = run::program_output(rustc_sysroot(), - ~[~"--out-dir", - buildpath.to_str(), - cf.to_str()] + extra_flags); - if p.status != 0 { - error(fmt!("rustc failed: %d\n%s\n%s", p.status, p.err, p.out)); - return None; - } - Some(buildpath) -} - -pub fn test_one_crate(_c: &Cargo, path: &Path, cf: &Path) { - let buildpath = match run_in_buildpath(~"testing", path, - &Path("test"), - cf, - ~[ ~"--test"]) { - None => return, - Some(bp) => bp - }; - run_programs(&buildpath); -} - -pub fn install_one_crate(c: &Cargo, path: &Path, cf: &Path) { - let buildpath = match run_in_buildpath(~"installing", path, - &Path("build"), - cf, ~[]) { - None => return, - Some(bp) => bp - }; - let newv = os::list_dir_path(&buildpath); - let exec_suffix = str::from_slice(os::EXE_SUFFIX); - for newv.each |ct| { - if (exec_suffix != ~"" && str::ends_with(ct.to_str(), - exec_suffix)) || - (exec_suffix == ~"" && - !str::starts_with(ct.filename().get(), - ~"lib")) { - debug!(" bin: %s", ct.to_str()); - install_to_dir(*ct, &c.bindir); - if c.opts.mode == SystemMode { - // FIXME (#2662): Put this file in PATH / symlink it so it can - // be used as a generic executable - // `cargo install -G rustray` and `rustray file.obj` - } - } else { - debug!(" lib: %s", ct.to_str()); - install_to_dir(*ct, &c.libdir); - } - } -} - - -pub fn rustc_sysroot() -> ~str { - match os::self_exe_path() { - Some(path) => { - let rustc = path.push_many([~"..", ~"bin", ~"rustc"]); - debug!(" rustc: %s", rustc.to_str()); - rustc.to_str() - } - None => ~"rustc" - } -} - -pub fn install_source(c: &mut Cargo, path: &Path) { - debug!("source: %s", path.to_str()); - os::change_dir(path); - - let mut cratefiles = ~[]; - for os::walk_dir(&Path(".")) |p| { - if p.filetype() == Some(~".rc") { - cratefiles.push(*p); - } - } - - if vec::is_empty(cratefiles) { - fail!(~"this doesn't look like a rust package (no .rc files)"); - } - - for cratefiles.each |cf| { - match load_crate(cf) { - None => loop, - Some(crate) => { - for crate.deps.each |query| { - // FIXME (#1356): handle cyclic dependencies - // (n.b. #1356 says "Cyclic dependency is an error - // condition") - - let wd = get_temp_workdir(c); - install_query(c, &wd, *query); - } - - os::change_dir(path); - - if c.opts.test { - test_one_crate(c, path, cf); - } - install_one_crate(c, path, cf); - } - } - } -} - -pub fn install_git(c: &mut Cargo, wd: &Path, url: ~str, - reference: Option<~str>) { - run::program_output(~"git", ~[~"clone", url, wd.to_str()]); - if reference.is_some() { - let r = reference.get(); - os::change_dir(wd); - run::run_program(~"git", ~[~"checkout", r]); - } - - install_source(c, wd); -} - -pub fn install_curl(c: &mut Cargo, wd: &Path, url: ~str) { - let tarpath = wd.push("pkg.tar"); - let p = run::program_output(~"curl", ~[~"-f", ~"-s", ~"-o", - tarpath.to_str(), url]); - if p.status != 0 { - fail!(fmt!("fetch of %s failed: %s", url, p.err)); - } - run::run_program(~"tar", ~[~"-x", ~"--strip-components=1", - ~"-C", wd.to_str(), - ~"-f", tarpath.to_str()]); - install_source(c, wd); -} - -pub fn install_file(c: &mut Cargo, wd: &Path, path: &Path) { - run::program_output(~"tar", ~[~"-x", ~"--strip-components=1", - ~"-C", wd.to_str(), - ~"-f", path.to_str()]); - install_source(c, wd); -} - -pub fn install_package(c: &mut Cargo, src: ~str, wd: &Path, pkg: Package) { - let url = copy pkg.url; - let method = match pkg.method { - ~"git" => ~"git", - ~"file" => ~"file", - _ => ~"curl" - }; - - info(fmt!("installing %s/%s via %s...", src, pkg.name, method)); - - match method { - ~"git" => install_git(c, wd, url, copy pkg.reference), - ~"file" => install_file(c, wd, &Path(url)), - ~"curl" => install_curl(c, wd, url), - _ => () - } -} - -pub fn cargo_suggestion(c: &Cargo, fallback: fn()) { - if c.sources.is_empty() { - error(~"no sources defined - you may wish to run " + - ~"`cargo init`"); - return; - } - fallback(); -} - -pub fn install_uuid(c: &mut Cargo, wd: &Path, uuid: ~str) { - let mut ps = ~[]; - for_each_package(c, |s, p| { - if p.uuid == uuid { - vec::push(&mut ps, (s.name, copy *p)); - } - }); - if vec::len(ps) == 1u { - let (sname, p) = copy ps[0]; - install_package(c, sname, wd, p); - return; - } else if vec::len(ps) == 0u { - cargo_suggestion(c, || { - error(~"can't find package: " + uuid); - }); - return; - } - error(~"found multiple packages:"); - for ps.each |elt| { - let (sname,p) = copy *elt; - info(~" " + sname + ~"/" + p.uuid + ~" (" + p.name + ~")"); - } -} - -pub fn install_named(c: &mut Cargo, wd: &Path, name: ~str) { - let mut ps = ~[]; - for_each_package(c, |s, p| { - if p.name == name { - vec::push(&mut ps, (s.name, copy *p)); - } - }); - if vec::len(ps) == 1u { - let (sname, p) = copy ps[0]; - install_package(c, sname, wd, p); - return; - } else if vec::len(ps) == 0u { - cargo_suggestion(c, || { - error(~"can't find package: " + name); - }); - return; - } - error(~"found multiple packages:"); - for ps.each |elt| { - let (sname,p) = copy *elt; - info(~" " + sname + ~"/" + p.uuid + ~" (" + p.name + ~")"); - } -} - -pub fn install_uuid_specific(c: &mut Cargo, wd: &Path, src: ~str, - uuid: ~str) { - match c.sources.find(&src) { - Some(s) => { - for s.packages.each |p| { - if p.uuid == uuid { - install_package(c, src, wd, *p); - return; - } - } - } - _ => () - } - error(~"can't find package: " + src + ~"/" + uuid); -} - -pub fn install_named_specific(c: &mut Cargo, wd: &Path, src: ~str, - name: ~str) { - match c.sources.find(&src) { - Some(s) => { - for s.packages.each |p| { - if p.name == name { - install_package(c, src, wd, *p); - return; - } - } - } - _ => () - } - error(~"can't find package: " + src + ~"/" + name); -} - -pub fn cmd_uninstall(c: &Cargo) { - if vec::len(c.opts.free) < 3u { - cmd_usage(); - return; - } - - let lib = &c.libdir; - let bin = &c.bindir; - let target = c.opts.free[2u]; - - // FIXME (#2662): needs stronger pattern matching - // FIXME (#2662): needs to uninstall from a specified location in a - // cache instead of looking for it (binaries can be uninstalled by - // name only) - - fn try_uninstall(p: &Path) -> bool { - if os::remove_file(p) { - info(~"uninstalled: '" + p.to_str() + ~"'"); - true - } else { - error(~"could not uninstall: '" + - p.to_str() + ~"'"); - false - } - } - - if is_uuid(target) { - for os::list_dir(lib).each |file| { - match str::find_str(*file, ~"-" + target + ~"-") { - Some(_) => if !try_uninstall(&lib.push(*file)) { return }, - None => () - } - } - error(~"can't find package with uuid: " + target); - } else { - for os::list_dir(lib).each |file| { - match str::find_str(*file, ~"lib" + target + ~"-") { - Some(_) => if !try_uninstall(&lib.push(*file)) { return }, - None => () - } - } - for os::list_dir(bin).each |file| { - match str::find_str(*file, target) { - Some(_) => if !try_uninstall(&lib.push(*file)) { return }, - None => () - } - } - - error(~"can't find package with name: " + target); - } -} - -pub fn install_query(c: &mut Cargo, wd: &Path, target: ~str) { - match c.dep_cache.find(&target) { - Some(inst) => { - if inst { - return; - } - } - None => () - } - - c.dep_cache.insert(target, true); - - if is_archive_path(target) { - install_file(c, wd, &Path(target)); - return; - } else if is_git_url(target) { - let reference = if c.opts.free.len() >= 4u { - Some(c.opts.free[3u]) - } else { - None - }; - install_git(c, wd, target, reference); - } else if !valid_pkg_name(target) && has_archive_extension(target) { - install_curl(c, wd, target); - return; - } else { - let mut ps = copy target; - - match str::find_char(ps, '/') { - option::Some(idx) => { - let source = str::slice(ps, 0u, idx); - ps = str::slice(ps, idx + 1u, str::len(ps)); - if is_uuid(ps) { - install_uuid_specific(c, wd, source, ps); - } else { - install_named_specific(c, wd, source, ps); - } - } - option::None => { - if is_uuid(ps) { - install_uuid(c, wd, ps); - } else { - install_named(c, wd, ps); - } - } - } - } - - // FIXME (#2662): This whole dep_cache and current_install thing is - // a bit of a hack. It should be cleaned up in the future. - - if target == c.current_install { - c.dep_cache.clear(); - c.current_install = ~""; - } -} - -pub fn get_temp_workdir(c: &Cargo) -> Path { - match tempfile::mkdtemp(&c.workdir, "cargo") { - Some(wd) => wd, - None => fail!(fmt!("needed temp dir: %s", - c.workdir.to_str())) - } -} - -pub fn cmd_install(c: &mut Cargo) { - unsafe { - let wd = get_temp_workdir(c); - - if vec::len(c.opts.free) == 2u { - let cwd = os::getcwd(); - let status = run::run_program(~"cp", ~[~"-R", cwd.to_str(), - wd.to_str()]); - - if status != 0 { - fail!(fmt!("could not copy directory: %s", cwd.to_str())); - } - - install_source(c, &wd); - return; - } - - sync(c); - - let query = c.opts.free[2]; - c.current_install = query.to_str(); - - install_query(c, &wd, query); - } -} - -pub fn sync(c: &Cargo) { - for c.sources.each_key |&k| { - let mut s = c.sources.get(&k); - sync_one(c, s); - c.sources.insert(k, s); - } -} - -pub fn sync_one_file(c: &Cargo, dir: &Path, src: @Source) -> bool { - let name = src.name; - let srcfile = dir.push("source.json.new"); - let destsrcfile = dir.push("source.json"); - let pkgfile = dir.push("packages.json.new"); - let destpkgfile = dir.push("packages.json"); - let keyfile = dir.push("key.gpg"); - let srcsigfile = dir.push("source.json.sig"); - let sigfile = dir.push("packages.json.sig"); - let url = Path(src.url); - let mut has_src_file = false; - - if !os::copy_file(&url.push("packages.json"), &pkgfile) { - error(fmt!("fetch for source %s (url %s) failed", - name, url.to_str())); - return false; - } - - if os::copy_file(&url.push("source.json"), &srcfile) { - has_src_file = false; - } - - os::copy_file(&url.push("source.json.sig"), &srcsigfile); - os::copy_file(&url.push("packages.json.sig"), &sigfile); - - match copy src.key { - Some(u) => { - let p = run::program_output(~"curl", - ~[~"-f", ~"-s", - ~"-o", keyfile.to_str(), u]); - if p.status != 0 { - error(fmt!("fetch for source %s (key %s) failed", name, u)); - return false; - } - pgp::add(&c.root, &keyfile); - } - _ => () - } - match (src.key, src.keyfp) { - (Some(_), Some(f)) => { - let r = pgp::verify(&c.root, &pkgfile, &sigfile); - - if !r { - error(fmt!("signature verification failed for source %s with \ - key %s", name, f)); - return false; - } - - if has_src_file { - let e = pgp::verify(&c.root, &srcfile, &srcsigfile); - - if !e { - error(fmt!("signature verification failed for source %s \ - with key %s", name, f)); - return false; - } - } - } - _ => () - } - - copy_warn(&pkgfile, &destpkgfile); - - if has_src_file { - copy_warn(&srcfile, &destsrcfile); - } - - os::remove_file(&keyfile); - os::remove_file(&srcfile); - os::remove_file(&srcsigfile); - os::remove_file(&pkgfile); - os::remove_file(&sigfile); - - info(fmt!("synced source: %s", name)); - - return true; -} - -pub fn sync_one_git(c: &Cargo, dir: &Path, src: @Source) -> bool { - let name = src.name; - let srcfile = dir.push("source.json"); - let pkgfile = dir.push("packages.json"); - let keyfile = dir.push("key.gpg"); - let srcsigfile = dir.push("source.json.sig"); - let sigfile = dir.push("packages.json.sig"); - let url = src.url; - - fn rollback(name: ~str, dir: &Path, insecure: bool) { - fn msg(name: ~str, insecure: bool) { - error(fmt!("could not rollback source: %s", name)); - - if insecure { - warn(~"a past security check failed on source " + - name + ~" and rolling back the source failed -" - + ~" this source may be compromised"); - } - } - - if !os::change_dir(dir) { - msg(name, insecure); - } - else { - let p = run::program_output(~"git", ~[~"reset", ~"--hard", - ~"HEAD@{1}"]); - - if p.status != 0 { - msg(name, insecure); - } - } - } - - if !os::path_exists(&dir.push(".git")) { - let p = run::program_output(~"git", ~[~"clone", url, dir.to_str()]); - - if p.status != 0 { - error(fmt!("fetch for source %s (url %s) failed", name, url)); - return false; - } - } - else { - if !os::change_dir(dir) { - error(fmt!("fetch for source %s (url %s) failed", name, url)); - return false; - } - - let p = run::program_output(~"git", ~[~"pull"]); - - if p.status != 0 { - error(fmt!("fetch for source %s (url %s) failed", name, url)); - return false; - } - } - - let has_src_file = os::path_exists(&srcfile); - - match copy src.key { - Some(u) => { - let p = run::program_output(~"curl", - ~[~"-f", ~"-s", - ~"-o", keyfile.to_str(), u]); - if p.status != 0 { - error(fmt!("fetch for source %s (key %s) failed", name, u)); - rollback(name, dir, false); - return false; - } - pgp::add(&c.root, &keyfile); - } - _ => () - } - match (src.key, src.keyfp) { - (Some(_), Some(f)) => { - let r = pgp::verify(&c.root, &pkgfile, &sigfile); - - if !r { - error(fmt!("signature verification failed for source %s with \ - key %s", name, f)); - rollback(name, dir, false); - return false; - } - - if has_src_file { - let e = pgp::verify(&c.root, &srcfile, &srcsigfile); - - if !e { - error(fmt!("signature verification failed for source %s \ - with key %s", name, f)); - rollback(name, dir, false); - return false; - } - } - } - _ => () - } - - os::remove_file(&keyfile); - - info(fmt!("synced source: %s", name)); - - return true; -} - -pub fn sync_one_curl(c: &Cargo, dir: &Path, src: @Source) -> bool { - let name = src.name; - let srcfile = dir.push("source.json.new"); - let destsrcfile = dir.push("source.json"); - let pkgfile = dir.push("packages.json.new"); - let destpkgfile = dir.push("packages.json"); - let keyfile = dir.push("key.gpg"); - let srcsigfile = dir.push("source.json.sig"); - let sigfile = dir.push("packages.json.sig"); - let mut url = src.url; - let smart = !str::ends_with(src.url, ~"packages.json"); - let mut has_src_file = false; - - if smart { - url += ~"/packages.json"; - } - - let p = run::program_output(~"curl", - ~[~"-f", ~"-s", - ~"-o", pkgfile.to_str(), url]); - - if p.status != 0 { - error(fmt!("fetch for source %s (url %s) failed", name, url)); - return false; - } - if smart { - url = src.url + ~"/source.json"; - let p = - run::program_output(~"curl", - ~[~"-f", ~"-s", - ~"-o", srcfile.to_str(), url]); - - if p.status == 0 { - has_src_file = true; - } - } - - match copy src.key { - Some(u) => { - let p = run::program_output(~"curl", - ~[~"-f", ~"-s", - ~"-o", keyfile.to_str(), u]); - if p.status != 0 { - error(fmt!("fetch for source %s (key %s) failed", name, u)); - return false; - } - pgp::add(&c.root, &keyfile); - } - _ => () - } - match (src.key, src.keyfp) { - (Some(_), Some(f)) => { - if smart { - url = src.url + ~"/packages.json.sig"; - } - else { - url = src.url + ~".sig"; - } - - let mut p = run::program_output(~"curl", - ~[~"-f", ~"-s", ~"-o", - sigfile.to_str(), url]); - if p.status != 0 { - error(fmt!("fetch for source %s (sig %s) failed", name, url)); - return false; - } - - let r = pgp::verify(&c.root, &pkgfile, &sigfile); - - if !r { - error(fmt!("signature verification failed for source %s with \ - key %s", name, f)); - return false; - } - - if smart && has_src_file { - url = src.url + ~"/source.json.sig"; - - p = run::program_output(~"curl", - ~[~"-f", ~"-s", ~"-o", - srcsigfile.to_str(), url]); - if p.status != 0 { - error(fmt!("fetch for source %s (sig %s) failed", - name, url)); - return false; - } - - let e = pgp::verify(&c.root, &srcfile, &srcsigfile); - - if !e { - error(~"signature verification failed for " + - ~"source " + name + ~" with key " + f); - return false; - } - } - } - _ => () - } - - copy_warn(&pkgfile, &destpkgfile); - - if smart && has_src_file { - copy_warn(&srcfile, &destsrcfile); - } - - os::remove_file(&keyfile); - os::remove_file(&srcfile); - os::remove_file(&srcsigfile); - os::remove_file(&pkgfile); - os::remove_file(&sigfile); - - info(fmt!("synced source: %s", name)); - - return true; -} - -pub fn sync_one(c: &Cargo, src: @Source) { - let name = src.name; - let dir = c.sourcedir.push(name); - - info(fmt!("syncing source: %s...", name)); - - need_dir(&dir); - - let result = match src.method { - ~"git" => sync_one_git(c, &dir, src), - ~"file" => sync_one_file(c, &dir, src), - _ => sync_one_curl(c, &dir, src) - }; - - if result { - load_source_info(c, src); - load_source_packages(c, src); - } -} - -pub fn cmd_init(c: &Cargo) { - let srcurl = ~"http://www.rust-lang.org/cargo/sources.json"; - let sigurl = ~"http://www.rust-lang.org/cargo/sources.json.sig"; - - let srcfile = c.root.push("sources.json.new"); - let sigfile = c.root.push("sources.json.sig"); - let destsrcfile = c.root.push("sources.json"); - - let p = - run::program_output(~"curl", ~[~"-f", ~"-s", - ~"-o", srcfile.to_str(), srcurl]); - if p.status != 0 { - error(fmt!("fetch of sources.json failed: %s", p.out)); - return; - } - - let p = - run::program_output(~"curl", ~[~"-f", ~"-s", - ~"-o", sigfile.to_str(), sigurl]); - if p.status != 0 { - error(fmt!("fetch of sources.json.sig failed: %s", p.out)); - return; - } - - let r = pgp::verify(&c.root, &srcfile, &sigfile); - if !r { - error(fmt!("signature verification failed for '%s'", - srcfile.to_str())); - return; - } - - copy_warn(&srcfile, &destsrcfile); - os::remove_file(&srcfile); - os::remove_file(&sigfile); - - info(fmt!("initialized .cargo in %s", c.root.to_str())); -} - -pub fn print_pkg(s: @Source, p: &Package) { - let mut m = s.name + ~"/" + p.name + ~" (" + p.uuid + ~")"; - if vec::len(p.tags) > 0u { - m = m + ~" [" + str::connect(p.tags, ~", ") + ~"]"; - } - info(m); - if p.description != ~"" { - print(~" >> " + p.description + ~"\n") - } -} - -pub fn print_source(s: @Source) { - info(s.name + ~" (" + s.url + ~")"); - - let pks = sort::merge_sort(s.packages.get(), sys::shape_lt); - let l = vec::len(pks); - - print(io::with_str_writer(|writer| { - let mut list = ~" >> "; - - for vec::eachi(pks) |i, pk| { - if str::len(list) > 78u { - writer.write_line(list); - list = ~" >> "; - } - list += pk.name + (if l - 1u == i { ~"" } else { ~", " }); - } - - writer.write_line(list); - })); -} - -pub fn cmd_list(c: &Cargo) { - sync(c); - - if vec::len(c.opts.free) >= 3u { - let v = vec::view(c.opts.free, 2u, vec::len(c.opts.free)); - for vec::each(v) |name| { - if !valid_pkg_name(*name) { - error(fmt!("'%s' is an invalid source name", *name)); - } else { - match c.sources.find(name) { - Some(source) => { - print_source(source); - } - None => { - error(fmt!("no such source: %s", *name)); - } - } - } - } - } else { - for c.sources.each_value |&v| { - print_source(v); - } - } -} - -pub fn cmd_search(c: &Cargo) { - if vec::len(c.opts.free) < 3u { - cmd_usage(); - return; - } - - sync(c); - - let mut n = 0; - let name = c.opts.free[2]; - let tags = vec::slice(c.opts.free, 3u, vec::len(c.opts.free)); - for_each_package(c, |s, p| { - if (str::contains(p.name, name) || name == ~"*") && - vec::all(tags, |t| vec::contains(p.tags, t) ) { - print_pkg(s, p); - n += 1; - } - }); - info(fmt!("found %d packages", n)); -} - -pub fn install_to_dir(srcfile: &Path, destdir: &Path) { - let newfile = destdir.push(srcfile.filename().get()); - - let status = run::run_program(~"cp", ~[~"-r", srcfile.to_str(), - newfile.to_str()]); - if status == 0 { - info(fmt!("installed: '%s'", newfile.to_str())); - } else { - error(fmt!("could not install: '%s'", newfile.to_str())); - } -} - -pub fn dump_cache(c: &Cargo) { - need_dir(&c.root); - - let out = c.root.push("cache.json"); - let _root = json::Object(~LinearMap::new()); - - if os::path_exists(&out) { - copy_warn(&out, &c.root.push("cache.json.old")); - } -} - -pub fn dump_sources(c: &Cargo) { - if c.sources.is_empty() { - return; - } - - need_dir(&c.root); - - let out = c.root.push("sources.json"); - - if os::path_exists(&out) { - copy_warn(&out, &c.root.push("sources.json.old")); - } - - match io::buffered_file_writer(&out) { - result::Ok(writer) => { - let mut hash = ~LinearMap::new(); - - for c.sources.each |&k, &v| { - let mut chash = ~LinearMap::new(); - - chash.insert(~"url", json::String(v.url)); - chash.insert(~"method", json::String(v.method)); - - match copy v.key { - Some(key) => { - chash.insert(~"key", json::String(copy key)); - } - _ => () - } - match copy v.keyfp { - Some(keyfp) => { - chash.insert(~"keyfp", json::String(copy keyfp)); - } - _ => () - } - - hash.insert(copy k, json::Object(move chash)); - } - - json::to_writer(writer, &json::Object(move hash)) - } - result::Err(e) => { - error(fmt!("could not dump sources: %s", e)); - } - } -} - -pub fn copy_warn(srcfile: &Path, destfile: &Path) { - if !os::copy_file(srcfile, destfile) { - warn(fmt!("copying %s to %s failed", - srcfile.to_str(), destfile.to_str())); - } -} - -pub fn cmd_sources(c: &Cargo) { - if vec::len(c.opts.free) < 3u { - for c.sources.each_value |&v| { - info(fmt!("%s (%s) via %s", - v.name, v.url, v.method)); - } - return; - } - - let action = c.opts.free[2u]; - - match action { - ~"clear" => { - for c.sources.each_key |&k| { - c.sources.remove(&k); - } - - info(~"cleared sources"); - } - ~"add" => { - if vec::len(c.opts.free) < 5u { - cmd_usage(); - return; - } - - let name = c.opts.free[3u]; - let url = c.opts.free[4u]; - - if !valid_pkg_name(name) { - error(fmt!("'%s' is an invalid source name", name)); - return; - } - - if c.sources.contains_key(&name) { - error(fmt!("source already exists: %s", name)); - } else { - c.sources.insert(name, @Source { - name: name, - mut url: url, - mut method: assume_source_method(url), - mut key: None, - mut keyfp: None, - packages: DVec() - }); - info(fmt!("added source: %s", name)); - } - } - ~"remove" => { - if vec::len(c.opts.free) < 4u { - cmd_usage(); - return; - } - - let name = c.opts.free[3u]; - - if !valid_pkg_name(name) { - error(fmt!("'%s' is an invalid source name", name)); - return; - } - - if c.sources.contains_key(&name) { - c.sources.remove(&name); - info(fmt!("removed source: %s", name)); - } else { - error(fmt!("no such source: %s", name)); - } - } - ~"set-url" => { - if vec::len(c.opts.free) < 5u { - cmd_usage(); - return; - } - - let name = c.opts.free[3u]; - let url = c.opts.free[4u]; - - if !valid_pkg_name(name) { - error(fmt!("'%s' is an invalid source name", name)); - return; - } - - match c.sources.find(&name) { - Some(source) => { - let old = copy source.url; - let method = assume_source_method(url); - - source.url = url; - source.method = method; - - c.sources.insert(name, source); - - info(fmt!("changed source url: '%s' to '%s'", old, url)); - } - None => { - error(fmt!("no such source: %s", name)); - } - } - } - ~"set-method" => { - if vec::len(c.opts.free) < 5u { - cmd_usage(); - return; - } - - let name = c.opts.free[3u]; - let method = c.opts.free[4u]; - - if !valid_pkg_name(name) { - error(fmt!("'%s' is an invalid source name", name)); - return; - } - - match c.sources.find(&name) { - Some(source) => { - let old = copy source.method; - - source.method = match method { - ~"git" => ~"git", - ~"file" => ~"file", - _ => ~"curl" - }; - - c.sources.insert(name, source); - - info(fmt!("changed source method: '%s' to '%s'", old, - method)); - } - None => { - error(fmt!("no such source: %s", name)); - } - } - } - ~"rename" => { - if vec::len(c.opts.free) < 5u { - cmd_usage(); - return; - } - - let name = c.opts.free[3u]; - let newn = c.opts.free[4u]; - - if !valid_pkg_name(name) { - error(fmt!("'%s' is an invalid source name", name)); - return; - } - if !valid_pkg_name(newn) { - error(fmt!("'%s' is an invalid source name", newn)); - return; - } - - match c.sources.find(&name) { - Some(source) => { - c.sources.remove(&name); - c.sources.insert(newn, source); - info(fmt!("renamed source: %s to %s", name, newn)); - } - None => { - error(fmt!("no such source: %s", name)); - } - } - } - _ => cmd_usage() - } -} - -pub fn cmd_usage() { - print(~"Usage: cargo [options] [args..] -e.g. cargo install - -Where is one of: - init, install, list, search, sources, - uninstall, usage - -Options: - - -h, --help Display this message - -h, --help Display help for -"); -} - -pub fn cmd_usage_init() { - print(~"cargo init - -Re-initialize cargo in ~/.cargo. Clears all sources and then adds the -default sources from ."); -} - -pub fn cmd_usage_install() { - print(~"cargo install -cargo install [source/][@version] -cargo install [source/][@version] -cargo install [ref] -cargo install -cargo install - -Options: - --test Run crate tests before installing - -g Install to the user level (~/.cargo/bin/ instead of - locally in ./.cargo/bin/ by default) - -G Install to the system level (/usr/local/lib/cargo/bin/) - -Install a crate. If no arguments are supplied, it installs from -the current working directory. If a source is provided, only install -from that source, otherwise it installs from any source."); -} - -pub fn cmd_usage_uninstall() { - print(~"cargo uninstall [source/][@version] -cargo uninstall [source/][@version] -cargo uninstall [@version] -cargo uninstall [@version] - -Options: - -g Remove from the user level (~/.cargo/bin/ instead of - locally in ./.cargo/bin/ by default) - -G Remove from the system level (/usr/local/lib/cargo/bin/) - -Remove a crate. If a source is provided, only remove -from that source, otherwise it removes from any source. -If a crate was installed directly (git, tarball, etc.), you can remove -it by metadata."); -} - -pub fn cmd_usage_list() { - print(~"cargo list [sources..] - -If no arguments are provided, list all sources and their packages. -If source names are provided, list those sources and their packages. -"); -} - -pub fn cmd_usage_search() { - print(~"cargo search [tags..] - -Search packages."); -} - -pub fn cmd_usage_sources() { - print(~"cargo sources -cargo sources add -cargo sources remove -cargo sources rename -cargo sources set-url -cargo sources set-method - -If no arguments are supplied, list all sources (but not their packages). - -Commands: - add Add a source. The source method will be guessed - from the URL. - remove Remove a source. - rename Rename a source. - set-url Change the URL for a source. - set-method Change the method for a source."); -} - -pub fn main() { - let argv = os::args(); - let o = build_cargo_options(argv); - - if vec::len(o.free) < 2u { - cmd_usage(); - return; - } - if o.help { - match o.free[1] { - ~"init" => cmd_usage_init(), - ~"install" => cmd_usage_install(), - ~"uninstall" => cmd_usage_uninstall(), - ~"list" => cmd_usage_list(), - ~"search" => cmd_usage_search(), - ~"sources" => cmd_usage_sources(), - _ => cmd_usage() - } - return; - } - if o.free[1] == ~"usage" { - cmd_usage(); - return; - } - - let mut c = configure(o); - let home = c.root; - let first_time = os::path_exists(&home.push("sources.json")); - - if !first_time && o.free[1] != ~"init" { - cmd_init(&c); - - // FIXME (#2662): shouldn't need to reconfigure - c = configure(o); - } - - match o.free[1] { - ~"init" => cmd_init(&c), - ~"install" => cmd_install(&mut c), - ~"uninstall" => cmd_uninstall(&c), - ~"list" => cmd_list(&c), - ~"search" => cmd_search(&c), - ~"sources" => cmd_sources(&c), - _ => cmd_usage() - } - - dump_cache(&c); - dump_sources(&c); -} - diff --git a/src/libcargo/pgp.rs b/src/libcargo/pgp.rs deleted file mode 100644 index 364effcd32f48..0000000000000 --- a/src/libcargo/pgp.rs +++ /dev/null @@ -1,115 +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. - -use core::os; -use core::path::Path; -use core::run; - -pub fn gpgv(args: ~[~str]) -> run::ProgramOutput { - return run::program_output(~"gpgv", args); -} - -pub fn signing_key() -> ~str { - ~" ------BEGIN PGP PUBLIC KEY BLOCK----- -Version: SKS 1.1.0 - -mQINBE7dQY0BEADYs5pHqXQugXjmgRTj0AzE3F4HAEJAiUBechVOmCgNcnW4dyb6bgj7Ctqs -Td/ZDSZkFwmsIqpwfGxMr+s9VA3PW+sEMDZPY+p8w3kvFPo/L2eRjSnQ+cPffdUPo+IXl96d -N/49iXs6/d7PHw+pYszdgCfpPAAo4TtLJLVCWRs1ETSbZBIUOFywgE5P71egYVMgYKndRM5K -cY0ZUsGUX9InpItuD3R7vFwDL9cUHBonOJoax+rYeM7eLQvNncl4YAwJsUKOVDBy28QK2wmz -R6MsBTX8+vRkj3ZTCnP1+RBNllViYnq6absnAgHFdQ6OL4T2wKhAaYhukE1foFTNNI1wAm4s -iYAI20Me+54xMQZa3QvrokL/Wf9+qeajEDOTZWs1T3Sn+H3Dg3T25b8WOH3ULZE7R4FPr0Id -5u95nxKG2D2fkMXDwc0BeG+VWh3lCdjOBn2kyT+6TwM9d+/VQmY4vZdZFhI6nCUlxeKEg4wk -HW6kad5QPcUlS/3flNHM0bVLPrmNDb61bm+2sYPpgw0iy7JA5m8MceG57jS7q6Mo001cIya8 -EqrfBLZ0/0eLyIH81/RjFYwEoI54+QWe0ovdsqNTVnQsCcZnIRFTbMQqdInuCqrROIn+00xe -L0KNMh0iQO4zRaG0XhQaUxt2mIbkA0PuntsM8+I9DUIAqXgttwARAQABtERSdXN0IExhbmd1 -YWdlIChUYWcgYW5kIFJlbGVhc2UgU2lnbmluZyBLZXkpIDxydXN0LWtleUBydXN0LWxhbmcu -b3JnPokCPgQTAQIAKAUCTt1BjQIbAwUJAeEzgAYLCQgHAwIGFQgCCQoLBBYCAwECHgECF4AA -CgkQCy1qKDAzY3azFg//V+IoiCurdYyS4nckMbr9gTn5SKaAtQUqMWAoJty3/lZ2jLq/9zO0 -TO9Zw0rcoVUORpl4VsGsUu0QIA53KJJLOto4hHGvDBsASm4x1o06Ftsp37YrMozRN+4capIR -Kx5uM3whSUTGponOQplj9ED3zw/FkFWF4ni2KAZMfRJQy6berIBBHNWbMtY/vneTwv0YZOah -sS23AQ958mVhOfDYYnmpEzHza9kl6le9RjmxuFX0bOOB+bHE4T3X0OmB2q4RJetwd18qRGGY -dy/e5xON13Y708gV2v4t3ZC3X+XT/+dwHHjoa6nWIxI5OU59AfnjBJIs09pHq2VYUCfdZiHL -YRTrMQkUyapjOwWV5tbCtYnCufjILk2vk1YBqj1vjco0tMH7llsEoQ4seg8NrwkZYZ8jccN9 -Aymb0ObZZgSVJCFN3akUESfh9wPDAQjmLjqWAOMNDSpnElIVAxLX1O/HNgRv7tl0Te14Goul -lhrWzTg5vPpOhSe+1SVUAUVcBwHcZl1opXCHQHfW2vkfe9w1hRBqEMOmr54TBXufxneNc/te -NuV+ZA4l9QvirmGtmQee4LQwz7d//IFGVxidsbOTVOU9hbijm/USJCK1BPqF36I2rB/8ve7h -qTwTVbvMRb8qWS2YhwRHsYrngXbun1vwwFouiW2KV5NEFNMt3pj+Rcu5Ag0ETt1BjQEQAMOf -6oCHj5ASMHCdKzSGF+ofIG3OWH7SUVRDKtJck75LyjbW/14SxNQCF6UvyjwhVWnnGmXiCED6 -cCOo9UdMhF46ojWe//mszSJRZTc0OvUpq9AIe3UA7mLHve4A+8fXBd1mpgciG8qD4vifdO4T -yvkb4dwxW+hpsenKHaM4hvQJFB1c33loEeGdfE/9svZyCO9T4FA6tdj5niLdtGtcJ6eC/6rp -53kcg4RLz9hOH39ouitqIHVqO/j+TW2M8kYgh1niBCGQm2kV5jeh7QUMe7TA3KHksAVqAKcJ -4TO538KswbC8MLz4+cdHpXf+kSUNnRzyndazjIF31XSyT8cDZHdfFHFkCA/4Xr7ebp+gub6R -qbCeCbds/UQ8L7NOqze9/qGuRBLTarXmvZ0AgELu/z4bPF6GyKcJjFYkMZQoAzYZfFc2pNW+ -WhWCusAz0aw+6NoZVI6bYhfY2w+kf3vebpzuKdD0Qublk5cKFCU9bV6BYqI9PbgBkErUgrgp -Zrjkc2c2u6uje0sKRxihdczr75Kikhb3M4BKQx3V5GyKdvo+61MhYurwWtyTylgMvlyL+3Bn -r0bg/vFbdwO4wgdNjR9UkjjABjuTExdnAqvf2+eBnYkuzxG60TH5At3CRTBshNUO9N0q1SGH -tGJkDOOxEZwAnUmE9jAG9CdeWxJNaUa5ABEBAAGJAiUEGAECAA8FAk7dQY0CGwwFCQHhM4AA -CgkQCy1qKDAzY3a9NBAAqpQKlFBCJV2h8GJU68OzFdxYIelhzH0KcInm6QREiUtU2+WAAyli -IbvsEL3c0hH0xykhwZx0wPmj7QQW7h5geOTvfLhNe/XMLsnlIRXBCSZKmlsZ8HfOVAXZTY61 -LM0v11eI6w0lCUC6GqWfzpph+uxUQjJ6YrGomj7nDrvj8Dp4S4UYaJc+1pcVPjO/XmZrZkb1 -6KnTm4RJcIW0iO61g7SDn8JZCmrDf9Ur+9NmRdynEeiWn9DUkbAXTKj09NiRyV+8mVmSGw4F -Jylqtk+X4WTu7qCm9C0S3ROuSSJOkCQGcE552GaS5RN9wdL/cG1PfqQjSaY0HMQzpBzV+nXa -2eFk3Bg2/qi4OghjR00Y3SQftDWI4K3opwVdsF7u9YH6PQoX4jl5DJIvtdIwwQJVaHLjVF4r -koV3ryFlL4Oq70TLwBSUlUhYoii5pokr3GdzloUWuuBa8AK5sM0RG/pybUPWK1PQnDlJJg6H -JyEC4EFfBWv2+nwt1K+vIRuCX9ZSd5YP9F4RbQjsnz7dimo5ooy3Wj7Fv7lQnQGkaUev0+hs -t9H7RfQEyREukTMxzXjKEW9EO4lJ20cif3l7Be+bw6OzKaEkVE3reZRnKxO6SejUYA7reye1 -HI1jilzwKSXuV2EmyBk3tKh9NwscT/A78pr30FxxPUg3v72raNgusTo= -=2z6P ------END PGP PUBLIC KEY BLOCK----- -" -} - -pub fn signing_key_fp() -> ~str { - ~"FE79 EDB0 3DEF B0D8 27D2 6C41 0B2D 6A28 3033 6376" -} - -pub fn supported() -> bool { - let r = gpgv(~[~"--version"]); - r.status == 0 -} - -pub fn init(root: &Path) { - let p = root.push("gpg"); - if !os::path_is_dir(&p) { - os::make_dir(&p, 0x1c0i32); - let mut p = run::start_program(~"gpg", ~[~"--homedir", - p.to_str(), - ~"--import"]); - p.input().write_str(signing_key()); - let s = p.finish(); - if s != 0 { - fail!(~"pgp init failed"); - } - } -} - -pub fn add(root: &Path, key: &Path) { - let path = root.push("gpg"); - let p = - run::program_output(~"gpg", ~[~"--homedir", path.to_str(), - ~"--import", key.to_str()]); - if p.status != 0 { - fail!(~"pgp add failed: " + p.out); - } -} - -pub fn verify(root: &Path, data: &Path, sig: &Path) -> bool { - let path = root.push("gpg"); - let res = gpgv(~[~"--homedir", path.to_str(), - ~"--keyring", ~"pubring.gpg", - ~"--verbose", - sig.to_str(), data.to_str()]); - if res.status != 0 { - return false; - } - return true; -} diff --git a/src/libcargo/sources.json b/src/libcargo/sources.json deleted file mode 100644 index 66e14f9eff7d4..0000000000000 --- a/src/libcargo/sources.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "central": { - "url": "https://raw.github.com/mozilla/cargo-central/master/packages.json" - }, - "elly": { - "url": "https://raw.github.com/elly/rust-packages/master/packages.json", - "sig": "https://raw.github.com/elly/rust-packages/master/packages.json.sig", - "key": "https://raw.github.com/elly/rust-packages/master/signing-key.gpg", - "keyfp": "4107 21C0 FF32 858F 61FF 33F6 E595 8E36 FDC8 EA00" - }, - "erickt": { - "url": "https://raw.github.com/erickt/rust-packages/master/packages.json" - } -} diff --git a/src/libcore/at_vec.rs b/src/libcore/at_vec.rs index 75db5359e2e31..57bd8a97b5db9 100644 --- a/src/libcore/at_vec.rs +++ b/src/libcore/at_vec.rs @@ -30,11 +30,6 @@ pub extern mod rustrt { ++n: libc::size_t); } -#[abi = "rust-intrinsic"] -pub extern mod rusti { - pub fn move_val_init(dst: &mut T, -src: T); -} - /// Returns the number of elements the vector can hold without reallocating #[inline(always)] pub pure fn capacity(v: @[const T]) -> uint { @@ -101,7 +96,7 @@ pub pure fn build_sized_opt(size: Option, // Appending #[inline(always)] -pub pure fn append(lhs: @[T], rhs: &[const T]) -> @[T] { +pub pure fn append(lhs: @[T], rhs: &[const T]) -> @[T] { do build_sized(lhs.len() + rhs.len()) |push| { for vec::each(lhs) |x| { push(*x); } for uint::range(0, rhs.len()) |i| { push(rhs[i]); } @@ -137,7 +132,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 pure fn from_elem(n_elts: uint, t: T) -> @[T] { do build_sized(n_elts) |push| { let mut i: uint = 0u; while i < n_elts { push(copy t); i += 1u; } @@ -173,7 +168,7 @@ pub mod traits { use kinds::Copy; use ops::Add; - pub impl @[T] : Add<&[const T],@[T]> { + pub impl Add<&[const T],@[T]> for @[T] { #[inline(always)] pure fn add(&self, rhs: & &self/[const T]) -> @[T] { append(*self, (*rhs)) @@ -185,9 +180,10 @@ pub mod traits { pub mod traits {} pub mod raw { - use at_vec::{capacity, rusti, rustrt}; + use at_vec::{capacity, rustrt}; use cast::transmute; use libc; + use private::intrinsics::{move_val_init}; use ptr::addr_of; use ptr; use sys; @@ -229,12 +225,12 @@ pub mod raw { (**repr).unboxed.fill += sys::size_of::(); let p = addr_of(&((**repr).unboxed.data)); let p = ptr::offset(p, fill) as *mut T; - rusti::move_val_init(&mut(*p), move initval); + move_val_init(&mut(*p), initval); } pub unsafe fn push_slow(v: &mut @[const T], initval: T) { reserve_at_least(&mut *v, v.len() + 1u); - push_fast(v, move initval); + push_fast(v, initval); } /** diff --git a/src/libcore/cast.rs b/src/libcore/cast.rs index 14cc79ceaffed..22ed4f7694310 100644 --- a/src/libcore/cast.rs +++ b/src/libcore/cast.rs @@ -29,7 +29,7 @@ pub unsafe fn reinterpret_cast(src: &T) -> U { * reinterpret_cast on pointer types. */ #[inline(always)] -pub unsafe fn forget(thing: T) { rusti::forget(move thing); } +pub unsafe fn forget(thing: T) { rusti::forget(thing); } /** * Force-increment the reference count on a shared box. If used @@ -37,7 +37,7 @@ pub unsafe fn forget(thing: T) { rusti::forget(move thing); } * and/or reinterpret_cast when such calls would otherwise scramble a box's * reference count */ -pub unsafe fn bump_box_refcount(t: @T) { forget(move t); } +pub unsafe fn bump_box_refcount(t: @T) { forget(t); } /** * Transform a value of one type into a value of another type. @@ -50,23 +50,23 @@ pub unsafe fn bump_box_refcount(t: @T) { forget(move t); } #[inline(always)] pub unsafe fn transmute(thing: L) -> G { let newthing: G = reinterpret_cast(&thing); - forget(move thing); - move newthing + forget(thing); + newthing } /// Coerce an immutable reference to be mutable. #[inline(always)] -pub unsafe fn transmute_mut(ptr: &a/T) -> &a/mut T { transmute(move ptr) } +pub unsafe fn transmute_mut(ptr: &a/T) -> &a/mut T { transmute(ptr) } /// Coerce a mutable reference to be immutable. #[inline(always)] pub unsafe fn transmute_immut(ptr: &a/mut T) -> &a/T { - transmute(move ptr) + transmute(ptr) } /// Coerce a borrowed pointer to have an arbitrary associated region. #[inline(always)] -pub unsafe fn transmute_region(ptr: &a/T) -> &b/T { transmute(move ptr) } +pub unsafe fn transmute_region(ptr: &a/T) -> &b/T { transmute(ptr) } /// Coerce an immutable reference to be mutable. #[inline(always)] @@ -83,7 +83,7 @@ pub unsafe fn transmute_immut_unsafe(ptr: *const T) -> *T { /// Coerce a borrowed mutable pointer to have an arbitrary associated region. #[inline(always)] pub unsafe fn transmute_mut_region(ptr: &a/mut T) -> &b/mut T { - transmute(move ptr) + transmute(ptr) } /// Transforms lifetime of the second pointer to match the first. @@ -132,9 +132,9 @@ pub mod tests { use managed::raw::BoxRepr; unsafe { let x = @100u8; - let x: *BoxRepr = transmute(move x); + let x: *BoxRepr = transmute(x); assert (*x).data == 100; - let _x: @int = transmute(move x); + let _x: @int = transmute(x); } } diff --git a/src/libcore/cleanup.rs b/src/libcore/cleanup.rs index 11a4cad5d1bbb..567d6da23a68c 100644 --- a/src/libcore/cleanup.rs +++ b/src/libcore/cleanup.rs @@ -111,45 +111,102 @@ struct Task { * This runs at task death to free all boxes. */ +struct AnnihilateStats { + n_total_boxes: uint, + n_unique_boxes: uint, + n_bytes_freed: uint +} + +unsafe fn each_live_alloc(f: fn(box: *mut BoxRepr, uniq: bool) -> bool) { + use managed; + + let task: *Task = transmute(rustrt::rust_get_task()); + let box = (*task).boxed_region.live_allocs; + let mut box: *mut BoxRepr = transmute(copy box); + while box != mut_null() { + let next = transmute(copy (*box).header.next); + let uniq = + (*box).header.ref_count == managed::raw::RC_MANAGED_UNIQUE; + + if ! f(box, uniq) { + break + } + + box = next + } +} + +#[cfg(unix)] +fn debug_mem() -> bool { + use os; + use libc; + do os::as_c_charp("RUST_DEBUG_MEM") |p| { + unsafe { libc::getenv(p) != null() } + } +} + +#[cfg(windows)] +fn debug_mem() -> bool { + false +} + /// Destroys all managed memory (i.e. @ boxes) held by the current task. #[cfg(notest)] #[lang="annihilate"] pub unsafe fn annihilate() { use rt::rt_free; use io::WriterUtil; + use io; + use libc; + use sys; + use managed; - let task: *Task = transmute(rustrt::rust_get_task()); + let mut stats = AnnihilateStats { + n_total_boxes: 0, + n_unique_boxes: 0, + n_bytes_freed: 0 + }; // Pass 1: Make all boxes immortal. - let box = (*task).boxed_region.live_allocs; - let mut box: *mut BoxRepr = transmute(copy box); - while box != mut_null() { - debug!("making box immortal: %x", box as uint); - (*box).header.ref_count = 0x77777777; - box = transmute(copy (*box).header.next); + for each_live_alloc |box, uniq| { + stats.n_total_boxes += 1; + if uniq { + stats.n_unique_boxes += 1; + } else { + (*box).header.ref_count = managed::raw::RC_IMMORTAL; + } } // Pass 2: Drop all boxes. - let box = (*task).boxed_region.live_allocs; - let mut box: *mut BoxRepr = transmute(copy box); - while box != mut_null() { - debug!("calling drop glue for box: %x", box as uint); - let tydesc: *TypeDesc = transmute(copy (*box).header.type_desc); - let drop_glue: DropGlue = transmute(((*tydesc).drop_glue, 0)); - drop_glue(to_unsafe_ptr(&tydesc), transmute(&(*box).data)); - - box = transmute(copy (*box).header.next); + for each_live_alloc |box, uniq| { + if !uniq { + let tydesc: *TypeDesc = transmute(copy (*box).header.type_desc); + let drop_glue: DropGlue = transmute(((*tydesc).drop_glue, 0)); + drop_glue(to_unsafe_ptr(&tydesc), transmute(&(*box).data)); + } } // Pass 3: Free all boxes. - loop { - let box = (*task).boxed_region.live_allocs; - if box == null() { break; } - let mut box: *mut BoxRepr = transmute(copy box); - assert (*box).header.prev == null(); - - debug!("freeing box: %x", box as uint); - rt_free(transmute(box)); + for each_live_alloc |box, uniq| { + if !uniq { + stats.n_bytes_freed += + (*((*box).header.type_desc)).size + + sys::size_of::(); + rt_free(transmute(box)); + } + } + + if debug_mem() { + // We do logging here w/o allocation. + let dbg = libc::STDERR_FILENO as io::fd_t; + dbg.write_str("annihilator stats:"); + dbg.write_str("\n total_boxes: "); + dbg.write_uint(stats.n_total_boxes); + dbg.write_str("\n unique_boxes: "); + dbg.write_uint(stats.n_unique_boxes); + dbg.write_str("\n bytes_freed: "); + dbg.write_uint(stats.n_bytes_freed); + dbg.write_str("\n"); } } diff --git a/src/libcore/cmp.rs b/src/libcore/cmp.rs index 7cd4d4c9bc3b2..fd99235bd270c 100644 --- a/src/libcore/cmp.rs +++ b/src/libcore/cmp.rs @@ -56,41 +56,41 @@ pub trait Ord { } #[inline(always)] -pub pure fn lt(v1: &T, v2: &T) -> bool { +pub pure fn lt(v1: &T, v2: &T) -> bool { (*v1).lt(v2) } #[inline(always)] -pub pure fn le(v1: &T, v2: &T) -> bool { +pub pure fn le(v1: &T, v2: &T) -> bool { (*v1).le(v2) } #[inline(always)] -pub pure fn eq(v1: &T, v2: &T) -> bool { +pub pure fn eq(v1: &T, v2: &T) -> bool { (*v1).eq(v2) } #[inline(always)] -pub pure fn ne(v1: &T, v2: &T) -> bool { +pub pure fn ne(v1: &T, v2: &T) -> bool { (*v1).ne(v2) } #[inline(always)] -pub pure fn ge(v1: &T, v2: &T) -> bool { +pub pure fn ge(v1: &T, v2: &T) -> bool { (*v1).ge(v2) } #[inline(always)] -pub pure fn gt(v1: &T, v2: &T) -> bool { +pub pure fn gt(v1: &T, v2: &T) -> bool { (*v1).gt(v2) } #[inline(always)] -pub pure fn min(v1: T, v2: T) -> T { +pub pure 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 pure fn max(v1: T, v2: T) -> T { if v1 > v2 { v1 } else { v2 } } diff --git a/src/libcore/comm.rs b/src/libcore/comm.rs new file mode 100644 index 0000000000000..7939644e51cb9 --- /dev/null +++ b/src/libcore/comm.rs @@ -0,0 +1,410 @@ +// 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. + +// Transitional -- needs snapshot +#[allow(structural_records)]; + +use either::{Either, Left, Right}; +use kinds::Owned; +use option; +use option::{Option, Some, None, unwrap}; +use private; +use vec; + +use pipes::{recv, try_recv, wait_many, peek, PacketHeader}; + +// NOTE Making this public exposes some plumbing from pipes. Needs +// some refactoring +pub use pipes::Selectable; + +/// A trait for things that can send multiple messages. +pub trait GenericChan { + /// Sends a message. + fn send(x: T); +} + +/// Things that can send multiple messages and can detect when the receiver +/// is closed +pub trait GenericSmartChan { + /// Sends a message, or report if the receiver has closed the connection. + fn try_send(x: T) -> bool; +} + +/// A trait for things that can receive multiple messages. +pub trait GenericPort { + /// Receives a message, or fails if the connection closes. + fn recv() -> T; + + /** Receives a message, or returns `none` if + the connection is closed or closes. + */ + fn try_recv() -> Option; +} + +/// Ports that can `peek` +pub trait Peekable { + /// Returns true if a message is available + pure fn peek() -> bool; +} + +/// Returns the index of an endpoint that is ready to receive. +pub fn selecti(endpoints: &[T]) -> uint { + wait_many(endpoints) +} + +/// Returns 0 or 1 depending on which endpoint is ready to receive +pub fn select2i(a: &A, b: &B) -> + Either<(), ()> { + match wait_many([a.header(), b.header()]) { + 0 => Left(()), + 1 => Right(()), + _ => fail!(~"wait returned unexpected index") + } +} + +// Streams - Make pipes a little easier in general. + +proto! streamp ( + Open:send { + data(T) -> Open + } +) + +#[doc(hidden)] +struct Chan_ { + mut endp: Option> +} + +/// An endpoint that can send many messages. +pub enum Chan { + Chan_(Chan_) +} + +struct Port_ { + mut endp: Option>, +} + +/// An endpoint that can receive many messages. +pub enum Port { + Port_(Port_) +} + +/** Creates a `(chan, port)` pair. + +These allow sending or receiving an unlimited number of messages. + +*/ +pub fn stream() -> (Port, Chan) { + let (c, s) = streamp::init(); + + (Port_(Port_ { endp: Some(s) }), Chan_(Chan_{ endp: Some(c) })) +} + +impl GenericChan for Chan { + fn send(x: T) { + let mut endp = None; + endp <-> self.endp; + self.endp = Some( + streamp::client::data(unwrap(endp), x)) + } +} + +impl GenericSmartChan for Chan { + + fn try_send(x: T) -> bool { + let mut endp = None; + endp <-> self.endp; + match streamp::client::try_data(unwrap(endp), x) { + Some(next) => { + self.endp = Some(next); + true + } + None => false + } + } +} + +impl GenericPort for Port { + fn recv() -> T { + let mut endp = None; + endp <-> self.endp; + let streamp::data(x, endp) = recv(unwrap(endp)); + self.endp = Some(endp); + x + } + + fn try_recv() -> Option { + let mut endp = None; + endp <-> self.endp; + match try_recv(unwrap(endp)) { + Some(streamp::data(x, endp)) => { + self.endp = Some(endp); + Some(x) + } + None => None + } + } +} + +impl Peekable for Port { + pure fn peek() -> bool { + unsafe { + let mut endp = None; + endp <-> self.endp; + let peek = match &endp { + &Some(ref endp) => peek(endp), + &None => fail!(~"peeking empty stream") + }; + self.endp <-> endp; + peek + } + } +} + +impl Selectable for Port { + pure fn header() -> *PacketHeader { + unsafe { + match self.endp { + Some(ref endp) => endp.header(), + None => fail!(~"peeking empty stream") + } + } + } +} + +/// Treat many ports as one. +pub struct PortSet { + mut ports: ~[Port], +} + +pub fn PortSet() -> PortSet{ + PortSet { + ports: ~[] + } +} + +impl PortSet { + + fn add(port: Port) { + self.ports.push(port) + } + + fn chan() -> Chan { + let (po, ch) = stream(); + self.add(po); + ch + } +} + +impl GenericPort for PortSet { + + fn try_recv() -> Option { + let mut result = None; + // we have to swap the ports array so we aren't borrowing + // aliasable mutable memory. + let mut ports = ~[]; + ports <-> self.ports; + while result.is_none() && ports.len() > 0 { + let i = wait_many(ports); + match ports[i].try_recv() { + Some(m) => { + result = Some(m); + } + None => { + // Remove this port. + let _ = ports.swap_remove(i); + } + } + } + ports <-> self.ports; + result + } + + fn recv() -> T { + self.try_recv().expect("port_set: endpoints closed") + } + +} + +impl Peekable for PortSet { + pure fn peek() -> bool { + // It'd be nice to use self.port.each, but that version isn't + // pure. + for vec::each(self.ports) |p| { + if p.peek() { return true } + } + false + } +} + +/// A channel that can be shared between many senders. +pub type SharedChan = private::Exclusive>; + +impl GenericChan for SharedChan { + fn send(x: T) { + let mut xx = Some(x); + do self.with_imm |chan| { + let mut x = None; + x <-> xx; + chan.send(option::unwrap(x)) + } + } +} + +impl GenericSmartChan for SharedChan { + fn try_send(x: T) -> bool { + let mut xx = Some(x); + do self.with_imm |chan| { + let mut x = None; + x <-> xx; + chan.try_send(option::unwrap(x)) + } + } +} + +/// Converts a `chan` into a `shared_chan`. +pub fn SharedChan(c: Chan) -> SharedChan { + private::exclusive(c) +} + +/// Receive a message from one of two endpoints. +pub trait Select2 { + /// Receive a message or return `None` if a connection closes. + fn try_select() -> Either, Option>; + /// Receive a message or fail if a connection closes. + fn select() -> Either; +} + +impl, + Right: Selectable + GenericPort> + Select2 for (Left, Right) { + + fn select() -> Either { + match self { + (ref lp, ref rp) => match select2i(lp, rp) { + Left(()) => Left (lp.recv()), + Right(()) => Right(rp.recv()) + } + } + } + + fn try_select() -> Either, Option> { + match self { + (ref lp, ref rp) => match select2i(lp, rp) { + Left(()) => Left (lp.try_recv()), + Right(()) => Right(rp.try_recv()) + } + } + } +} + +proto! oneshot ( + Oneshot:send { + send(T) -> ! + } +) + +/// The send end of a oneshot pipe. +pub type ChanOne = oneshot::client::Oneshot; +/// The receive end of a oneshot pipe. +pub type PortOne = oneshot::server::Oneshot; + +/// Initialiase a (send-endpoint, recv-endpoint) oneshot pipe pair. +pub fn oneshot() -> (PortOne, ChanOne) { + let (chan, port) = oneshot::init(); + (port, chan) +} + +impl PortOne { + fn recv(self) -> T { recv_one(self) } + fn try_recv(self) -> Option { try_recv_one(self) } +} + +impl ChanOne { + fn send(self, data: T) { send_one(self, data) } + fn try_send(self, data: T) -> bool { try_send_one(self, data) } +} + +/** + * Receive a message from a oneshot pipe, failing if the connection was + * closed. + */ +pub fn recv_one(port: PortOne) -> T { + let oneshot::send(message) = recv(port); + message +} + +/// Receive a message from a oneshot pipe unless the connection was closed. +pub fn try_recv_one (port: PortOne) -> Option { + let message = try_recv(port); + + if message.is_none() { None } + else { + let oneshot::send(message) = option::unwrap(message); + Some(message) + } +} + +/// Send a message on a oneshot pipe, failing if the connection was closed. +pub fn send_one(chan: ChanOne, data: T) { + oneshot::client::send(chan, data); +} + +/** + * Send a message on a oneshot pipe, or return false if the connection was + * closed. + */ +pub fn try_send_one(chan: ChanOne, data: T) + -> bool { + oneshot::client::try_send(chan, data).is_some() +} + +#[cfg(test)] +pub mod test { + use either::{Either, Left, Right}; + use super::{Chan, Port, oneshot, recv_one, stream}; + + #[test] + pub fn test_select2() { + let (p1, c1) = stream(); + let (p2, c2) = stream(); + + c1.send(~"abc"); + + match (p1, p2).select() { + Right(_) => fail!(), + _ => () + } + + c2.send(123); + } + + #[test] + pub fn test_oneshot() { + let (c, p) = oneshot::init(); + + oneshot::client::send(c, ()); + + recv_one(p) + } + + #[test] + fn test_peek_terminated() { + let (port, chan): (Port, Chan) = stream(); + + { + // Destroy the channel + let _chan = chan; + } + + assert !port.peek(); + } +} diff --git a/src/libcore/core.rc b/src/libcore/core.rc index 5b6c40e09ef07..01669557389ae 100644 --- a/src/libcore/core.rc +++ b/src/libcore/core.rc @@ -148,6 +148,7 @@ pub mod hashmap; #[path = "task/mod.rs"] pub mod task; +pub mod comm; pub mod pipes; @@ -170,7 +171,6 @@ pub mod condition; pub mod logging; pub mod util; - /* Reexported core operators */ pub use kinds::{Const, Copy, Owned, Durable}; @@ -226,6 +226,8 @@ pub const debug : u32 = 4_u32; // The runtime interface used by the compiler #[cfg(notest)] pub mod rt; // The runtime and compiler interface to fmt! +#[cfg(stage0)] +#[path = "private/extfmt.rs"] pub mod extfmt; // Private APIs pub mod private; @@ -254,6 +256,7 @@ pub mod core { pub use option; pub use kinds; pub use sys; + pub use pipes; } diff --git a/src/libcore/dlist.rs b/src/libcore/dlist.rs index 0af0ecb16aa10..3580736488926 100644 --- a/src/libcore/dlist.rs +++ b/src/libcore/dlist.rs @@ -106,7 +106,7 @@ pub pure fn from_elem(data: T) -> @mut DList { list } -pub fn from_vec(vec: &[T]) -> @mut DList { +pub fn from_vec(vec: &[T]) -> @mut DList { do vec::foldl(DList(), vec) |list,data| { list.push(*data); // Iterating left-to-right -- add newly to the tail. list @@ -457,7 +457,7 @@ impl DList { } } -impl DList { +impl DList { /// Remove data from the head of the list. O(1). fn pop(@mut self) -> Option { self.pop_n().map(|nobe| nobe.data) @@ -493,7 +493,7 @@ impl DList { v[index] = *data; } } - move v + v } } diff --git a/src/libcore/dvec.rs b/src/libcore/dvec.rs index 0a96bd633d1ef..7651b737bf34e 100644 --- a/src/libcore/dvec.rs +++ b/src/libcore/dvec.rs @@ -67,18 +67,18 @@ pub pure fn DVec() -> DVec { /// Creates a new dvec with a single element pub pure fn from_elem(e: A) -> DVec { - DVec {mut data: ~[move e]} + DVec {mut data: ~[e]} } /// Creates a new dvec with the contents of a vector pub pure fn from_vec(v: ~[A]) -> DVec { - DVec {mut data: move v} + DVec {mut data: v} } /// Consumes the vector and returns its contents pub pure fn unwrap(d: DVec) -> ~[A] { - let DVec {data: v} = move d; - move v + let DVec {data: v} = d; + v } priv impl DVec { @@ -99,14 +99,14 @@ priv impl DVec { data <-> self.data; let data_ptr: *() = cast::reinterpret_cast(&data); if data_ptr.is_null() { fail!(~"Recursive use of dvec"); } - return f(move data); + return f(data); } } #[inline(always)] fn give_back(data: ~[A]) { unsafe { - self.data = move data; + self.data = data; } } @@ -130,7 +130,7 @@ impl DVec { */ #[inline(always)] fn swap(f: &fn(v: ~[A]) -> ~[A]) { - self.check_out(|v| self.give_back(f(move v))) + self.check_out(|v| self.give_back(f(v))) } /** @@ -141,7 +141,7 @@ impl DVec { #[inline(always)] fn swap_mut(f: &fn(v: ~[mut A]) -> ~[mut A]) { do self.swap |v| { - vec::cast_from_mut(f(vec::cast_to_mut(move v))) + vec::cast_from_mut(f(vec::cast_to_mut(v))) } } @@ -156,16 +156,16 @@ impl DVec { #[inline(always)] fn set(w: ~[A]) { self.check_not_borrowed(); - self.data = move w; + self.data = w; } /// Remove and return the last element fn pop() -> A { do self.check_out |v| { - let mut v = move v; + let mut v = v; let result = v.pop(); - self.give_back(move v); - move result + self.give_back(v); + result } } @@ -176,8 +176,8 @@ impl DVec { data <-> self.data; let data_ptr: *() = cast::reinterpret_cast(&data); if data_ptr.is_null() { fail!(~"Recursive use of dvec"); } - self.data = move ~[move t]; - self.data.push_all_move(move data); + self.data = ~[t]; + self.data.push_all_move(data); } } @@ -185,25 +185,25 @@ impl DVec { #[inline(always)] fn push(t: A) { self.check_not_borrowed(); - self.data.push(move t); + self.data.push(t); } /// Remove and return the first element fn shift() -> A { do self.check_out |v| { - let mut v = move v; + let mut v = v; let result = v.shift(); - self.give_back(move v); - move result + self.give_back(v); + result } } /// Reverse the elements in the list, in place fn reverse() { do self.check_out |v| { - let mut v = move v; + let mut v = v; vec::reverse(v); - self.give_back(move v); + self.give_back(v); } } @@ -211,23 +211,23 @@ impl DVec { fn borrow(op: fn(x: &[A]) -> R) -> R { do self.check_out |v| { let result = op(v); - self.give_back(move v); - move result + self.give_back(v); + result } } /// Gives access to the vector as a slice with mutable contents fn borrow_mut(op: fn(x: &[mut A]) -> R) -> R { do self.check_out |v| { - let mut v = move v; + let mut v = v; let result = op(v); - self.give_back(move v); - move result + self.give_back(v); + result } } } -impl DVec { +impl DVec { /** * Append all elements of a vector to the end of the list * @@ -240,7 +240,7 @@ impl DVec { /// Appends elements from `from_idx` to `to_idx` (exclusive) fn push_slice(ts: &[const A], from_idx: uint, to_idx: uint) { do self.swap |v| { - let mut v = move v; + let mut v = v; let new_len = vec::len(v) + to_idx - from_idx; vec::reserve(&mut v, new_len); let mut i = from_idx; @@ -248,7 +248,7 @@ impl DVec { v.push(ts[i]); i += 1u; } - move v + v } } @@ -265,7 +265,7 @@ impl DVec { none { v } Some(h) { let len = v.len() + h; - let mut v = move v; + let mut v = v; vec::reserve(v, len); v } @@ -286,8 +286,8 @@ impl DVec { unsafe { do self.check_out |v| { let w = copy v; - self.give_back(move v); - move w + self.give_back(v); + w } } } @@ -312,9 +312,9 @@ impl DVec { */ fn grow_set_elt(idx: uint, initval: &A, val: A) { do self.swap |v| { - let mut v = move v; + let mut v = v; v.grow_set(idx, initval, val); - move v + v } } @@ -340,7 +340,7 @@ impl DVec { for vec::rev_each(v) |e| { if !f(e) { break; } } - move v + v } } @@ -353,7 +353,7 @@ impl DVec { for vec::rev_eachi(v) |i, e| { if !f(i, e) { break; } } - move v + v } } } diff --git a/src/libcore/either.rs b/src/libcore/either.rs index 54c9f7b98793b..93b28233acdd8 100644 --- a/src/libcore/either.rs +++ b/src/libcore/either.rs @@ -41,7 +41,7 @@ pub fn either(f_left: fn(&T) -> V, } } -pub fn lefts(eithers: &[Either]) -> ~[T] { +pub fn lefts(eithers: &[Either]) -> ~[T] { //! Extracts from a vector of either all the left values do vec::build_sized(eithers.len()) |push| { @@ -84,7 +84,7 @@ pub fn partition(eithers: ~[Either]) Right(r) => rights.push(r) } } - return (move lefts, move rights); + return (lefts, rights); } #[inline(always)] @@ -131,8 +131,8 @@ pub pure fn is_right(eith: &Either) -> bool { pub pure fn unwrap_left(eith: Either) -> T { //! Retrieves the value in the left branch. Fails if the either is Right. - match move eith { - Left(move x) => move x, + match eith { + Left(x) => x, Right(_) => fail!(~"either::unwrap_left Right") } } @@ -141,8 +141,8 @@ pub pure fn unwrap_left(eith: Either) -> T { pub pure fn unwrap_right(eith: Either) -> U { //! Retrieves the value in the right branch. Fails if the either is Left. - match move eith { - Right(move x) => move x, + match eith { + Right(x) => x, Left(_) => fail!(~"either::unwrap_right Left") } } diff --git a/src/libcore/flate.rs b/src/libcore/flate.rs index 6b5c083662b84..c47e27e75d950 100644 --- a/src/libcore/flate.rs +++ b/src/libcore/flate.rs @@ -50,7 +50,7 @@ pub fn deflate_bytes(bytes: &[const u8]) -> ~[u8] { let out = vec::raw::from_buf_raw(res as *u8, outsz as uint); libc::free(res); - move out + out } } } @@ -68,7 +68,7 @@ pub fn inflate_bytes(bytes: &[const u8]) -> ~[u8] { let out = vec::raw::from_buf_raw(res as *u8, outsz as uint); libc::free(res); - move out + out } } } diff --git a/src/libcore/hash.rs b/src/libcore/hash.rs index b4f4e7d343b0a..7c1448c88eef7 100644 --- a/src/libcore/hash.rs +++ b/src/libcore/hash.rs @@ -59,7 +59,7 @@ pub trait HashUtil { pure fn hash() -> u64; } -impl HashUtil for A { +impl HashUtil for A { #[inline(always)] pure fn hash() -> u64 { self.hash_keyed(0,0) } } @@ -74,7 +74,7 @@ pub trait Streaming { fn reset(); } -impl Hash for A { +impl Hash for A { #[inline(always)] pure fn hash_keyed(k0: u64, k1: u64) -> u64 { unsafe { @@ -183,7 +183,7 @@ fn SipState(key0: u64, key1: u64) -> SipState { mut ntail : 0u, }; (&state).reset(); - move state + state } @@ -352,7 +352,7 @@ impl Streaming for &SipState { for vec::each(r) |b| { s += uint::to_str_radix(*b as uint, 16u); } - move s + s } #[inline(always)] @@ -447,7 +447,7 @@ pub fn test_siphash() { for vec::each(*r) |b| { s += uint::to_str_radix(*b as uint, 16u); } - move s + s } while t < 64 { diff --git a/src/libcore/hashmap.rs b/src/libcore/hashmap.rs index 1e9f05a35ebdc..07c7780898f96 100644 --- a/src/libcore/hashmap.rs +++ b/src/libcore/hashmap.rs @@ -51,18 +51,19 @@ pub mod linear { FoundEntry(uint), FoundHole(uint), TableFull } + #[inline(always)] pure fn resize_at(capacity: uint) -> uint { ((capacity as float) * 3. / 4.) as uint } - pub fn linear_map_with_capacity( + pub fn linear_map_with_capacity( initial_capacity: uint) -> LinearMap { let r = rand::task_rng(); linear_map_with_capacity_and_keys(r.gen_u64(), r.gen_u64(), initial_capacity) } - pure fn linear_map_with_capacity_and_keys( + pure fn linear_map_with_capacity_and_keys( k0: u64, k1: u64, initial_capacity: uint) -> LinearMap { LinearMap { @@ -73,13 +74,11 @@ pub mod linear { } } - priv impl LinearMap { + priv impl LinearMap { #[inline(always)] pure fn to_bucket(&self, h: uint) -> uint { - // FIXME(#3041) borrow a more sophisticated technique here from - // Gecko, for example borrowing from Knuth, as Eich so - // colorfully argues for here: - // https://bugzilla.mozilla.org/show_bug.cgi?id=743107#c22 + // A good hash function with entropy spread over all of the + // bits is assumed. SipHash is more than good enough. h % self.buckets.len() } @@ -128,12 +127,19 @@ pub mod linear { TableFull } - /// Expands the capacity of the array and re-inserts each - /// of the existing buckets. + /// Expand the capacity of the array to the next power of two + /// and re-insert each of the existing buckets. + #[inline(always)] fn expand(&mut self) { + let new_capacity = self.buckets.len() * 2; + self.resize(new_capacity); + } + + /// Expands the capacity of the array and re-insert each of the + /// existing buckets. + fn resize(&mut self, new_capacity: uint) { let old_capacity = self.buckets.len(); - let new_capacity = old_capacity * 2; - self.resize_at = ((new_capacity as float) * 3.0 / 4.0) as uint; + self.resize_at = resize_at(new_capacity); let mut old_buckets = vec::from_fn(new_capacity, |_| None); self.buckets <-> old_buckets; @@ -159,7 +165,7 @@ pub mod linear { pure fn value_for_bucket(&self, idx: uint) -> &self/V { match self.buckets[idx] { Some(ref bkt) => &bkt.value, - None => die!(~"LinearMap::find: internal logic error"), + None => fail!(~"LinearMap::find: internal logic error"), } } @@ -240,7 +246,7 @@ pub mod linear { } } - impl BaseIter<(&K, &V)> for LinearMap { + impl BaseIter<(&K, &V)> for LinearMap { /// Visit all key-value pairs pure fn each(&self, blk: fn(&(&self/K, &self/V)) -> bool) { for uint::range(0, self.buckets.len()) |i| { @@ -257,7 +263,7 @@ pub mod linear { } - impl Container for LinearMap { + impl Container for LinearMap { /// Return the number of elements in the map pure fn len(&self) -> uint { self.size } @@ -265,7 +271,7 @@ pub mod linear { pure fn is_empty(&self) -> bool { self.len() == 0 } } - impl Mutable for LinearMap { + impl Mutable for LinearMap { /// Clear the map, removing all key-value pairs. fn clear(&mut self) { for uint::range(0, self.buckets.len()) |idx| { @@ -275,7 +281,7 @@ pub mod linear { } } - impl Map for LinearMap { + impl Map for LinearMap { /// Return true if the map contains a value for the specified key pure fn contains_key(&self, k: &K) -> bool { match self.bucket_for_key(k) { @@ -327,12 +333,20 @@ pub mod linear { } } - pub impl LinearMap { + pub impl LinearMap { /// Create an empty LinearMap static fn new() -> LinearMap { linear_map_with_capacity(INITIAL_CAPACITY) } + /// Reserve space for at least `n` elements in the hash table. + fn reserve_at_least(&mut self, n: uint) { + if n > self.buckets.len() { + let buckets = n * 4 / 3 + 1; + self.resize(uint::next_power_of_two(buckets)); + } + } + fn pop(&mut self, k: &K) -> Option { let hash = k.hash_keyed(self.k0, self.k1) as uint; self.pop_internal(hash, k) @@ -373,7 +387,7 @@ pub mod linear { let hash = k.hash_keyed(self.k0, self.k1) as uint; let idx = match self.bucket_for_key_with_hash(hash, &k) { - TableFull => die!(~"Internal logic error"), + TableFull => fail!(~"Internal logic error"), FoundEntry(idx) => idx, FoundHole(idx) => { self.buckets[idx] = Some(Bucket{hash: hash, key: k, @@ -403,7 +417,7 @@ pub mod linear { let hash = k.hash_keyed(self.k0, self.k1) as uint; let idx = match self.bucket_for_key_with_hash(hash, &k) { - TableFull => die!(~"Internal logic error"), + TableFull => fail!(~"Internal logic error"), FoundEntry(idx) => idx, FoundHole(idx) => { let v = f(&k); @@ -443,7 +457,7 @@ pub mod linear { } } - impl Eq for LinearMap { + impl Eq for LinearMap { pure fn eq(&self, other: &LinearMap) -> bool { if self.len() != other.len() { return false; } @@ -464,13 +478,13 @@ pub mod linear { priv map: LinearMap } - impl BaseIter for LinearSet { + 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()) } } - impl Eq for LinearSet { + impl Eq for LinearSet { pure fn eq(&self, other: &LinearSet) -> bool { self.map == other.map } @@ -479,7 +493,7 @@ pub mod linear { } } - impl Container for LinearSet { + impl Container for LinearSet { /// Return the number of elements in the set pure fn len(&self) -> uint { self.map.len() } @@ -487,12 +501,12 @@ pub mod linear { pure fn is_empty(&self) -> bool { self.map.is_empty() } } - impl Mutable for LinearSet { + impl Mutable for LinearSet { /// Clear the set, removing all values. fn clear(&mut self) { self.map.clear() } } - impl Set for LinearSet { + impl Set for LinearSet { /// Return true if the set contains a value pure fn contains(&self, value: &T) -> bool { self.map.contains_key(value) @@ -561,9 +575,14 @@ pub mod linear { } } - pub impl LinearSet { + pub impl LinearSet { /// Create an empty LinearSet static 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) { + self.map.reserve_at_least(n) + } } } diff --git a/src/libcore/io.rs b/src/libcore/io.rs index 2173efe5ac66f..421eb94a29128 100644 --- a/src/libcore/io.rs +++ b/src/libcore/io.rs @@ -169,7 +169,7 @@ pub trait ReaderUtil { fn read_i8(&self) -> i8; } -impl ReaderUtil for T { +impl ReaderUtil for T { fn read_bytes(&self,len: uint) -> ~[u8] { let mut bytes = vec::with_capacity(len); @@ -178,7 +178,7 @@ impl ReaderUtil for T { let count = self.read(bytes, len); unsafe { vec::raw::set_len(&mut bytes, count); } - move bytes + bytes } fn read_line(&self) -> ~str { @@ -193,7 +193,7 @@ impl ReaderUtil for T { fn read_chars(&self, n: uint) -> ~[char] { // returns the (consumed offset, n_req), appends characters to &chars - fn chars_from_bytes(bytes: &~[u8], chars: &mut ~[char]) + fn chars_from_bytes(bytes: &~[u8], chars: &mut ~[char]) -> (uint, uint) { let mut i = 0; let bytes_len = bytes.len(); @@ -246,10 +246,10 @@ impl ReaderUtil for T { // over-read by reading 1-byte per char needed nbread = if ncreq > nbreq { ncreq } else { nbreq }; if nbread > 0 { - bytes = vec::slice(bytes, offset, bytes.len()); + bytes = vec::slice(bytes, offset, bytes.len()).to_vec(); } } - move chars + chars } fn read_char(&self) -> char { @@ -273,7 +273,7 @@ impl ReaderUtil for T { fn read_whole_stream(&self) -> ~[u8] { let mut bytes: ~[u8] = ~[]; while !self.eof() { bytes.push_all(self.read_bytes(2048u)); } - move bytes + bytes } fn each_byte(&self, it: fn(int) -> bool) { @@ -460,7 +460,7 @@ struct Wrapper { // A forwarding impl of reader that also holds on to a resource for the // duration of its lifetime. // FIXME there really should be a better way to do this // #2004 -impl Reader for Wrapper { +impl Reader for Wrapper { fn read(&self, bytes: &mut [u8], len: uint) -> uint { self.base.read(bytes, len) } @@ -531,7 +531,7 @@ impl Reader for BytesReader { fn read(&self, bytes: &mut [u8], len: uint) -> uint { let count = uint::min(len, self.bytes.len() - self.pos); - let view = vec::view(self.bytes, self.pos, self.bytes.len()); + let view = vec::slice(self.bytes, self.pos, self.bytes.len()); vec::bytes::copy_memory(bytes, view, count); self.pos += count; @@ -589,7 +589,7 @@ pub trait Writer { fn get_type(&self) -> WriterType; } -impl Writer for Wrapper { +impl Writer for Wrapper { fn write(&self, bs: &[const u8]) { self.base.write(bs); } fn seek(&self, off: int, style: SeekStyle) { self.base.seek(off, style); } fn tell(&self) -> uint { self.base.tell() } @@ -890,7 +890,7 @@ pub trait WriterUtil { fn write_i8(&self, n: i8); } -impl WriterUtil for T { +impl WriterUtil for T { fn write_char(&self, ch: char) { if ch as uint < 128u { self.write(&[ch as u8]); @@ -999,7 +999,7 @@ pub struct BytesWriter { impl Writer for BytesWriter { fn write(&self, v: &[const u8]) { do self.bytes.swap |bytes| { - let mut bytes = move bytes; + let mut bytes = bytes; let v_len = v.len(); let bytes_len = bytes.len(); @@ -1008,13 +1008,13 @@ impl Writer for BytesWriter { unsafe { vec::raw::set_len(&mut bytes, count); } { - let view = vec::mut_view(bytes, self.pos, count); + let view = vec::mut_slice(bytes, self.pos, count); vec::bytes::copy_memory(view, v, v_len); } self.pos += v_len; - move bytes + bytes } } fn seek(&self, offset: int, whence: SeekStyle) { @@ -1035,7 +1035,7 @@ pub pure fn with_bytes_writer(f: fn(Writer)) -> ~[u8] { let wr = @BytesWriter(); f(wr as Writer); // FIXME (#3758): This should not be needed. - unsafe { wr.bytes.check_out(|bytes| move bytes) } + unsafe { wr.bytes.check_out(|bytes| bytes) } } pub pure fn with_str_writer(f: fn(Writer)) -> ~str { @@ -1048,7 +1048,7 @@ pub pure fn with_str_writer(f: fn(Writer)) -> ~str { } assert str::is_utf8(v); - unsafe { move ::cast::transmute(move v) } + unsafe { ::cast::transmute(v) } } // Utility functions @@ -1112,7 +1112,7 @@ pub mod fsync { arg: Arg, } - impl Drop for Res { + impl Drop for Res { fn finalize(&self) { match self.arg.opt_level { None => (), @@ -1126,7 +1126,7 @@ pub mod fsync { pub fn Res(arg: Arg) -> Res{ Res { - arg: move arg + arg: arg } } diff --git a/src/libcore/iter-trait.rs b/src/libcore/iter-trait.rs index 7c2b5d7ffcd40..7c4a99133bbdb 100644 --- a/src/libcore/iter-trait.rs +++ b/src/libcore/iter-trait.rs @@ -42,7 +42,7 @@ impl iter::ExtendedIter for IMPL_T { } #[inline(always)] pure fn foldl(&self, b0: B, blk: fn(&B, &A) -> B) -> B { - iter::foldl(self, move b0, blk) + iter::foldl(self, b0, blk) } #[inline(always)] pure fn position(&self, f: fn(&A) -> bool) -> Option { @@ -60,14 +60,14 @@ impl iter::ExtendedIter for IMPL_T { } -impl iter::EqIter for IMPL_T { +impl iter::EqIter for IMPL_T { #[inline(always)] pure fn contains(&self, x: &A) -> bool { iter::contains(self, x) } #[inline(always)] pure fn count(&self, x: &A) -> uint { iter::count(self, x) } } -impl iter::CopyableIter for IMPL_T { +impl iter::CopyableIter for IMPL_T { #[inline(always)] pure fn filter_to_vec(&self, pred: fn(&A) -> bool) -> ~[A] { iter::filter_to_vec(self, pred) @@ -80,7 +80,7 @@ impl iter::CopyableIter for IMPL_T { } } -impl iter::CopyableOrderedIter for IMPL_T { +impl iter::CopyableOrderedIter for IMPL_T { #[inline(always)] pure fn min(&self) -> A { iter::min(self) } #[inline(always)] diff --git a/src/libcore/iter-trait/dvec.rs b/src/libcore/iter-trait/dvec.rs index af788989e9c0f..986aa18ad4ab1 100644 --- a/src/libcore/iter-trait/dvec.rs +++ b/src/libcore/iter-trait/dvec.rs @@ -25,7 +25,7 @@ mod inst { unsafe { do self.swap |v| { v.each(f); - move v + v } } } diff --git a/src/libcore/iter.rs b/src/libcore/iter.rs index a36fa56fc79ba..e48edc9c1735b 100644 --- a/src/libcore/iter.rs +++ b/src/libcore/iter.rs @@ -57,7 +57,7 @@ pub trait CopyableIter { pure fn find(&self, p: fn(&A) -> bool) -> Option; } -pub trait CopyableOrderedIter { +pub trait CopyableOrderedIter { pure fn min(&self) -> A; pure fn max(&self) -> A; } @@ -154,11 +154,11 @@ pub pure fn flat_map_to_vec,IB:BaseIter>( pub pure fn foldl>(self: &IA, b0: B, blk: fn(&B, &A) -> B) -> B { - let mut b = move b0; + let mut b = b0; for self.each |a| { b = blk(&b, a); } - move b + b } #[inline(always)] @@ -211,37 +211,37 @@ pub pure fn repeat(times: uint, blk: fn() -> bool) { } #[inline(always)] -pub pure fn min>(self: &IA) -> A { +pub pure fn min>(self: &IA) -> A { match do foldl::,IA>(self, None) |a, b| { match a { &Some(ref a_) if *a_ < *b => { - *(move a) + *(a) } _ => Some(*b) } } { - Some(move val) => val, + Some(val) => val, None => fail!(~"min called on empty iterator") } } #[inline(always)] -pub pure fn max>(self: &IA) -> A { +pub pure fn max>(self: &IA) -> A { match do foldl::,IA>(self, None) |a, b| { match a { &Some(ref a_) if *a_ > *b => { - *(move a) + *(a) } _ => Some(*b) } } { - Some(move val) => val, + Some(val) => val, None => fail!(~"max called on empty iterator") } } #[inline(always)] -pub pure fn find>(self: &IA, +pub pure fn find>(self: &IA, f: fn(&A) -> bool) -> Option { for self.each |i| { if f(i) { return Some(*i) } @@ -323,7 +323,7 @@ pub pure fn from_fn>(n_elts: uint, * to the value `t`. */ #[inline(always)] -pub pure fn from_elem>(n_elts: uint, +pub pure fn from_elem>(n_elts: uint, t: T) -> BT { do Buildable::build_sized(n_elts) |push| { let mut i: uint = 0; @@ -333,7 +333,7 @@ pub pure fn from_elem>(n_elts: uint, /// Appending two generic sequences #[inline(always)] -pub pure fn append,BT: Buildable>( +pub pure fn append,BT:Buildable>( lhs: &IT, rhs: &IT) -> BT { let size_opt = lhs.size_hint().chain_ref( |sz1| rhs.size_hint().map(|sz2| *sz1+*sz2)); @@ -346,7 +346,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>( +pub pure fn copy_seq,BT:Buildable>( v: &IT) -> BT { do build_sized_opt(v.size_hint()) |push| { for v.each |x| { push(*x); } diff --git a/src/libcore/managed.rs b/src/libcore/managed.rs index 0f13a8485afdb..bed50cfbc256e 100644 --- a/src/libcore/managed.rs +++ b/src/libcore/managed.rs @@ -16,7 +16,13 @@ use managed::raw::BoxRepr; use prelude::*; 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; + use intrinsic::TyDesc; pub struct BoxHeaderRepr { diff --git a/src/libcore/mutable.rs b/src/libcore/mutable.rs index 49e0d0bdd8a65..1fb855520ba49 100644 --- a/src/libcore/mutable.rs +++ b/src/libcore/mutable.rs @@ -32,15 +32,15 @@ struct Data { pub type Mut = Data; pub fn Mut(t: T) -> Mut { - Data {value: move t, mode: ReadOnly} + Data {value: t, mode: ReadOnly} } pub fn unwrap(m: Mut) -> T { // Borrowck should prevent us from calling unwrap while the value // is in use, as that would be a move from a borrowed value. assert (m.mode as uint) == (ReadOnly as uint); - let Data {value: move value, mode: _} = move m; - move value + let Data {value: value, mode: _} = m; + value } impl Data { diff --git a/src/libcore/num/f32.rs b/src/libcore/num/f32.rs index 8350ba42591d7..d5407daca80d0 100644 --- a/src/libcore/num/f32.rs +++ b/src/libcore/num/f32.rs @@ -14,9 +14,11 @@ use cmath; use cmp; use libc::{c_float, c_int}; use num::NumCast; +use num::strconv; use num; use ops; use option::Option; +use private::intrinsics::floorf32; use from_str; use to_str; @@ -282,7 +284,7 @@ impl num::One for f32 { static pure fn one() -> f32 { 1.0 } } -pub impl f32: NumCast { +pub impl NumCast for f32 { /** * Cast `n` to an `f32` */ @@ -331,11 +333,6 @@ impl ops::Neg for f32 { pure fn neg(&self) -> f32 { -*self } } -#[abi="rust-intrinsic"] -pub extern { - fn floorf32(val: f32) -> f32; -} - impl num::Round for f32 { #[inline(always)] pure fn round(&self, mode: num::RoundMode) -> f32 { @@ -376,8 +373,8 @@ impl num::Round for f32 { */ #[inline(always)] pub pure fn to_str(num: f32) -> ~str { - let (r, _) = num::to_str_common( - &num, 10u, true, true, num::SignNeg, num::DigAll); + let (r, _) = strconv::to_str_common( + &num, 10u, true, strconv::SignNeg, strconv::DigAll); r } @@ -390,8 +387,8 @@ pub pure fn to_str(num: f32) -> ~str { */ #[inline(always)] pub pure fn to_str_hex(num: f32) -> ~str { - let (r, _) = num::to_str_common( - &num, 16u, true, true, num::SignNeg, num::DigAll); + let (r, _) = strconv::to_str_common( + &num, 16u, true, strconv::SignNeg, strconv::DigAll); r } @@ -411,8 +408,8 @@ pub pure fn to_str_hex(num: f32) -> ~str { */ #[inline(always)] pub pure fn to_str_radix(num: f32, rdx: uint) -> ~str { - let (r, special) = num::to_str_common( - &num, rdx, true, true, num::SignNeg, num::DigAll); + let (r, special) = strconv::to_str_common( + &num, rdx, true, strconv::SignNeg, strconv::DigAll); if special { fail!(~"number has a special value, \ try to_str_radix_special() if those are expected") } r @@ -429,7 +426,8 @@ pub pure fn to_str_radix(num: f32, rdx: uint) -> ~str { */ #[inline(always)] pub pure fn to_str_radix_special(num: f32, rdx: uint) -> (~str, bool) { - num::to_str_common(&num, rdx, true, true, num::SignNeg, num::DigAll) + strconv::to_str_common(&num, rdx, true, + strconv::SignNeg, strconv::DigAll) } /** @@ -443,8 +441,8 @@ pub pure fn to_str_radix_special(num: f32, rdx: uint) -> (~str, bool) { */ #[inline(always)] pub pure fn to_str_exact(num: f32, dig: uint) -> ~str { - let (r, _) = num::to_str_common( - &num, 10u, true, true, num::SignNeg, num::DigExact(dig)); + let (r, _) = strconv::to_str_common( + &num, 10u, true, strconv::SignNeg, strconv::DigExact(dig)); r } @@ -459,8 +457,8 @@ pub pure fn to_str_exact(num: f32, dig: uint) -> ~str { */ #[inline(always)] pub pure fn to_str_digits(num: f32, dig: uint) -> ~str { - let (r, _) = num::to_str_common( - &num, 10u, true, true, num::SignNeg, num::DigMax(dig)); + let (r, _) = strconv::to_str_common( + &num, 10u, true, strconv::SignNeg, strconv::DigMax(dig)); r } @@ -505,7 +503,8 @@ impl num::ToStrRadix for f32 { */ #[inline(always)] pub pure fn from_str(num: &str) -> Option { - num::from_str_common(num, 10u, true, true, true, num::ExpDec, false) + strconv::from_str_common(num, 10u, true, true, true, + strconv::ExpDec, false) } /** @@ -537,7 +536,8 @@ pub pure fn from_str(num: &str) -> Option { */ #[inline(always)] pub pure fn from_str_hex(num: &str) -> Option { - num::from_str_common(num, 16u, true, true, true, num::ExpBin, false) + strconv::from_str_common(num, 16u, true, true, true, + strconv::ExpBin, false) } /** @@ -561,7 +561,8 @@ pub pure fn from_str_hex(num: &str) -> Option { */ #[inline(always)] pub pure fn from_str_radix(num: &str, rdx: uint) -> Option { - num::from_str_common(num, rdx, true, true, false, num::ExpNone, false) + strconv::from_str_common(num, rdx, true, true, false, + strconv::ExpNone, false) } impl from_str::FromStr for f32 { diff --git a/src/libcore/num/f64.rs b/src/libcore/num/f64.rs index 474067a1860c8..4e4e7c68646f2 100644 --- a/src/libcore/num/f64.rs +++ b/src/libcore/num/f64.rs @@ -15,9 +15,11 @@ use cmp; use libc::{c_double, c_int}; use libc; use num::NumCast; +use num::strconv; use num; use ops; use option::Option; +use private::intrinsics::floorf64; use to_str; use from_str; @@ -297,7 +299,7 @@ impl cmp::Ord for f64 { pure fn gt(&self, other: &f64) -> bool { (*self) > (*other) } } -pub impl f64: NumCast { +pub impl NumCast for f64 { /** * Cast `n` to an `f64` */ @@ -356,11 +358,6 @@ impl ops::Neg for f64 { pure fn neg(&self) -> f64 { -*self } } -#[abi="rust-intrinsic"] -pub extern { - fn floorf64(val: f64) -> f64; -} - impl num::Round for f64 { #[inline(always)] pure fn round(&self, mode: num::RoundMode) -> f64 { @@ -401,8 +398,8 @@ impl num::Round for f64 { */ #[inline(always)] pub pure fn to_str(num: f64) -> ~str { - let (r, _) = num::to_str_common( - &num, 10u, true, true, num::SignNeg, num::DigAll); + let (r, _) = strconv::to_str_common( + &num, 10u, true, strconv::SignNeg, strconv::DigAll); r } @@ -415,8 +412,8 @@ pub pure fn to_str(num: f64) -> ~str { */ #[inline(always)] pub pure fn to_str_hex(num: f64) -> ~str { - let (r, _) = num::to_str_common( - &num, 16u, true, true, num::SignNeg, num::DigAll); + let (r, _) = strconv::to_str_common( + &num, 16u, true, strconv::SignNeg, strconv::DigAll); r } @@ -436,8 +433,8 @@ pub pure fn to_str_hex(num: f64) -> ~str { */ #[inline(always)] pub pure fn to_str_radix(num: f64, rdx: uint) -> ~str { - let (r, special) = num::to_str_common( - &num, rdx, true, true, num::SignNeg, num::DigAll); + let (r, special) = strconv::to_str_common( + &num, rdx, true, strconv::SignNeg, strconv::DigAll); if special { fail!(~"number has a special value, \ try to_str_radix_special() if those are expected") } r @@ -454,7 +451,8 @@ pub pure fn to_str_radix(num: f64, rdx: uint) -> ~str { */ #[inline(always)] pub pure fn to_str_radix_special(num: f64, rdx: uint) -> (~str, bool) { - num::to_str_common(&num, rdx, true, true, num::SignNeg, num::DigAll) + strconv::to_str_common(&num, rdx, true, + strconv::SignNeg, strconv::DigAll) } /** @@ -468,8 +466,8 @@ pub pure fn to_str_radix_special(num: f64, rdx: uint) -> (~str, bool) { */ #[inline(always)] pub pure fn to_str_exact(num: f64, dig: uint) -> ~str { - let (r, _) = num::to_str_common( - &num, 10u, true, true, num::SignNeg, num::DigExact(dig)); + let (r, _) = strconv::to_str_common( + &num, 10u, true, strconv::SignNeg, strconv::DigExact(dig)); r } @@ -484,8 +482,8 @@ pub pure fn to_str_exact(num: f64, dig: uint) -> ~str { */ #[inline(always)] pub pure fn to_str_digits(num: f64, dig: uint) -> ~str { - let (r, _) = num::to_str_common( - &num, 10u, true, true, num::SignNeg, num::DigMax(dig)); + let (r, _) = strconv::to_str_common( + &num, 10u, true, strconv::SignNeg, strconv::DigMax(dig)); r } @@ -530,7 +528,8 @@ impl num::ToStrRadix for f64 { */ #[inline(always)] pub pure fn from_str(num: &str) -> Option { - num::from_str_common(num, 10u, true, true, true, num::ExpDec, false) + strconv::from_str_common(num, 10u, true, true, true, + strconv::ExpDec, false) } /** @@ -562,7 +561,8 @@ pub pure fn from_str(num: &str) -> Option { */ #[inline(always)] pub pure fn from_str_hex(num: &str) -> Option { - num::from_str_common(num, 16u, true, true, true, num::ExpBin, false) + strconv::from_str_common(num, 16u, true, true, true, + strconv::ExpBin, false) } /** @@ -586,7 +586,8 @@ pub pure fn from_str_hex(num: &str) -> Option { */ #[inline(always)] pub pure fn from_str_radix(num: &str, rdx: uint) -> Option { - num::from_str_common(num, rdx, true, true, false, num::ExpNone, false) + strconv::from_str_common(num, rdx, true, true, false, + strconv::ExpNone, false) } impl from_str::FromStr for f64 { diff --git a/src/libcore/num/float.rs b/src/libcore/num/float.rs index 0f0b721e4626a..b857f76570ff5 100644 --- a/src/libcore/num/float.rs +++ b/src/libcore/num/float.rs @@ -26,6 +26,7 @@ use cmp::{Eq, Ord}; use cmp; use f64; use num::NumCast; +use num::strconv; use num; use ops; use option::{None, Option, Some}; @@ -107,8 +108,8 @@ pub mod consts { */ #[inline(always)] pub pure fn to_str(num: float) -> ~str { - let (r, _) = num::to_str_common( - &num, 10u, true, true, num::SignNeg, num::DigAll); + let (r, _) = strconv::to_str_common( + &num, 10u, true, strconv::SignNeg, strconv::DigAll); r } @@ -121,8 +122,8 @@ pub pure fn to_str(num: float) -> ~str { */ #[inline(always)] pub pure fn to_str_hex(num: float) -> ~str { - let (r, _) = num::to_str_common( - &num, 16u, true, true, num::SignNeg, num::DigAll); + let (r, _) = strconv::to_str_common( + &num, 16u, true, strconv::SignNeg, strconv::DigAll); r } @@ -142,8 +143,8 @@ pub pure fn to_str_hex(num: float) -> ~str { */ #[inline(always)] pub pure fn to_str_radix(num: float, radix: uint) -> ~str { - let (r, special) = num::to_str_common( - &num, radix, true, true, num::SignNeg, num::DigAll); + let (r, special) = strconv::to_str_common( + &num, radix, true, strconv::SignNeg, strconv::DigAll); if special { fail!(~"number has a special value, \ try to_str_radix_special() if those are expected") } r @@ -160,7 +161,8 @@ pub pure fn to_str_radix(num: float, radix: uint) -> ~str { */ #[inline(always)] pub pure fn to_str_radix_special(num: float, radix: uint) -> (~str, bool) { - num::to_str_common(&num, radix, true, true, num::SignNeg, num::DigAll) + strconv::to_str_common(&num, radix, true, + strconv::SignNeg, strconv::DigAll) } /** @@ -174,8 +176,8 @@ pub pure fn to_str_radix_special(num: float, radix: uint) -> (~str, bool) { */ #[inline(always)] pub pure fn to_str_exact(num: float, digits: uint) -> ~str { - let (r, _) = num::to_str_common( - &num, 10u, true, true, num::SignNeg, num::DigExact(digits)); + let (r, _) = strconv::to_str_common( + &num, 10u, true, strconv::SignNeg, strconv::DigExact(digits)); r } @@ -196,8 +198,8 @@ pub fn test_to_str_exact_do_decimal() { */ #[inline(always)] pub pure fn to_str_digits(num: float, digits: uint) -> ~str { - let (r, _) = num::to_str_common( - &num, 10u, true, true, num::SignNeg, num::DigMax(digits)); + let (r, _) = strconv::to_str_common( + &num, 10u, true, strconv::SignNeg, strconv::DigMax(digits)); r } @@ -242,7 +244,8 @@ impl num::ToStrRadix for float { */ #[inline(always)] pub pure fn from_str(num: &str) -> Option { - num::from_str_common(num, 10u, true, true, true, num::ExpDec, false) + strconv::from_str_common(num, 10u, true, true, true, + strconv::ExpDec, false) } /** @@ -274,7 +277,8 @@ pub pure fn from_str(num: &str) -> Option { */ #[inline(always)] pub pure fn from_str_hex(num: &str) -> Option { - num::from_str_common(num, 16u, true, true, true, num::ExpBin, false) + strconv::from_str_common(num, 16u, true, true, true, + strconv::ExpBin, false) } /** @@ -298,7 +302,8 @@ pub pure fn from_str_hex(num: &str) -> Option { */ #[inline(always)] pub pure fn from_str_radix(num: &str, radix: uint) -> Option { - num::from_str_common(num, radix, true, true, false, num::ExpNone, false) + strconv::from_str_common(num, radix, true, true, false, + strconv::ExpNone, false) } impl from_str::FromStr for float { @@ -415,7 +420,7 @@ impl num::One for float { static pure fn one() -> float { 1.0 } } -pub impl float: NumCast { +pub impl NumCast for float { /** * Cast `n` to a `float` */ diff --git a/src/libcore/num/int-template.rs b/src/libcore/num/int-template.rs index eaaa78b84f837..8d72878ef6acb 100644 --- a/src/libcore/num/int-template.rs +++ b/src/libcore/num/int-template.rs @@ -16,6 +16,7 @@ use cmp; use to_str::ToStr; use from_str::FromStr; use num::{ToStrRadix, FromStrRadix}; +use num::strconv; use num; use prelude::*; use str; @@ -176,18 +177,6 @@ impl num::One for T { static pure fn one() -> T { 1 } } -impl num::Round for T { - #[inline(always)] - pure fn round(&self, _: num::RoundMode) -> T { *self } - - #[inline(always)] - pure fn floor(&self) -> T { *self } - #[inline(always)] - pure fn ceil(&self) -> T { *self } - #[inline(always)] - pure fn fract(&self) -> T { 0 } -} - #[cfg(notest)] impl ops::Add for T { pure fn add(&self, other: &T) -> T { *self + *other } @@ -218,22 +207,22 @@ impl ops::Neg for T { /// Parse a string as a number in base 10. #[inline(always)] pub pure fn from_str(s: &str) -> Option { - num::from_str_common(s, 10u, true, false, false, - num::ExpNone, false) + 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 { - num::from_str_common(s, radix, true, false, false, - num::ExpNone, false) + 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 { - num::from_str_bytes_common(buf, radix, true, false, false, - num::ExpNone, false) + strconv::from_str_bytes_common(buf, radix, true, false, false, + strconv::ExpNone, false) } impl FromStr for T { @@ -255,24 +244,24 @@ 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 { - let (buf, _) = num::to_str_bytes_common(&n, radix, false, false, - num::SignNeg, num::DigAll); + let (buf, _) = strconv::to_str_bytes_common(&n, radix, false, + strconv::SignNeg, strconv::DigAll); f(buf) } /// Convert to a string in base 10. #[inline(always)] pub pure fn to_str(num: T) -> ~str { - let (buf, _) = num::to_str_common(&num, 10u, false, false, - num::SignNeg, num::DigAll); + let (buf, _) = strconv::to_str_common(&num, 10u, false, + strconv::SignNeg, strconv::DigAll); buf } /// Convert to a string in a given base. #[inline(always)] pub pure fn to_str_radix(num: T, radix: uint) -> ~str { - let (buf, _) = num::to_str_common(&num, radix, false, false, - num::SignNeg, num::DigAll); + let (buf, _) = strconv::to_str_common(&num, radix, false, + strconv::SignNeg, strconv::DigAll); buf } diff --git a/src/libcore/num/int-template/i16.rs b/src/libcore/num/int-template/i16.rs index 76725e3895b55..1352959306a03 100644 --- a/src/libcore/num/int-template/i16.rs +++ b/src/libcore/num/int-template/i16.rs @@ -17,7 +17,7 @@ mod inst { pub const bits: uint = ::u16::bits; } -pub impl i16: NumCast { +pub impl NumCast for i16 { /** * Cast `n` to a `i16` */ diff --git a/src/libcore/num/int-template/i32.rs b/src/libcore/num/int-template/i32.rs index 1c2d60a80ee2b..e8dd603d50753 100644 --- a/src/libcore/num/int-template/i32.rs +++ b/src/libcore/num/int-template/i32.rs @@ -17,7 +17,7 @@ mod inst { pub const bits: uint = ::u32::bits; } -pub impl i32: NumCast { +pub impl NumCast for i32 { /** * Cast `n` to a `i32` */ diff --git a/src/libcore/num/int-template/i64.rs b/src/libcore/num/int-template/i64.rs index d7413920a64f1..6f1371f8ee221 100644 --- a/src/libcore/num/int-template/i64.rs +++ b/src/libcore/num/int-template/i64.rs @@ -17,7 +17,7 @@ mod inst { pub const bits: uint = ::u64::bits; } -pub impl i64: NumCast { +pub impl NumCast for i64 { /** * Cast `n` to a `i64` */ diff --git a/src/libcore/num/int-template/i8.rs b/src/libcore/num/int-template/i8.rs index f2577020128bd..46c734b95483e 100644 --- a/src/libcore/num/int-template/i8.rs +++ b/src/libcore/num/int-template/i8.rs @@ -17,7 +17,7 @@ mod inst { pub const bits: uint = ::u8::bits; } -pub impl i8: NumCast { +pub impl NumCast for i8 { /** * Cast `n` to a `i8` */ diff --git a/src/libcore/num/int-template/int.rs b/src/libcore/num/int-template/int.rs index 4ba1570e1359a..83ef421b70578 100644 --- a/src/libcore/num/int-template/int.rs +++ b/src/libcore/num/int-template/int.rs @@ -58,7 +58,7 @@ mod inst { } } -pub impl int: NumCast { +pub impl NumCast for int { /** * Cast `n` to a `int` */ diff --git a/src/libcore/num/num.rs b/src/libcore/num/num.rs index 44cd66363fb28..7038ba07c0dea 100644 --- a/src/libcore/num/num.rs +++ b/src/libcore/num/num.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. // @@ -17,6 +17,8 @@ use str; use kinds::Copy; use vec; +pub mod strconv; + pub trait IntConvertible { pure fn to_int(&self) -> int; static pure fn from_int(n: int) -> Self; @@ -42,6 +44,13 @@ pub trait Round { pure fn fract(&self) -> Self; } +pub enum RoundMode { + RoundDown, + RoundUp, + RoundToZero, + RoundFromZero +} + /** * Cast a number the the enclosing type * @@ -53,7 +62,7 @@ pub trait Round { * ~~~ */ #[inline(always)] -pub pure fn cast(n: T) -> U { +pub pure fn cast(n: T) -> U { NumCast::from(n) } @@ -80,13 +89,6 @@ pub trait NumCast { pure fn to_float(&self) -> float; } -pub enum RoundMode { - RoundDown, - RoundUp, - RoundToZero, - RoundFromZero -} - pub trait ToStrRadix { pub pure fn to_str_radix(&self, radix: uint) -> ~str; } @@ -97,62 +99,6 @@ pub trait FromStrRadix { // Generic math functions: -/// Dynamically calculates the value `inf` (`1/0`). -/// Can fail on integer types. -#[inline(always)] -pub pure fn infinity>() -> T { - let _0: T = Zero::zero(); - let _1: T = One::one(); - _1 / _0 -} - -/// Dynamically calculates the value `-inf` (`-1/0`). -/// Can fail on integer types. -#[inline(always)] -pub pure fn neg_infinity+Neg>() -> T { - let _0: T = Zero::zero(); - let _1: T = One::one(); - - _1 / _0 -} - -/// Dynamically calculates the value `NaN` (`0/0`). -/// Can fail on integer types. -#[inline(always)] -pub pure fn NaN>() -> T { - let _0: T = Zero::zero(); - _0 / _0 -} - -/// Returns `true` if `num` has the value `inf` (`1/0`). -/// Can fail on integer types. -#[inline(always)] -pub pure fn is_infinity>(num: &T) -> bool { - (*num) == (infinity::()) -} - -/// Returns `true` if `num` has the value `-inf` (`-1/0`). -/// Can fail on integer types. -#[inline(always)] -pub pure fn is_neg_infinity+Neg>(num: &T) - -> bool { - (*num) == (neg_infinity::()) -} - -/// Returns `true` if `num` has the value `NaN` (is not equal to itself). -#[inline(always)] -pub pure fn is_NaN(num: &T) -> bool { - (*num) != (*num) -} - -/// Returns `true` if `num` has the value `-0` (`1/num == -1/0`). -/// Can fail on integer types. -#[inline(always)] -pub pure fn is_neg_zero+Neg>(num: &T) -> bool { - let _1: T = One::one(); - let _0: T = Zero::zero(); - *num == _0 && is_neg_infinity(&(_1 / *num)) -} - /** * Calculates a power to a given radix, optimized for uint `pow` and `radix`. * @@ -186,540 +132,3 @@ pub pure fn pow_with_uint+Mul>( total } -pub enum ExponentFormat { - ExpNone, - ExpDec, - ExpBin -} - -pub enum SignificantDigits { - DigAll, - DigMax(uint), - DigExact(uint) -} - -pub enum SignFormat { - SignNone, - SignNeg, - SignAll -} - -/** - * Converts a number to its string representation as a byte vector. - * This is meant to be a common base implementation for all numeric string - * conversion functions like `to_str()` or `to_str_radix()`. - * - * # Arguments - * - `num` - The number to convert. Accepts any number that - * implements the numeric traits. - * - `radix` - Base to use. Accepts only the values 2-36. - * - `special` - Whether to attempt to compare to special values like - * `inf` or `NaN`. Also needed to detect negative 0. - * Can fail if it doesn't match `num`s type - * (see safety note). - * - `negative_zero` - Whether to treat the special value `-0` as - * `-0` or as `+0`. - * - `sign` - How to emit the sign. Options are: - * - `SignNone`: No sign at all. Basically emits `abs(num)`. - * - `SignNeg`: Only `-` on negative values. - * - `SignAll`: Both `+` on positive, and `-` on negative numbers. - * - `digits` - The amount of digits to use for emitting the - * fractional part, if any. Options are: - * - `DigAll`: All calculatable digits. Beware of bignums or - * fractions! - * - `DigMax(uint)`: Maximum N digits, truncating any trailing zeros. - * - `DigExact(uint)`: Exactly N digits. - * - * # Return value - * A tuple containing the byte vector, and a boolean flag indicating - * whether it represents a special value like `inf`, `-inf`, `NaN` or not. - * It returns a tuple because there can be ambiguity between a special value - * and a number representation at higher bases. - * - * # Failure - * - Fails if `radix` < 2 or `radix` > 36. - * - Fails on wrong value for `special` (see safety note). - * - * # Safety note - * The function detects the special values `inf`, `-inf` and `NaN` by - * dynamically comparing `num` to `1 / 0`, `-1 / 0` and `0 / 0` - * (each of type T) if `special` is `true`. This will fail on integer types - * with a 'divide by zero'. Likewise, it will fail if `num` **is** one of - * those special values, and `special` is `false`, because then the - * algorithm just does normal calculations on them. - */ -pub pure fn to_str_bytes_common+ - Neg+Modulo+Mul>( - num: &T, radix: uint, special: bool, negative_zero: bool, - sign: SignFormat, digits: SignificantDigits) -> (~[u8], bool) { - 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 { - fail!(fmt!("to_str_bytes_common: radix %? to high, \ - must lie in the range [2, 36]", radix)); - } - - let _0: T = Zero::zero(); - let _1: T = One::one(); - - if special { - if is_NaN(num) { - return (str::to_bytes("NaN"), true); - } else if is_infinity(num){ - return match sign { - SignAll => (str::to_bytes("+inf"), true), - _ => (str::to_bytes("inf"), true) - } - } else if is_neg_infinity(num) { - return match sign { - SignNone => (str::to_bytes("inf"), true), - _ => (str::to_bytes("-inf"), true), - } - } - } - - let neg = *num < _0 || (negative_zero && *num == _0 - && special && is_neg_zero(num)); - let mut buf: ~[u8] = ~[]; - let radix_gen: T = cast(radix as int); - - let mut deccum; - - // First emit the non-fractional part, looping at least once to make - // sure at least a `0` gets emitted. - deccum = num.round(RoundToZero); - loop { - // Calculate the absolute value of each digit instead of only - // doing it once for the whole number because a - // representable negative number doesn't necessary have an - // representable additive inverse of the same type - // (See twos complement). But we assume that for the - // numbers [-35 .. 0] we always have [0 .. 35]. - let current_digit_signed = deccum % radix_gen; - let current_digit = if current_digit_signed < _0 { - -current_digit_signed - } else { - current_digit_signed - }; - - // Decrease the deccumulator one digit at a time - deccum /= radix_gen; - deccum = deccum.round(RoundToZero); - - unsafe { // FIXME: Pureness workaround (#4568) - buf.push(char::from_digit(current_digit.to_int() as uint, radix) - .unwrap() as u8); - } - - // No more digits to calculate for the non-fractional part -> break - if deccum == _0 { break; } - } - - // If limited digits, calculate one digit more for rounding. - let (limit_digits, digit_count, exact) = match digits { - DigAll => (false, 0u, false), - DigMax(count) => (true, count+1, false), - DigExact(count) => (true, count+1, true) - }; - - // Decide what sign to put in front - match sign { - SignNeg | SignAll if neg => { - unsafe { // FIXME: Pureness workaround (#4568) - buf.push('-' as u8); - } - } - SignAll => { - unsafe { // FIXME: Pureness workaround (#4568) - buf.push('+' as u8); - } - } - _ => () - } - - unsafe { // FIXME: Pureness workaround (#4568) - vec::reverse(buf); - } - - // Remember start of the fractional digits. - // Points one beyond end of buf if none get generated, - // or at the '.' otherwise. - let start_fractional_digits = buf.len(); - - // Now emit the fractional part, if any - deccum = num.fract(); - if deccum != _0 || (limit_digits && exact && digit_count > 0) { - unsafe { // FIXME: Pureness workaround (#4568) - buf.push('.' as u8); - } - let mut dig = 0u; - - // calculate new digits while - // - there is no limit and there are digits left - // - or there is a limit, it's not reached yet and - // - it's exact - // - or it's a maximum, and there are still digits left - while (!limit_digits && deccum != _0) - || (limit_digits && dig < digit_count && ( - exact - || (!exact && deccum != _0) - ) - ) { - // Shift first fractional digit into the integer part - deccum *= radix_gen; - - // Calculate the absolute value of each digit. - // See note in first loop. - let current_digit_signed = deccum.round(RoundToZero); - let current_digit = if current_digit_signed < _0 { - -current_digit_signed - } else { - current_digit_signed - }; - - unsafe { // FIXME: Pureness workaround (#4568) - buf.push(char::from_digit( - current_digit.to_int() as uint, radix).unwrap() as u8); - } - - // Decrease the deccumulator one fractional digit at a time - deccum = deccum.fract(); - dig += 1u; - } - - // If digits are limited, and that limit has been reached, - // cut off the one extra digit, and depending on its value - // round the remaining ones. - if limit_digits && dig == digit_count { - let ascii2value = |chr: u8| { - char::to_digit(chr as char, radix).unwrap() as uint - }; - let value2ascii = |val: uint| { - char::from_digit(val, radix).unwrap() as u8 - }; - - unsafe { // FIXME: Pureness workaround (#4568) - let extra_digit = ascii2value(buf.pop()); - if extra_digit >= radix / 2 { // -> need to round - let mut i: int = buf.len() as int - 1; - loop { - // If reached left end of number, have to - // insert additional digit: - if i < 0 - || buf[i] == '-' as u8 - || buf[i] == '+' as u8 { - buf.insert((i + 1) as uint, value2ascii(1)); - break; - } - - // Skip the '.' - if buf[i] == '.' as u8 { i -= 1; loop; } - - // Either increment the digit, - // or set to 0 if max and carry the 1. - let current_digit = ascii2value(buf[i]); - if current_digit < (radix - 1) { - buf[i] = value2ascii(current_digit+1); - break; - } else { - buf[i] = value2ascii(0); - i -= 1; - } - } - } - } - } - } - - // if number of digits is not exact, remove all trailing '0's up to - // and including the '.' - if !exact { - let buf_max_i = buf.len() - 1; - - // index to truncate from - let mut i = buf_max_i; - - // discover trailing zeros of fractional part - while i > start_fractional_digits && buf[i] == '0' as u8 { - i -= 1; - } - - // Only attempt to truncate digits if buf has fractional digits - if i >= start_fractional_digits { - // If buf ends with '.', cut that too. - if buf[i] == '.' as u8 { i -= 1 } - - // only resize buf if we actually remove digits - if i < buf_max_i { - buf = buf.slice(0, i + 1); - } - } - } // If exact and trailing '.', just cut that - else { - let max_i = buf.len() - 1; - if buf[max_i] == '.' as u8 { - buf = buf.slice(0, max_i); - } - } - - (buf, false) -} - -/** - * Converts a number to its string representation. This is a wrapper for - * `to_str_bytes_common()`, for details see there. - */ -#[inline(always)] -pub pure fn to_str_common+Neg - +Modulo+Mul>( - num: &T, radix: uint, special: bool, negative_zero: bool, - sign: SignFormat, digits: SignificantDigits) -> (~str, bool) { - let (bytes, special) = to_str_bytes_common(num, radix, special, - negative_zero, sign, digits); - (str::from_bytes(bytes), special) -} - -// Some constants for from_str_bytes_common's input validation, -// they define minimum radix values for which the character is a valid digit. -priv const DIGIT_P_RADIX: uint = ('p' as uint) - ('a' as uint) + 11u; -priv const DIGIT_I_RADIX: uint = ('i' as uint) - ('a' as uint) + 11u; -priv const DIGIT_E_RADIX: uint = ('e' as uint) - ('a' as uint) + 11u; - -/** - * Parses a byte slice as a number. This is meant to - * be a common base implementation for all numeric string conversion - * functions like `from_str()` or `from_str_radix()`. - * - * # Arguments - * - `buf` - The byte slice to parse. - * - `radix` - Which base to parse the number as. Accepts 2-36. - * - `negative` - Whether to accept negative numbers. - * - `fractional` - Whether to accept numbers with fractional parts. - * - `special` - Whether to accept special values like `inf` - * and `NaN`. Can conflict with `radix`, see Failure. - * - `exponent` - Which exponent format to accept. Options are: - * - `ExpNone`: No Exponent, accepts just plain numbers like `42` or - * `-8.2`. - * - `ExpDec`: Accepts numbers with a decimal exponent like `42e5` or - * `8.2E-2`. The exponent string itself is always base 10. - * Can conflict with `radix`, see Failure. - * - `ExpBin`: Accepts numbers with a binary exponent like `42P-8` or - * `FFp128`. The exponent string itself is always base 10. - * Can conflict with `radix`, see Failure. - * - `empty_zero` - Whether to accept a empty `buf` as a 0 or not. - * - * # Return value - * Returns `Some(n)` if `buf` parses to a number n without overflowing, and - * `None` otherwise, depending on the constraints set by the remaining - * arguments. - * - * # Failure - * - Fails if `radix` < 2 or `radix` > 36. - * - Fails if `radix` > 14 and `exponent` is `ExpDec` due to conflict - * between digit and exponent sign `'e'`. - * - Fails if `radix` > 25 and `exponent` is `ExpBin` due to conflict - * between digit and exponent sign `'p'`. - * - Fails if `radix` > 18 and `special == true` due to conflict - * between digit and lowest first character in `inf` and `NaN`, the `'i'`. - * - * # Possible improvements - * - Could accept option to allow ignoring underscores, allowing for numbers - * formated like `FF_AE_FF_FF`. - */ -pub pure fn from_str_bytes_common+ - Mul+Sub+Neg+Add>( - buf: &[u8], radix: uint, negative: bool, fractional: bool, - special: bool, exponent: ExponentFormat, empty_zero: bool - ) -> Option { - match exponent { - ExpDec if radix >= DIGIT_E_RADIX // decimal exponent 'e' - => fail!(fmt!("from_str_bytes_common: radix %? incompatible with \ - use of 'e' as decimal exponent", radix)), - ExpBin if radix >= DIGIT_P_RADIX // binary exponent 'p' - => fail!(fmt!("from_str_bytes_common: radix %? incompatible with \ - use of 'p' as binary exponent", radix)), - _ 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 - => fail!(fmt!("from_str_bytes_common: radix %? to low, \ - must lie in the range [2, 36]", radix)), - _ if radix as int > 36 - => fail!(fmt!("from_str_bytes_common: radix %? to high, \ - must lie in the range [2, 36]", radix)), - _ => () - } - - let _0: T = Zero::zero(); - let _1: T = One::one(); - let radix_gen: T = cast(radix as int); - - let len = buf.len(); - - if len == 0 { - if empty_zero { - return Some(_0); - } else { - return None; - } - } - - if special { - if buf == str::to_bytes("inf") || buf == str::to_bytes("+inf") { - return Some(infinity()); - } else if buf == str::to_bytes("-inf") { - if negative { - return Some(neg_infinity()); - } else { - return None; - } - } else if buf == str::to_bytes("NaN") { - return Some(NaN()); - } - } - - let (start, accum_positive) = match buf[0] { - '-' as u8 if !negative => return None, - '-' as u8 => (1u, false), - '+' as u8 => (1u, true), - _ => (0u, true) - }; - - // Initialize accumulator with signed zero for floating point parsing to - // work - let mut accum = if accum_positive { _0 } else { -_1 * _0}; - let mut last_accum = accum; // Necessary to detect overflow - let mut i = start; - let mut exp_found = false; - - // Parse integer part of number - while i < len { - let c = buf[i] as char; - - match char::to_digit(c, radix) { - Some(digit) => { - // shift accum one digit left - accum *= radix_gen; - - // add/subtract current digit depending on sign - if accum_positive { - accum += cast(digit as int); - } else { - accum -= cast(digit as int); - } - - // Detect overflow by comparing to last value - if accum_positive && accum < last_accum { return None; } - if !accum_positive && accum > last_accum { return None; } - last_accum = accum; - } - None => match c { - 'e' | 'E' | 'p' | 'P' => { - exp_found = true; - break; // start of exponent - } - '.' if fractional => { - i += 1u; // skip the '.' - break; // start of fractional part - } - _ => return None // invalid number - } - } - - i += 1u; - } - - // Parse fractional part of number - // Skip if already reached start of exponent - if !exp_found { - let mut power = _1; - - while i < len { - let c = buf[i] as char; - - match char::to_digit(c, radix) { - Some(digit) => { - // Decrease power one order of magnitude - power /= radix_gen; - - let digit_t: T = cast(digit); - - // add/subtract current digit depending on sign - if accum_positive { - accum += digit_t * power; - } else { - accum -= digit_t * power; - } - - // Detect overflow by comparing to last value - if accum_positive && accum < last_accum { return None; } - if !accum_positive && accum > last_accum { return None; } - last_accum = accum; - } - None => match c { - 'e' | 'E' | 'p' | 'P' => { - exp_found = true; - break; // start of exponent - } - _ => return None // invalid number - } - } - - i += 1u; - } - } - - // Special case: buf not empty, but does not contain any digit in front - // of the exponent sign -> number is empty string - if i == start { - if empty_zero { - return Some(_0); - } else { - return None; - } - } - - let mut multiplier = _1; - - if exp_found { - let c = buf[i] as char; - let base = match (c, exponent) { - ('e', ExpDec) | ('E', ExpDec) => 10u, - ('p', ExpBin) | ('P', ExpBin) => 2u, - _ => return None // char doesn't fit given exponent format - }; - - // 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); - - match exp { - Some(exp_pow) => { - multiplier = if exp_pow < 0 { - _1 / pow_with_uint::(base, (-exp_pow.to_int()) as uint) - } else { - pow_with_uint::(base, exp_pow.to_int() as uint) - } - } - None => return None // invalid exponent -> invalid number - } - } - - Some(accum * multiplier) -} - -/** - * Parses a string as a number. This is a wrapper for - * `from_str_bytes_common()`, for details see there. - */ -#[inline(always)] -pub pure fn from_str_common+Mul+ - Sub+Neg+Add>( - buf: &str, radix: uint, negative: bool, fractional: bool, - special: bool, exponent: ExponentFormat, empty_zero: bool - ) -> Option { - from_str_bytes_common(str::to_bytes(buf), radix, negative, - fractional, special, exponent, empty_zero) -} diff --git a/src/libcore/num/strconv.rs b/src/libcore/num/strconv.rs new file mode 100644 index 0000000000000..4322ea40428fb --- /dev/null +++ b/src/libcore/num/strconv.rs @@ -0,0 +1,639 @@ +// 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 core::cmp::{Ord, Eq}; +use ops::{Add, Div, Modulo, Mul, Neg, Sub}; +use option::{None, Option, Some}; +use char; +use str; +use kinds::Copy; +use vec; +use num::{NumCast, Zero, One, cast, pow_with_uint}; +use f64; + +pub enum ExponentFormat { + ExpNone, + ExpDec, + ExpBin +} + +pub enum SignificantDigits { + DigAll, + DigMax(uint), + DigExact(uint) +} + +pub enum SignFormat { + SignNone, + SignNeg, + SignAll +} + +#[inline(always)] +pure fn is_NaN(num: &T) -> bool { + *num != *num +} + +#[inline(always)] +pure fn is_inf(num: &T) -> bool { + match NumStrConv::inf() { + None => false, + Some(n) => *num == n + } +} + +#[inline(always)] +pure fn is_neg_inf(num: &T) -> bool { + match NumStrConv::neg_inf() { + None => false, + Some(n) => *num == n + } +} + +#[inline(always)] +pure fn is_neg_zero>(num: &T) -> bool { + let _0: T = Zero::zero(); + let _1: T = One::one(); + + *num == _0 && is_neg_inf(&(_1 / *num)) +} + +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; + + pure fn round_to_zero(&self) -> Self; + pure 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) } + #[inline(always)] + static pure fn inf() -> Option<$t> { Some( 1.0 / 0.0) } + #[inline(always)] + static pure fn neg_inf() -> Option<$t> { Some(-1.0 / 0.0) } + #[inline(always)] + static pure fn neg_zero() -> Option<$t> { Some(-0.0 ) } + + #[inline(always)] + pure 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 { + *self - self.round_to_zero() + } + } +)) + +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)] pure fn round_to_zero(&self) -> $t { *self } + #[inline(always)] pure fn fractional_part(&self) -> $t { 0 } + } +)) + +// FIXME: #4955 +// Replace by two generic impls for traits 'Integral' and 'Floating' +impl_NumStrConv_Floating!(float) +impl_NumStrConv_Floating!(f32) +impl_NumStrConv_Floating!(f64) + +impl_NumStrConv_Integer!(int) +impl_NumStrConv_Integer!(i8) +impl_NumStrConv_Integer!(i16) +impl_NumStrConv_Integer!(i32) +impl_NumStrConv_Integer!(i64) + +impl_NumStrConv_Integer!(uint) +impl_NumStrConv_Integer!(u8) +impl_NumStrConv_Integer!(u16) +impl_NumStrConv_Integer!(u32) +impl_NumStrConv_Integer!(u64) + +/** + * Converts a number to its string representation as a byte vector. + * This is meant to be a common base implementation for all numeric string + * conversion functions like `to_str()` or `to_str_radix()`. + * + * # Arguments + * - `num` - The number to convert. Accepts any number that + * implements the numeric traits. + * - `radix` - Base to use. Accepts only the values 2-36. + * - `negative_zero` - Whether to treat the special value `-0` as + * `-0` or as `+0`. + * - `sign` - How to emit the sign. Options are: + * - `SignNone`: No sign at all. Basically emits `abs(num)`. + * - `SignNeg`: Only `-` on negative values. + * - `SignAll`: Both `+` on positive, and `-` on negative numbers. + * - `digits` - The amount of digits to use for emitting the + * fractional part, if any. Options are: + * - `DigAll`: All calculatable digits. Beware of bignums or + * fractions! + * - `DigMax(uint)`: Maximum N digits, truncating any trailing zeros. + * - `DigExact(uint)`: Exactly N digits. + * + * # Return value + * A tuple containing the byte vector, and a boolean flag indicating + * whether it represents a special value like `inf`, `-inf`, `NaN` or not. + * It returns a tuple because there can be ambiguity between a special value + * and a number representation at higher bases. + * + * # 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 { + fail!(fmt!("to_str_bytes_common: radix %? to low, \ + must lie in the range [2, 36]", radix)); + } else if radix as int > 36 { + fail!(fmt!("to_str_bytes_common: radix %? to high, \ + must lie in the range [2, 36]", radix)); + } + + let _0: T = Zero::zero(); + let _1: T = One::one(); + + if is_NaN(num) { + return (str::to_bytes("NaN"), true); + } + else if is_inf(num){ + return match sign { + SignAll => (str::to_bytes("+inf"), true), + _ => (str::to_bytes("inf"), true) + } + } + else if is_neg_inf(num) { + return match sign { + SignNone => (str::to_bytes("inf"), true), + _ => (str::to_bytes("-inf"), true), + } + } + + let neg = *num < _0 || (negative_zero && is_neg_zero(num)); + let mut buf: ~[u8] = ~[]; + let radix_gen: T = cast(radix as int); + + let mut deccum; + + // First emit the non-fractional part, looping at least once to make + // sure at least a `0` gets emitted. + deccum = num.round_to_zero(); + loop { + // Calculate the absolute value of each digit instead of only + // doing it once for the whole number because a + // representable negative number doesn't necessary have an + // representable additive inverse of the same type + // (See twos complement). But we assume that for the + // numbers [-35 .. 0] we always have [0 .. 35]. + let current_digit_signed = deccum % radix_gen; + let current_digit = if current_digit_signed < _0 { + -current_digit_signed + } else { + current_digit_signed + }; + + // Decrease the deccumulator one digit at a time + deccum /= radix_gen; + deccum = deccum.round_to_zero(); + + unsafe { // FIXME: Pureness workaround (#4568) + buf.push(char::from_digit(current_digit.to_int() as uint, radix) + .unwrap() as u8); + } + + // No more digits to calculate for the non-fractional part -> break + if deccum == _0 { break; } + } + + // If limited digits, calculate one digit more for rounding. + let (limit_digits, digit_count, exact) = match digits { + DigAll => (false, 0u, false), + DigMax(count) => (true, count+1, false), + DigExact(count) => (true, count+1, true) + }; + + // Decide what sign to put in front + match sign { + SignNeg | SignAll if neg => { + unsafe { // FIXME: Pureness workaround (#4568) + buf.push('-' as u8); + } + } + SignAll => { + unsafe { // FIXME: Pureness workaround (#4568) + buf.push('+' as u8); + } + } + _ => () + } + + unsafe { // FIXME: Pureness workaround (#4568) + vec::reverse(buf); + } + + // Remember start of the fractional digits. + // Points one beyond end of buf if none get generated, + // or at the '.' otherwise. + let start_fractional_digits = buf.len(); + + // Now emit the fractional part, if any + deccum = num.fractional_part(); + if deccum != _0 || (limit_digits && exact && digit_count > 0) { + unsafe { // FIXME: Pureness workaround (#4568) + buf.push('.' as u8); + } + let mut dig = 0u; + + // calculate new digits while + // - there is no limit and there are digits left + // - or there is a limit, it's not reached yet and + // - it's exact + // - or it's a maximum, and there are still digits left + while (!limit_digits && deccum != _0) + || (limit_digits && dig < digit_count && ( + exact + || (!exact && deccum != _0) + ) + ) { + // Shift first fractional digit into the integer part + deccum *= radix_gen; + + // Calculate the absolute value of each digit. + // See note in first loop. + let current_digit_signed = deccum.round_to_zero(); + let current_digit = if current_digit_signed < _0 { + -current_digit_signed + } else { + current_digit_signed + }; + + unsafe { // FIXME: Pureness workaround (#4568) + buf.push(char::from_digit( + current_digit.to_int() as uint, radix).unwrap() as u8); + } + + // Decrease the deccumulator one fractional digit at a time + deccum = deccum.fractional_part(); + dig += 1u; + } + + // If digits are limited, and that limit has been reached, + // cut off the one extra digit, and depending on its value + // round the remaining ones. + if limit_digits && dig == digit_count { + let ascii2value = |chr: u8| { + char::to_digit(chr as char, radix).unwrap() as uint + }; + let value2ascii = |val: uint| { + char::from_digit(val, radix).unwrap() as u8 + }; + + unsafe { // FIXME: Pureness workaround (#4568) + let extra_digit = ascii2value(buf.pop()); + if extra_digit >= radix / 2 { // -> need to round + let mut i: int = buf.len() as int - 1; + loop { + // If reached left end of number, have to + // insert additional digit: + if i < 0 + || buf[i] == '-' as u8 + || buf[i] == '+' as u8 { + buf.insert((i + 1) as uint, value2ascii(1)); + break; + } + + // Skip the '.' + if buf[i] == '.' as u8 { i -= 1; loop; } + + // Either increment the digit, + // or set to 0 if max and carry the 1. + let current_digit = ascii2value(buf[i]); + if current_digit < (radix - 1) { + buf[i] = value2ascii(current_digit+1); + break; + } else { + buf[i] = value2ascii(0); + i -= 1; + } + } + } + } + } + } + + // if number of digits is not exact, remove all trailing '0's up to + // and including the '.' + if !exact { + let buf_max_i = buf.len() - 1; + + // index to truncate from + let mut i = buf_max_i; + + // discover trailing zeros of fractional part + while i > start_fractional_digits && buf[i] == '0' as u8 { + i -= 1; + } + + // Only attempt to truncate digits if buf has fractional digits + if i >= start_fractional_digits { + // If buf ends with '.', cut that too. + if buf[i] == '.' as u8 { i -= 1 } + + // only resize buf if we actually remove digits + if i < buf_max_i { + buf = buf.slice(0, i + 1); + } + } + } // If exact and trailing '.', just cut that + else { + let max_i = buf.len() - 1; + if buf[max_i] == '.' as u8 { + buf = buf.slice(0, max_i); + } + } + + (buf, false) +} + +/** + * Converts a number to its string representation. This is a wrapper for + * `to_str_bytes_common()`, for details see there. + */ +#[inline(always)] +pub pure fn to_str_common+Neg+Modulo+Mul>( + num: &T, radix: uint, negative_zero: bool, + sign: SignFormat, digits: SignificantDigits) -> (~str, bool) { + let (bytes, special) = to_str_bytes_common(num, radix, + negative_zero, sign, digits); + (str::from_bytes(bytes), special) +} + +// Some constants for from_str_bytes_common's input validation, +// they define minimum radix values for which the character is a valid digit. +priv const DIGIT_P_RADIX: uint = ('p' as uint) - ('a' as uint) + 11u; +priv const DIGIT_I_RADIX: uint = ('i' as uint) - ('a' as uint) + 11u; +priv const DIGIT_E_RADIX: uint = ('e' as uint) - ('a' as uint) + 11u; + +/** + * Parses a byte slice as a number. This is meant to + * be a common base implementation for all numeric string conversion + * functions like `from_str()` or `from_str_radix()`. + * + * # Arguments + * - `buf` - The byte slice to parse. + * - `radix` - Which base to parse the number as. Accepts 2-36. + * - `negative` - Whether to accept negative numbers. + * - `fractional` - Whether to accept numbers with fractional parts. + * - `special` - Whether to accept special values like `inf` + * and `NaN`. Can conflict with `radix`, see Failure. + * - `exponent` - Which exponent format to accept. Options are: + * - `ExpNone`: No Exponent, accepts just plain numbers like `42` or + * `-8.2`. + * - `ExpDec`: Accepts numbers with a decimal exponent like `42e5` or + * `8.2E-2`. The exponent string itself is always base 10. + * Can conflict with `radix`, see Failure. + * - `ExpBin`: Accepts numbers with a binary exponent like `42P-8` or + * `FFp128`. The exponent string itself is always base 10. + * Can conflict with `radix`, see Failure. + * - `empty_zero` - Whether to accept a empty `buf` as a 0 or not. + * + * # Return value + * Returns `Some(n)` if `buf` parses to a number n without overflowing, and + * `None` otherwise, depending on the constraints set by the remaining + * arguments. + * + * # Failure + * - Fails if `radix` < 2 or `radix` > 36. + * - Fails if `radix` > 14 and `exponent` is `ExpDec` due to conflict + * between digit and exponent sign `'e'`. + * - Fails if `radix` > 25 and `exponent` is `ExpBin` due to conflict + * between digit and exponent sign `'p'`. + * - Fails if `radix` > 18 and `special == true` due to conflict + * between digit and lowest first character in `inf` and `NaN`, the `'i'`. + * + * # Possible improvements + * - Could accept option to allow ignoring underscores, allowing for numbers + * formated like `FF_AE_FF_FF`. + */ +pub pure fn from_str_bytes_common+ + Mul+Sub+Neg+Add+ + NumStrConv>( + buf: &[u8], radix: uint, negative: bool, fractional: bool, + special: bool, exponent: ExponentFormat, empty_zero: bool + ) -> Option { + match exponent { + ExpDec if radix >= DIGIT_E_RADIX // decimal exponent 'e' + => fail!(fmt!("from_str_bytes_common: radix %? incompatible with \ + use of 'e' as decimal exponent", radix)), + ExpBin if radix >= DIGIT_P_RADIX // binary exponent 'p' + => fail!(fmt!("from_str_bytes_common: radix %? incompatible with \ + use of 'p' as binary exponent", radix)), + _ 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 + => fail!(fmt!("from_str_bytes_common: radix %? to low, \ + must lie in the range [2, 36]", radix)), + _ if radix as int > 36 + => fail!(fmt!("from_str_bytes_common: radix %? to high, \ + must lie in the range [2, 36]", radix)), + _ => () + } + + let _0: T = Zero::zero(); + let _1: T = One::one(); + let radix_gen: T = cast(radix as int); + + let len = buf.len(); + + if len == 0 { + if empty_zero { + return Some(_0); + } else { + return None; + } + } + + // XXX: Bytevector constant from str + if special { + if buf == str::to_bytes("inf") || buf == str::to_bytes("+inf") { + return NumStrConv::inf(); + } else if buf == str::to_bytes("-inf") { + if negative { + return NumStrConv::neg_inf(); + } else { + return None; + } + } else if buf == str::to_bytes("NaN") { + return NumStrConv::NaN(); + } + } + + let (start, accum_positive) = match buf[0] { + '-' as u8 if !negative => return None, + '-' as u8 => (1u, false), + '+' as u8 => (1u, true), + _ => (0u, true) + }; + + // Initialize accumulator with signed zero for floating point parsing to + // work + let mut accum = if accum_positive { _0 } else { -_1 * _0}; + let mut last_accum = accum; // Necessary to detect overflow + let mut i = start; + let mut exp_found = false; + + // Parse integer part of number + while i < len { + let c = buf[i] as char; + + match char::to_digit(c, radix) { + Some(digit) => { + // shift accum one digit left + accum *= radix_gen; + + // add/subtract current digit depending on sign + if accum_positive { + accum += cast(digit as int); + } else { + accum -= cast(digit as int); + } + + // Detect overflow by comparing to last value + if accum_positive && accum < last_accum { return None; } + if !accum_positive && accum > last_accum { return None; } + last_accum = accum; + } + None => match c { + 'e' | 'E' | 'p' | 'P' => { + exp_found = true; + break; // start of exponent + } + '.' if fractional => { + i += 1u; // skip the '.' + break; // start of fractional part + } + _ => return None // invalid number + } + } + + i += 1u; + } + + // Parse fractional part of number + // Skip if already reached start of exponent + if !exp_found { + let mut power = _1; + + while i < len { + let c = buf[i] as char; + + match char::to_digit(c, radix) { + Some(digit) => { + // Decrease power one order of magnitude + power /= radix_gen; + + let digit_t: T = cast(digit); + + // add/subtract current digit depending on sign + if accum_positive { + accum += digit_t * power; + } else { + accum -= digit_t * power; + } + + // Detect overflow by comparing to last value + if accum_positive && accum < last_accum { return None; } + if !accum_positive && accum > last_accum { return None; } + last_accum = accum; + } + None => match c { + 'e' | 'E' | 'p' | 'P' => { + exp_found = true; + break; // start of exponent + } + _ => return None // invalid number + } + } + + i += 1u; + } + } + + // Special case: buf not empty, but does not contain any digit in front + // of the exponent sign -> number is empty string + if i == start { + if empty_zero { + return Some(_0); + } else { + return None; + } + } + + let mut multiplier = _1; + + if exp_found { + let c = buf[i] as char; + let base = match (c, exponent) { + ('e', ExpDec) | ('E', ExpDec) => 10u, + ('p', ExpBin) | ('P', ExpBin) => 2u, + _ => return None // char doesn't fit given exponent format + }; + + // 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); + + match exp { + Some(exp_pow) => { + multiplier = if exp_pow < 0 { + _1 / pow_with_uint::(base, (-exp_pow.to_int()) as uint) + } else { + pow_with_uint::(base, exp_pow.to_int() as uint) + } + } + None => return None // invalid exponent -> invalid number + } + } + + Some(accum * multiplier) +} + +/** + * Parses a string as a number. This is a wrapper for + * `from_str_bytes_common()`, for details see there. + */ +#[inline(always)] +pub pure fn from_str_common+Mul+ + Sub+Neg+Add+NumStrConv>( + buf: &str, radix: uint, negative: bool, fractional: bool, + special: bool, exponent: ExponentFormat, empty_zero: bool + ) -> Option { + from_str_bytes_common(str::to_bytes(buf), radix, negative, + fractional, special, exponent, empty_zero) +} diff --git a/src/libcore/num/uint-template.rs b/src/libcore/num/uint-template.rs index b1ef3f11fa4e1..005f0f2b5a4df 100644 --- a/src/libcore/num/uint-template.rs +++ b/src/libcore/num/uint-template.rs @@ -17,6 +17,7 @@ use cmp; use to_str::ToStr; use from_str::FromStr; use num::{ToStrRadix, FromStrRadix}; +use num::strconv; use num; use option::{None, Option, Some}; use prelude::*; @@ -140,18 +141,6 @@ impl num::One for T { static pure fn one() -> T { 1 } } -impl num::Round for T { - #[inline(always)] - pure fn round(&self, _: num::RoundMode) -> T { *self } - - #[inline(always)] - pure fn floor(&self) -> T { *self } - #[inline(always)] - pure fn ceil(&self) -> T { *self } - #[inline(always)] - pure fn fract(&self) -> T { 0 } -} - #[cfg(notest)] impl ops::Add for T { pure fn add(&self, other: &T) -> T { *self + *other } @@ -182,22 +171,22 @@ impl ops::Neg for T { /// Parse a string as a number in base 10. #[inline(always)] pub pure fn from_str(s: &str) -> Option { - num::from_str_common(s, 10u, false, false, false, - num::ExpNone, false) + 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 { - num::from_str_common(s, radix, false, false, false, - num::ExpNone, false) + 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 { - num::from_str_bytes_common(buf, radix, false, false, false, - num::ExpNone, false) + strconv::from_str_bytes_common(buf, radix, false, false, false, + strconv::ExpNone, false) } impl FromStr for T { @@ -219,24 +208,24 @@ 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 { - let (buf, _) = num::to_str_bytes_common(&n, radix, false, false, - num::SignNeg, num::DigAll); + let (buf, _) = strconv::to_str_bytes_common(&n, radix, false, + strconv::SignNeg, strconv::DigAll); f(buf) } /// Convert to a string in base 10. #[inline(always)] pub pure fn to_str(num: T) -> ~str { - let (buf, _) = num::to_str_common(&num, 10u, false, false, - num::SignNeg, num::DigAll); + let (buf, _) = strconv::to_str_common(&num, 10u, false, + strconv::SignNeg, strconv::DigAll); buf } /// Convert to a string in a given base. #[inline(always)] pub pure fn to_str_radix(num: T, radix: uint) -> ~str { - let (buf, _) = num::to_str_common(&num, radix, false, false, - num::SignNeg, num::DigAll); + let (buf, _) = strconv::to_str_common(&num, radix, false, + strconv::SignNeg, strconv::DigAll); buf } diff --git a/src/libcore/num/uint-template/u16.rs b/src/libcore/num/uint-template/u16.rs index 57e1f5283f664..315ff84cc234c 100644 --- a/src/libcore/num/uint-template/u16.rs +++ b/src/libcore/num/uint-template/u16.rs @@ -19,7 +19,7 @@ mod inst { pub const bits: uint = 16; } -pub impl u16: NumCast { +pub impl NumCast for u16 { /** * Cast `n` to a `u16` */ diff --git a/src/libcore/num/uint-template/u32.rs b/src/libcore/num/uint-template/u32.rs index 7099d15c40b49..834feff292c59 100644 --- a/src/libcore/num/uint-template/u32.rs +++ b/src/libcore/num/uint-template/u32.rs @@ -19,7 +19,7 @@ mod inst { pub const bits: uint = 32; } -pub impl u32: NumCast { +pub impl NumCast for u32 { /** * Cast `n` to a `u32` */ diff --git a/src/libcore/num/uint-template/u64.rs b/src/libcore/num/uint-template/u64.rs index f4d1482de905f..b661b3b20b1cd 100644 --- a/src/libcore/num/uint-template/u64.rs +++ b/src/libcore/num/uint-template/u64.rs @@ -19,7 +19,7 @@ mod inst { pub const bits: uint = 64; } -pub impl u64: num::NumCast { +pub impl NumCast for u64 { /** * Cast `n` to a `u64` */ diff --git a/src/libcore/num/uint-template/u8.rs b/src/libcore/num/uint-template/u8.rs index e2f8e00db8197..c2be9e252d9a1 100644 --- a/src/libcore/num/uint-template/u8.rs +++ b/src/libcore/num/uint-template/u8.rs @@ -26,7 +26,7 @@ mod inst { pub pure fn is_ascii(x: T) -> bool { return 0 as T == x & 128 as T; } } -pub impl u8: NumCast { +pub impl NumCast for u8 { /** * Cast `n` to a `u8` */ diff --git a/src/libcore/num/uint-template/uint.rs b/src/libcore/num/uint-template/uint.rs index cfb445cbdc878..475ae243915d9 100644 --- a/src/libcore/num/uint-template/uint.rs +++ b/src/libcore/num/uint-template/uint.rs @@ -110,7 +110,7 @@ pub mod inst { return true; } - pub impl uint: iter::Times { + pub impl iter::Times for uint { #[inline(always)] /** * A convenience form for basic iteration. Given a uint `x`, @@ -209,7 +209,7 @@ pub mod inst { } } -pub impl uint: NumCast { +pub impl NumCast for uint { /** * Cast `n` to a `uint` */ diff --git a/src/libcore/option.rs b/src/libcore/option.rs index e57d664c2aaee..e27b7086bc45b 100644 --- a/src/libcore/option.rs +++ b/src/libcore/option.rs @@ -33,15 +33,15 @@ match msg { } // Remove the contained string, destroying the Option -let unwrapped_msg = match move msg { - Some(move m) => m, +let unwrapped_msg = match msg { + Some(m) => m, None => ~"default message" }; ~~~ */ -use cmp::Eq; +use cmp::{Eq,Ord}; use kinds::Copy; use option; use ptr; @@ -56,8 +56,36 @@ pub enum Option { Some(T), } +pub impl Ord for Option { + pure fn lt(&self, other: &Option) -> bool { + match (self, other) { + (&None, &None) => false, + (&None, &Some(_)) => true, + (&Some(_), &None) => false, + (&Some(ref a), &Some(ref b)) => *a < *b + } + } + + pure fn le(&self, other: &Option) -> bool { + match (self, other) { + (&None, &None) => true, + (&None, &Some(_)) => true, + (&Some(_), &None) => false, + (&Some(ref a), &Some(ref b)) => *a <= *b + } + } + + pure fn ge(&self, other: &Option) -> bool { + ! (self < other) + } + + pure fn gt(&self, other: &Option) -> bool { + ! (self <= other) + } +} + #[inline(always)] -pub pure fn get(opt: Option) -> T { +pub pure fn get(opt: Option) -> T { /*! Gets the value out of an option @@ -126,8 +154,8 @@ pub pure fn chain(opt: Option, * function that returns an option. */ - match move opt { - Some(move t) => f(move t), + match opt { + Some(t) => f(t), None => None } } @@ -148,9 +176,9 @@ pub pure fn or(opta: Option, optb: Option) -> Option { /*! * Returns the leftmost Some() value, or None if both are None. */ - match move opta { - Some(move opta) => Some(move opta), - _ => move optb + match opta { + Some(opta) => Some(opta), + _ => optb } } @@ -158,9 +186,9 @@ pub pure fn or(opta: Option, optb: Option) -> Option { pub pure fn while_some(x: Option, blk: fn(v: T) -> Option) { //! Applies a function zero or more times until the result is none. - let mut opt = move x; + let mut opt = x; while opt.is_some() { - opt = blk(unwrap(move opt)); + opt = blk(unwrap(opt)); } } @@ -179,14 +207,14 @@ pub pure fn is_some(opt: &Option) -> bool { } #[inline(always)] -pub pure fn get_or_zero(opt: Option) -> T { +pub pure 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 pure fn get_or_default(opt: Option, def: T) -> T { //! Returns the contained value or a default match opt { Some(copy x) => x, None => def } @@ -197,7 +225,7 @@ pub pure 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 - match *opt { None => move def, Some(ref t) => f(t) } + match *opt { None => def, Some(ref t) => f(t) } } #[inline(always)] @@ -224,8 +252,8 @@ pub pure fn unwrap(opt: Option) -> T { Instead, prefer to use pattern matching and handle the `None` case explicitly. */ - match move opt { - Some(move x) => move x, + match opt { + Some(x) => x, None => fail!(~"option::unwrap none") } } @@ -247,8 +275,8 @@ pub fn swap_unwrap(opt: &mut Option) -> T { #[inline(always)] pub pure fn expect(opt: Option, reason: &str) -> T { //! As unwrap, but with a specified failure message. - match move opt { - Some(move val) => val, + match opt { + Some(val) => val, None => fail!(reason.to_owned()), } } @@ -285,7 +313,7 @@ impl Option { /// 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 { - map_default(self, move def, f) + map_default(self, def, f) } /// As `map_default`, but consumes the option and gives `f` @@ -365,7 +393,7 @@ impl Option { pure fn expect(self, reason: &str) -> T { expect(self, reason) } } -impl Option { +impl Option { /** Gets the value out of an option @@ -393,7 +421,7 @@ impl Option { } } -impl Option { +impl Option { #[inline(always)] pure fn get_or_zero(self) -> T { get_or_zero(self) } } @@ -402,8 +430,8 @@ impl Option { fn test_unwrap_ptr() { let x = ~0; let addr_x = ptr::addr_of(&(*x)); - let opt = Some(move x); - let y = unwrap(move opt); + let opt = Some(x); + let y = unwrap(opt); let addr_y = ptr::addr_of(&(*y)); assert addr_x == addr_y; } @@ -412,8 +440,8 @@ fn test_unwrap_ptr() { fn test_unwrap_str() { let x = ~"test"; let addr_x = str::as_buf(x, |buf, _len| buf); - let opt = Some(move x); - let y = unwrap(move opt); + let opt = Some(x); + let y = unwrap(opt); let addr_y = str::as_buf(y, |buf, _len| buf); assert addr_x == addr_y; } @@ -434,8 +462,8 @@ fn test_unwrap_resource() { let i = @mut 0; { let x = R(i); - let opt = Some(move x); - let _y = unwrap(move opt); + let opt = Some(x); + let _y = unwrap(opt); } assert *i == 1; } diff --git a/src/libcore/os.rs b/src/libcore/os.rs index 6ed8d70642cce..8a512da7dc0ea 100644 --- a/src/libcore/os.rs +++ b/src/libcore/os.rs @@ -108,9 +108,10 @@ pub mod win32 { let mut res = None; let mut done = false; while !done { - let mut buf = vec::from_elem(n as uint, 0u16); + let mut k: DWORD = 0; + let buf = vec::cast_to_mut(vec::from_elem(n as uint, 0u16)); do vec::as_mut_buf(buf) |b, _sz| { - let k : DWORD = f(b, TMPBUF_SZ as DWORD); + k = f(b, TMPBUF_SZ as DWORD); if k == (0 as DWORD) { done = true; } else if (k == n && @@ -118,11 +119,13 @@ pub mod win32 { libc::ERROR_INSUFFICIENT_BUFFER as DWORD) { n *= (2 as DWORD); } else { - let sub = vec::slice(buf, 0u, k as uint); - res = option::Some(str::from_utf16(sub)); done = true; } } + if k != 0 && done { + let sub = vec::slice(buf, 0u, k as uint); + res = option::Some(str::from_utf16(sub)); + } } return res; } @@ -171,7 +174,7 @@ pub fn env() -> ~[(~str,~str)] { assert vec::len(vs) == 2u; pairs.push((copy vs[0], copy vs[1])); } - move pairs + pairs } } } @@ -306,10 +309,9 @@ pub fn waitpid(pid: pid_t) -> c_int { pub fn waitpid(pid: pid_t) -> c_int { unsafe { use libc::funcs::posix01::wait::*; - let status = 0 as c_int; + let mut status = 0 as c_int; - assert (waitpid(pid, ptr::mut_addr_of(&status), - 0 as c_int) != (-1 as c_int)); + assert (waitpid(pid, &mut status, 0 as c_int) != (-1 as c_int)); return status; } } @@ -322,7 +324,7 @@ pub fn pipe() -> Pipe { unsafe { let mut fds = Pipe {mut in: 0 as c_int, mut out: 0 as c_int }; - assert (libc::pipe(ptr::mut_addr_of(&(fds.in))) == (0 as c_int)); + assert (libc::pipe(&mut fds.in) == (0 as c_int)); return Pipe {in: fds.in, out: fds.out}; } } @@ -339,8 +341,7 @@ pub fn pipe() -> Pipe { // first, as in rust_run_program. let mut fds = Pipe { mut in: 0 as c_int, mut out: 0 as c_int }; - let res = libc::pipe(ptr::mut_addr_of(&(fds.in)), - 1024 as c_uint, + let res = libc::pipe(&mut fds.in, 1024 as c_uint, (libc::O_BINARY | libc::O_NOINHERIT) as c_int); assert (res == 0 as c_int); assert (fds.in != -1 as c_int && fds.in != 0 as c_int); @@ -373,9 +374,10 @@ pub fn self_exe_path() -> Option { let mib = ~[CTL_KERN as c_int, KERN_PROC as c_int, KERN_PROC_PATHNAME as c_int, -1 as c_int]; + let mut sz = sz; sysctl(vec::raw::to_ptr(mib), vec::len(mib) as c_uint, - buf as *mut c_void, ptr::mut_addr_of(&sz), - ptr::null(), 0u as size_t) == (0 as c_int) + buf as *mut c_void, &mut sz, ptr::null(), + 0u as size_t) == (0 as c_int) } } } @@ -406,8 +408,9 @@ pub fn self_exe_path() -> Option { fn load_self() -> Option<~str> { unsafe { do fill_charp_buf() |buf, sz| { + let mut sz = sz as u32; libc::funcs::extra::_NSGetExecutablePath( - buf, ptr::mut_addr_of(&(sz as u32))) == (0 as c_int) + buf, &mut sz) == (0 as c_int) } } } @@ -483,7 +486,7 @@ pub fn tmpdir() -> Path { fn getenv_nonempty(v: &str) -> Option { match getenv(v) { - Some(move x) => + Some(x) => if str::is_empty(x) { None } else { @@ -849,7 +852,7 @@ pub fn last_os_error() -> ~str { let err = strerror_r(errno() as c_int, &buf[0], TMPBUF_SZ as size_t); if err < 0 { - die!(~"strerror_r failure"); + fail!(~"strerror_r failure"); } str::raw::from_c_str(&buf[0]) @@ -887,7 +890,7 @@ pub fn last_os_error() -> ~str { &mut buf[0], TMPBUF_SZ as DWORD, ptr::null()); if res == 0 { - die!(fmt!("[%?] FormatMessage failure", errno())); + fail!(fmt!("[%?] FormatMessage failure", errno())); } str::raw::from_c_str(&buf[0]) @@ -916,7 +919,7 @@ unsafe fn load_argc_and_argv(argc: c_int, argv: **c_char) -> ~[~str] { for uint::range(0, argc as uint) |i| { vec::push(&mut args, str::raw::from_c_str(*argv.offset(i))); } - move args + args } /** @@ -1138,7 +1141,7 @@ mod tests { let rng: rand::Rng = rand::Rng(); let n = ~"TEST" + rng.gen_str(10u); assert getenv(n).is_none(); - move n + n } #[test] @@ -1172,7 +1175,7 @@ mod tests { let n = make_rand_name(); setenv(n, s); log(debug, copy s); - assert getenv(n) == option::Some(move s); + assert getenv(n) == option::Some(s); } #[test] @@ -1198,7 +1201,7 @@ mod tests { // MingW seems to set some funky environment variables like // "=C:=C:\MinGW\msys\1.0\bin" and "!::=::\" that are returned // from env() but not visible from getenv(). - assert v2.is_none() || v2 == option::Some(move v); + assert v2.is_none() || v2 == option::Some(v); } } @@ -1211,7 +1214,7 @@ mod tests { assert !vec::contains(e, &(copy n, ~"VALUE")); e = env(); - assert vec::contains(e, &(move n, ~"VALUE")); + assert vec::contains(e, &(n, ~"VALUE")); } #[test] diff --git a/src/libcore/path.rs b/src/libcore/path.rs index 91690b6b5b0b2..531ce95d067be 100644 --- a/src/libcore/path.rs +++ b/src/libcore/path.rs @@ -243,9 +243,9 @@ impl Path { unsafe { do str::as_c_str(self.to_str()) |buf| { let mut st = stat::arch::default_stat(); - let r = libc::stat(buf, ptr::mut_addr_of(&st)); + let r = libc::stat(buf, &mut st); - if r == 0 { Some(move st) } else { None } + if r == 0 { Some(st) } else { None } } } } @@ -255,9 +255,9 @@ impl Path { unsafe { do str::as_c_str(self.to_str()) |buf| { let mut st = stat::arch::default_stat(); - let r = libc::lstat(buf, ptr::mut_addr_of(&st)); + let r = libc::lstat(buf, &mut st); - if r == 0 { Some(move st) } else { None } + if r == 0 { Some(st) } else { None } } } } @@ -381,7 +381,7 @@ impl GenericPath for 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: move components } + components: components } } pure fn dirname() -> ~str { @@ -390,7 +390,7 @@ impl GenericPath for PosixPath { if s.len() == 0 { ~"." } else { - move s + s } } } @@ -430,7 +430,7 @@ impl GenericPath for PosixPath { let dpath = PosixPath(d); match self.filename() { Some(ref f) => dpath.push(*f), - None => move dpath + None => dpath } } @@ -477,7 +477,7 @@ impl GenericPath for PosixPath { Some(ref f) => ~[copy *f] }; return PosixPath { is_absolute: false, - components: move cs } + components: cs } } pure fn push_rel(other: &PosixPath) -> PosixPath { @@ -491,17 +491,17 @@ impl GenericPath for PosixPath { let mut ss = str::split_nonempty( *e, |c| windows::is_sep(c as u8)); - unsafe { v.push_all_move(move ss); } + unsafe { v.push_all_move(ss); } } PosixPath { is_absolute: self.is_absolute, - components: move v } + components: v } } pure fn push(s: &str) -> PosixPath { let mut v = copy self.components; let mut ss = str::split_nonempty(s, |c| windows::is_sep(c as u8)); - unsafe { v.push_all_move(move ss); } - PosixPath { components: move v, ..copy self } + unsafe { v.push_all_move(ss); } + PosixPath { components: v, ..copy self } } pure fn pop() -> PosixPath { @@ -511,7 +511,7 @@ impl GenericPath for PosixPath { } return PosixPath { is_absolute: self.is_absolute, - components: move cs + components: cs } //..self } } @@ -577,10 +577,10 @@ impl GenericPath for WindowsPath { let mut components = str::split_nonempty(rest, |c| windows::is_sep(c as u8)); let is_absolute = (rest.len() != 0 && windows::is_sep(rest[0])); - return WindowsPath { host: move host, - device: move device, + return WindowsPath { host: host, + device: device, is_absolute: is_absolute, - components: move components } + components: components } } pure fn dirname() -> ~str { @@ -589,7 +589,7 @@ impl GenericPath for WindowsPath { if s.len() == 0 { ~"." } else { - move s + s } } } @@ -629,7 +629,7 @@ impl GenericPath for WindowsPath { let dpath = WindowsPath(d); match self.filename() { Some(ref f) => dpath.push(*f), - None => move dpath + None => dpath } } @@ -677,7 +677,7 @@ impl GenericPath for WindowsPath { return WindowsPath { host: None, device: None, is_absolute: false, - components: move cs } + components: cs } } pure fn push_rel(other: &WindowsPath) -> WindowsPath { @@ -691,22 +691,22 @@ impl GenericPath for WindowsPath { let mut ss = str::split_nonempty( *e, |c| windows::is_sep(c as u8)); - unsafe { v.push_all_move(move ss); } + unsafe { v.push_all_move(ss); } } // tedious, but as-is, we can't use ..self return WindowsPath { host: copy self.host, device: copy self.device, is_absolute: self.is_absolute, - components: move v + components: v } } pure fn push(s: &str) -> WindowsPath { let mut v = copy self.components; let mut ss = str::split_nonempty(s, |c| windows::is_sep(c as u8)); - unsafe { v.push_all_move(move ss); } - return WindowsPath { components: move v, ..copy self } + unsafe { v.push_all_move(ss); } + return WindowsPath { components: v, ..copy self } } pure fn pop() -> WindowsPath { @@ -718,7 +718,7 @@ impl GenericPath for WindowsPath { host: copy self.host, device: copy self.device, is_absolute: self.is_absolute, - components: move cs + components: cs } } @@ -748,7 +748,7 @@ pub pure fn normalize(components: &[~str]) -> ~[~str] { } } } - move cs + cs } // Various windows helpers, and tests for the impl. @@ -771,7 +771,7 @@ pub mod windows { if s[i] == '\\' as u8 { let pre = s.slice(2, i); let rest = s.slice(i, s.len()); - return Some((move pre, move rest)); + return Some((pre, rest)); } i += 1; } @@ -789,7 +789,7 @@ pub mod windows { } else { s.slice(2, s.len()) }; - return Some((s.slice(0,1), move rest)); + return Some((s.slice(0,1), rest)); } None } diff --git a/src/libcore/pipes.rs b/src/libcore/pipes.rs index a26a6b5f8ec3d..94c0a567f4c09 100644 --- a/src/libcore/pipes.rs +++ b/src/libcore/pipes.rs @@ -92,6 +92,7 @@ use libc; use option; use option::{None, Option, Some, unwrap}; use pipes; +use private::intrinsics; use ptr; use private; use task; @@ -101,7 +102,7 @@ use vec; const SPIN_COUNT: uint = 0; macro_rules! move_it ( - { $x:expr } => ( unsafe { let y = move *ptr::addr_of(&($x)); move y } ) + { $x:expr } => ( unsafe { let y = *ptr::addr_of(&($x)); y } ) ) #[doc(hidden)] @@ -141,7 +142,7 @@ pub struct Buffer { data: T, } -struct PacketHeader { +pub struct PacketHeader { mut state: State, mut blocked_task: *rust_task, @@ -150,7 +151,7 @@ struct PacketHeader { mut buffer: *libc::c_void, } -fn PacketHeader() -> PacketHeader { +pub fn PacketHeader() -> PacketHeader { PacketHeader { state: Empty, blocked_task: ptr::null(), @@ -158,7 +159,7 @@ fn PacketHeader() -> PacketHeader { } } -impl PacketHeader { +pub impl PacketHeader { // Returns the old state. unsafe fn mark_blocked(this: *rust_task) -> State { rustrt::rust_task_ref(this); @@ -189,7 +190,7 @@ impl PacketHeader { reinterpret_cast(&self.buffer) } - fn set_buffer(b: ~Buffer) { + fn set_buffer(b: ~Buffer) { unsafe { self.buffer = reinterpret_cast(&b); } @@ -207,14 +208,14 @@ pub trait HasBuffer { fn set_buffer(b: *libc::c_void); } -impl HasBuffer for Packet { +impl HasBuffer for Packet { fn set_buffer(b: *libc::c_void) { self.header.buffer = b; } } #[doc(hidden)] -pub fn mk_packet() -> Packet { +pub fn mk_packet() -> Packet { Packet { header: PacketHeader(), payload: None, @@ -233,7 +234,7 @@ fn unibuffer() -> ~Buffer> { unsafe { b.data.header.buffer = reinterpret_cast(&b); } - move b + b } #[doc(hidden)] @@ -241,52 +242,41 @@ pub fn packet() -> *Packet { let b = unibuffer(); let p = ptr::addr_of(&(b.data)); // We'll take over memory management from here. - unsafe { forget(move b) } + unsafe { forget(b) } p } #[doc(hidden)] -pub fn entangle_buffer( +pub fn entangle_buffer( buffer: ~Buffer, init: fn(*libc::c_void, x: &T) -> *Packet) -> (SendPacketBuffered, RecvPacketBuffered) { let p = init(unsafe { reinterpret_cast(&buffer) }, &buffer.data); - unsafe { forget(move buffer) } + unsafe { forget(buffer) } (SendPacketBuffered(p), RecvPacketBuffered(p)) } -#[abi = "rust-intrinsic"] -#[doc(hidden)] -extern mod rusti { - fn atomic_xchg(dst: &mut int, src: int) -> int; - fn atomic_xchg_acq(dst: &mut int, src: int) -> int; - fn atomic_xchg_rel(dst: &mut int, src: int) -> int; - - fn atomic_xadd_acq(dst: &mut int, src: int) -> int; - fn atomic_xsub_rel(dst: &mut int, src: int) -> int; -} - // If I call the rusti versions directly from a polymorphic function, // I get link errors. This is a bug that needs investigated more. #[doc(hidden)] pub fn atomic_xchng_rel(dst: &mut int, src: int) -> int { unsafe { - rusti::atomic_xchg_rel(dst, src) + intrinsics::atomic_xchg_rel(dst, src) } } #[doc(hidden)] pub fn atomic_add_acq(dst: &mut int, src: int) -> int { unsafe { - rusti::atomic_xadd_acq(dst, src) + intrinsics::atomic_xadd_acq(dst, src) } } #[doc(hidden)] pub fn atomic_sub_rel(dst: &mut int, src: int) -> int { unsafe { - rusti::atomic_xsub_rel(dst, src) + intrinsics::atomic_xsub_rel(dst, src) } } @@ -295,7 +285,7 @@ pub fn swap_task(dst: &mut *rust_task, src: *rust_task) -> *rust_task { // It might be worth making both acquire and release versions of // this. unsafe { - transmute(rusti::atomic_xchg(transmute(move dst), src as int)) + transmute(intrinsics::atomic_xchg(transmute(dst), src as int)) } } @@ -335,14 +325,14 @@ fn wait_event(this: *rust_task) -> *libc::c_void { #[doc(hidden)] fn swap_state_acq(dst: &mut State, src: State) -> State { unsafe { - transmute(rusti::atomic_xchg_acq(transmute(move dst), src as int)) + transmute(intrinsics::atomic_xchg_acq(transmute(dst), src as int)) } } #[doc(hidden)] fn swap_state_rel(dst: &mut State, src: State) -> State { unsafe { - transmute(rusti::atomic_xchg_rel(transmute(move dst), src as int)) + transmute(intrinsics::atomic_xchg_rel(transmute(dst), src as int)) } } @@ -368,7 +358,7 @@ struct BufferResource { // go go gadget drop glue } else { - forget(move b) + forget(b) } } } @@ -381,7 +371,7 @@ fn BufferResource(b: ~Buffer) -> BufferResource { BufferResource { // tjc: ???? - buffer: move b + buffer: b } } @@ -392,7 +382,7 @@ pub fn send(p: SendPacketBuffered, payload: T) -> bool { let p = unsafe { &*p_ }; assert ptr::addr_of(&(p.header)) == header; assert p.payload.is_none(); - p.payload = move Some(move payload); + p.payload = Some(payload); let old_state = swap_state_rel(&mut p.header.state, Full); match old_state { Empty => { @@ -432,9 +422,9 @@ pub fn send(p: SendPacketBuffered, payload: T) -> bool { Fails if the sender closes the connection. */ -pub fn recv( +pub fn recv( p: RecvPacketBuffered) -> T { - try_recv(move p).expect("connection closed") + try_recv(p).expect("connection closed") } /** Attempts to receive a message from a pipe. @@ -443,7 +433,7 @@ Returns `None` if the sender has closed the connection without sending a message, or `Some(T)` if a message was received. */ -pub fn try_recv(p: RecvPacketBuffered) +pub fn try_recv(p: RecvPacketBuffered) -> Option { let p_ = p.unwrap(); @@ -474,7 +464,7 @@ pub fn try_recv(p: RecvPacketBuffered) let mut payload = None; payload <-> p.payload; p.header.state = Empty; - return Some(option::unwrap(move payload)) + return Some(option::unwrap(payload)) }, Terminated => return None, _ => {} @@ -532,7 +522,7 @@ pub fn try_recv(p: RecvPacketBuffered) } } p.header.state = Empty; - return Some(option::unwrap(move payload)) + return Some(option::unwrap(payload)) } Terminated => { // This assert detects when we've accidentally unsafely @@ -553,7 +543,7 @@ pub fn try_recv(p: RecvPacketBuffered) } /// Returns true if messages are available. -pub pure fn peek(p: &RecvPacketBuffered) -> bool { +pub pure fn peek(p: &RecvPacketBuffered) -> bool { match unsafe {(*p.header()).state} { Empty | Terminated => false, Blocked => fail!(~"peeking on blocked packet"), @@ -561,14 +551,8 @@ pub pure fn peek(p: &RecvPacketBuffered) -> bool { } } -impl Peekable for RecvPacketBuffered { - pure fn peek() -> bool { - peek(&self) - } -} - #[doc(hidden)] -fn sender_terminate(p: *Packet) { +fn sender_terminate(p: *Packet) { let p = unsafe { &*p }; match swap_state_rel(&mut p.header.state, Terminated) { Empty => { @@ -599,7 +583,7 @@ fn sender_terminate(p: *Packet) { } #[doc(hidden)] -fn receiver_terminate(p: *Packet) { +fn receiver_terminate(p: *Packet) { let p = unsafe { &*p }; match swap_state_rel(&mut p.header.state, Terminated) { Empty => { @@ -632,7 +616,7 @@ that vector. The index points to an endpoint that has either been closed by the sender or has a message waiting to be received. */ -fn wait_many(pkts: &[T]) -> uint { +pub fn wait_many(pkts: &[T]) -> uint { let this = unsafe { rustrt::rust_get_task() }; unsafe { @@ -714,7 +698,7 @@ Sometimes messages will be available on both endpoints at once. In this case, `select2` may return either `left` or `right`. */ -pub fn select2( +pub fn select2( a: RecvPacketBuffered, b: RecvPacketBuffered) -> Either<(Option, RecvPacketBuffered), @@ -723,14 +707,14 @@ pub fn select2( let i = wait_many([a.header(), b.header()]); match i { - 0 => Left((try_recv(move a), move b)), - 1 => Right((move a, try_recv(move b))), + 0 => Left((try_recv(a), b)), + 1 => Right((a, try_recv(b))), _ => fail!(~"select2 return an invalid packet") } } #[doc(hidden)] -trait Selectable { +pub trait Selectable { pure fn header() -> *PacketHeader; } @@ -739,12 +723,12 @@ impl Selectable for *PacketHeader { } /// Returns the index of an endpoint that is ready to receive. -pub fn selecti(endpoints: &[T]) -> uint { +pub fn selecti(endpoints: &[T]) -> uint { wait_many(endpoints) } /// Returns 0 or 1 depending on which endpoint is ready to receive -pub fn select2i(a: &A, b: &B) -> +pub fn select2i(a: &A, b: &B) -> Either<(), ()> { match wait_many([a.header(), b.header()]) { 0 => Left(()), @@ -757,14 +741,14 @@ pub fn select2i(a: &A, b: &B) -> list of the remaining endpoints. */ -pub fn select(endpoints: ~[RecvPacketBuffered]) +pub fn select(endpoints: ~[RecvPacketBuffered]) -> (uint, Option, ~[RecvPacketBuffered]) { let ready = wait_many(endpoints.map(|p| p.header())); - let mut remaining = move endpoints; + let mut remaining = endpoints; let port = remaining.swap_remove(ready); - let result = try_recv(move port); - (ready, move result, move remaining) + let result = try_recv(port); + (ready, result, remaining) } /** The sending end of a pipe. It can be used to send exactly one @@ -791,7 +775,7 @@ impl ::ops::Drop for SendPacketBuffered { if self.p != None { let mut p = None; p <-> self.p; - sender_terminate(option::unwrap(move p)) + sender_terminate(option::unwrap(p)) } //unsafe { error!("send_drop: %?", // if self.buffer == none { @@ -816,7 +800,7 @@ impl SendPacketBuffered { fn unwrap() -> *Packet { let mut p = None; p <-> self.p; - option::unwrap(move p) + option::unwrap(p) } pure fn header() -> *PacketHeader { @@ -835,7 +819,7 @@ impl SendPacketBuffered { //error!("send reuse_buffer"); let mut tmp = None; tmp <-> self.buffer; - option::unwrap(move tmp) + option::unwrap(tmp) } } @@ -852,7 +836,7 @@ pub struct RecvPacketBuffered { mut buffer: Option>, } -impl ::ops::Drop for RecvPacketBuffered { +impl ::ops::Drop for RecvPacketBuffered { fn finalize(&self) { //if self.p != none { // debug!("drop recv %?", option::get(self.p)); @@ -860,7 +844,7 @@ impl ::ops::Drop for RecvPacketBuffered { if self.p != None { let mut p = None; p <-> self.p; - receiver_terminate(option::unwrap(move p)) + receiver_terminate(option::unwrap(p)) } //unsafe { error!("recv_drop: %?", // if self.buffer == none { @@ -869,22 +853,22 @@ impl ::ops::Drop for RecvPacketBuffered { } } -impl RecvPacketBuffered { +impl RecvPacketBuffered { fn unwrap() -> *Packet { let mut p = None; p <-> self.p; - option::unwrap(move p) + option::unwrap(p) } fn reuse_buffer() -> BufferResource { //error!("recv reuse_buffer"); let mut tmp = None; tmp <-> self.buffer; - option::unwrap(move tmp) + option::unwrap(tmp) } } -impl Selectable for RecvPacketBuffered { +impl Selectable for RecvPacketBuffered { pure fn header() -> *PacketHeader { match self.p { Some(packet) => unsafe { @@ -923,7 +907,7 @@ endpoint. The send endpoint is returned to the caller and the receive endpoint is passed to the new task. */ -pub fn spawn_service( +pub fn spawn_service( init: extern fn() -> (SendPacketBuffered, RecvPacketBuffered), service: fn~(v: RecvPacketBuffered)) @@ -933,21 +917,21 @@ pub fn spawn_service( // This is some nasty gymnastics required to safely move the pipe // into a new task. - let server = ~mut Some(move server); - do task::spawn |move service, move server| { + let server = ~mut Some(server); + do task::spawn || { let mut server_ = None; server_ <-> *server; - service(option::unwrap(move server_)) + service(option::unwrap(server_)) } - move client + client } /** Like `spawn_service_recv`, but for protocols that start in the receive state. */ -pub fn spawn_service_recv( +pub fn spawn_service_recv( init: extern fn() -> (RecvPacketBuffered, SendPacketBuffered), service: fn~(v: SendPacketBuffered)) @@ -957,343 +941,14 @@ pub fn spawn_service_recv( // This is some nasty gymnastics required to safely move the pipe // into a new task. - let server = ~mut Some(move server); - do task::spawn |move service, move server| { + let server = ~mut Some(server); + do task::spawn || { let mut server_ = None; server_ <-> *server; - service(option::unwrap(move server_)) - } - - move client -} - -// Streams - Make pipes a little easier in general. - -proto! streamp ( - Open:send { - data(T) -> Open - } -) - -/// A trait for things that can send multiple messages. -pub trait GenericChan { - /// Sends a message. - fn send(x: T); -} - -/// Things that can send multiple messages and can detect when the receiver -/// is closed -pub trait GenericSmartChan { - /// Sends a message, or report if the receiver has closed the connection. - fn try_send(x: T) -> bool; -} - -/// A trait for things that can receive multiple messages. -pub trait GenericPort { - /// Receives a message, or fails if the connection closes. - fn recv() -> T; - - /** Receives a message, or returns `none` if - the connection is closed or closes. - */ - fn try_recv() -> Option; -} - -/// Ports that can `peek` -pub trait Peekable { - /// Returns true if a message is available - pure fn peek() -> bool; -} - -#[doc(hidden)] -struct Chan_ { - mut endp: Option> -} - -/// An endpoint that can send many messages. -pub enum Chan { - Chan_(Chan_) -} - -#[doc(hidden)] -struct Port_ { - mut endp: Option>, -} - -/// An endpoint that can receive many messages. -pub enum Port { - Port_(Port_) -} - -/** Creates a `(chan, port)` pair. - -These allow sending or receiving an unlimited number of messages. - -*/ -pub fn stream() -> (Port, Chan) { - let (c, s) = streamp::init(); - - (Port_(Port_ { endp: Some(s) }), Chan_(Chan_{ endp: Some(c) })) -} - -impl GenericChan for Chan { - fn send(x: T) { - let mut endp = None; - endp <-> self.endp; - self.endp = Some( - streamp::client::data(unwrap(move endp), move x)) - } -} - -impl GenericSmartChan for Chan { - - fn try_send(x: T) -> bool { - let mut endp = None; - endp <-> self.endp; - match move streamp::client::try_data(unwrap(move endp), move x) { - Some(move next) => { - self.endp = Some(move next); - true - } - None => false - } - } -} - -impl GenericPort for Port { - fn recv() -> T { - let mut endp = None; - endp <-> self.endp; - let streamp::data(x, endp) = pipes::recv(unwrap(move endp)); - self.endp = Some(move endp); - move x - } - - fn try_recv() -> Option { - let mut endp = None; - endp <-> self.endp; - match move pipes::try_recv(unwrap(move endp)) { - Some(streamp::data(move x, move endp)) => { - self.endp = Some(move endp); - Some(move x) - } - None => None - } - } -} - -impl Peekable for Port { - pure fn peek() -> bool { - unsafe { - let mut endp = None; - endp <-> self.endp; - let peek = match &endp { - &Some(ref endp) => pipes::peek(endp), - &None => fail!(~"peeking empty stream") - }; - self.endp <-> endp; - peek - } - } -} - -impl Selectable for Port { - pure fn header() -> *PacketHeader { - unsafe { - match self.endp { - Some(ref endp) => endp.header(), - None => fail!(~"peeking empty stream") - } - } - } -} - -/// Treat many ports as one. -pub struct PortSet { - mut ports: ~[pipes::Port], -} - -pub fn PortSet() -> PortSet{ - PortSet { - ports: ~[] - } -} - -impl PortSet { - - fn add(port: pipes::Port) { - self.ports.push(move port) - } - - fn chan() -> Chan { - let (po, ch) = stream(); - self.add(move po); - move ch - } -} - -impl GenericPort for PortSet { - - fn try_recv() -> Option { - let mut result = None; - // we have to swap the ports array so we aren't borrowing - // aliasable mutable memory. - let mut ports = ~[]; - ports <-> self.ports; - while result.is_none() && ports.len() > 0 { - let i = wait_many(ports); - match move ports[i].try_recv() { - Some(move m) => { - result = Some(move m); - } - None => { - // Remove this port. - let _ = ports.swap_remove(i); - } - } - } - ports <-> self.ports; - move result - } - - fn recv() -> T { - self.try_recv().expect("port_set: endpoints closed") - } - -} - -impl Peekable for PortSet { - pure fn peek() -> bool { - // It'd be nice to use self.port.each, but that version isn't - // pure. - for vec::each(self.ports) |p| { - if p.peek() { return true } - } - false - } -} - -/// A channel that can be shared between many senders. -pub type SharedChan = private::Exclusive>; - -impl GenericChan for SharedChan { - fn send(x: T) { - let mut xx = Some(move x); - do self.with_imm |chan| { - let mut x = None; - x <-> xx; - chan.send(option::unwrap(move x)) - } - } -} - -impl GenericSmartChan for SharedChan { - fn try_send(x: T) -> bool { - let mut xx = Some(move x); - do self.with_imm |chan| { - let mut x = None; - x <-> xx; - chan.try_send(option::unwrap(move x)) - } + service(option::unwrap(server_)) } -} - -/// Converts a `chan` into a `shared_chan`. -pub fn SharedChan(c: Chan) -> SharedChan { - private::exclusive(move c) -} - -/// Receive a message from one of two endpoints. -pub trait Select2 { - /// Receive a message or return `None` if a connection closes. - fn try_select() -> Either, Option>; - /// Receive a message or fail if a connection closes. - fn select() -> Either; -} - -impl, - Right: Selectable GenericPort> - (Left, Right): Select2 { - - fn select() -> Either { - match self { - (ref lp, ref rp) => match select2i(lp, rp) { - Left(()) => Left (lp.recv()), - Right(()) => Right(rp.recv()) - } - } - } - - fn try_select() -> Either, Option> { - match self { - (ref lp, ref rp) => match select2i(lp, rp) { - Left(()) => Left (lp.try_recv()), - Right(()) => Right(rp.try_recv()) - } - } - } -} - -proto! oneshot ( - Oneshot:send { - send(T) -> ! - } -) - -/// The send end of a oneshot pipe. -pub type ChanOne = oneshot::client::Oneshot; -/// The receive end of a oneshot pipe. -pub type PortOne = oneshot::server::Oneshot; - -/// Initialiase a (send-endpoint, recv-endpoint) oneshot pipe pair. -pub fn oneshot() -> (PortOne, ChanOne) { - let (chan, port) = oneshot::init(); - (port, chan) -} - -impl PortOne { - fn recv(self) -> T { recv_one(self) } - fn try_recv(self) -> Option { try_recv_one(self) } -} - -impl ChanOne { - fn send(self, data: T) { send_one(self, data) } - fn try_send(self, data: T) -> bool { try_send_one(self, data) } -} - -/** - * Receive a message from a oneshot pipe, failing if the connection was - * closed. - */ -pub fn recv_one(port: PortOne) -> T { - let oneshot::send(message) = recv(move port); - move message -} - -/// Receive a message from a oneshot pipe unless the connection was closed. -pub fn try_recv_one (port: PortOne) -> Option { - let message = try_recv(move port); - - if message.is_none() { None } - else { - let oneshot::send(message) = option::unwrap(move message); - Some(move message) - } -} - -/// Send a message on a oneshot pipe, failing if the connection was closed. -pub fn send_one(chan: ChanOne, data: T) { - oneshot::client::send(move chan, move data); -} -/** - * Send a message on a oneshot pipe, or return false if the connection was - * closed. - */ -pub fn try_send_one(chan: ChanOne, data: T) - -> bool { - oneshot::client::try_send(move chan, move data).is_some() + client } pub mod rt { @@ -1301,24 +956,24 @@ pub mod rt { // These are used to hide the option constructors from the // compiler because their names are changing - pub fn make_some(val: T) -> Option { Some(move val) } + pub fn make_some(val: T) -> Option { Some(val) } pub fn make_none() -> Option { None } } #[cfg(test)] pub mod test { use either::{Either, Left, Right}; - use pipes::{Chan, Port, oneshot, recv_one, stream}; - use pipes; + use comm::{Chan, Port, oneshot, recv_one, stream, Select2, + GenericPort, GenericChan, Peekable}; #[test] pub fn test_select2() { - let (p1, c1) = pipes::stream(); - let (p2, c2) = pipes::stream(); + let (p1, c1) = stream(); + let (p2, c2) = stream(); c1.send(~"abc"); - match (move p1, move p2).select() { + match (p1, p2).select() { Right(_) => fail!(), _ => () } @@ -1330,9 +985,9 @@ pub mod test { pub fn test_oneshot() { let (c, p) = oneshot::init(); - oneshot::client::send(move c, ()); + oneshot::client::send(c, ()); - recv_one(move p) + recv_one(p) } #[test] @@ -1341,7 +996,7 @@ pub mod test { { // Destroy the channel - let _chan = move chan; + let _chan = chan; } assert !port.peek(); diff --git a/src/libcore/prelude.rs b/src/libcore/prelude.rs index b50fa265f030d..d0a16f7875b5c 100644 --- a/src/libcore/prelude.rs +++ b/src/libcore/prelude.rs @@ -52,7 +52,6 @@ pub use char; pub use cmp; pub use dvec; pub use either; -pub use extfmt; pub use f32; pub use f64; pub use float; @@ -69,7 +68,7 @@ pub use ops; pub use option; pub use os; pub use path; -pub use pipes; +pub use comm; pub use private; pub use ptr; pub use rand; diff --git a/src/libcore/private.rs b/src/libcore/private.rs index 9df31bbd81f2c..280eb14b172c4 100644 --- a/src/libcore/private.rs +++ b/src/libcore/private.rs @@ -14,7 +14,7 @@ use cast; use iter; use libc; use option; -use pipes::{GenericChan, GenericPort}; +use comm::{GenericChan, GenericPort}; use prelude::*; use ptr; use result; @@ -32,6 +32,10 @@ pub mod finally; pub mod weak_task; #[path = "private/exchange_alloc.rs"] pub mod exchange_alloc; +#[path = "private/intrinsics.rs"] +pub mod intrinsics; +#[path = "private/extfmt.rs"] +pub mod extfmt; extern mod rustrt { pub unsafe fn rust_create_little_lock() -> rust_little_lock; @@ -43,13 +47,6 @@ extern mod rustrt { pub unsafe fn rust_raw_thread_join_delete(thread: *raw_thread); } -#[abi = "rust-intrinsic"] -extern mod rusti { - fn atomic_cxchg(dst: &mut int, old: int, src: int) -> int; - fn atomic_xadd(dst: &mut int, src: int) -> int; - fn atomic_xsub(dst: &mut int, src: int) -> int; -} - #[allow(non_camel_case_types)] // runtime type type raw_thread = libc::c_void; @@ -62,7 +59,7 @@ The executing thread has no access to a task pointer and will be using a normal large stack. */ pub unsafe fn run_in_bare_thread(f: ~fn()) { - let (port, chan) = pipes::stream(); + let (port, chan) = comm::stream(); // FIXME #4525: Unfortunate that this creates an extra scheduler but it's // necessary since rust_raw_thread_join_delete is blocking do task::spawn_sched(task::SingleThreaded) { @@ -101,7 +98,7 @@ fn test_run_in_bare_thread_exchange() { fn compare_and_swap(address: &mut int, oldval: int, newval: int) -> bool { unsafe { - let old = rusti::atomic_cxchg(address, oldval, newval); + let old = intrinsics::atomic_cxchg(address, oldval, newval); old == oldval } } @@ -113,7 +110,7 @@ fn compare_and_swap(address: &mut int, oldval: int, newval: int) -> bool { // An unwrapper uses this protocol to communicate with the "other" task that // drops the last refcount on an arc. Unfortunately this can't be a proper // pipe protocol because the unwrapper has to access both stages at once. -type UnwrapProto = ~mut Option<(pipes::ChanOne<()>, pipes::PortOne)>; +type UnwrapProto = ~mut Option<(comm::ChanOne<()>, comm::PortOne)>; struct ArcData { mut count: libc::intptr_t, @@ -132,7 +129,8 @@ struct ArcDestruct { } do task::unkillable { let data: ~ArcData = cast::reinterpret_cast(&self.data); - let new_count = rusti::atomic_xsub(&mut data.count, 1) - 1; + let new_count = + intrinsics::atomic_xsub(&mut data.count, 1) - 1; assert new_count >= 0; if new_count == 0 { // Were we really last, or should we hand off to an @@ -145,11 +143,11 @@ struct ArcDestruct { cast::reinterpret_cast(&data.unwrapper); let (message, response) = option::swap_unwrap(p); // Send 'ready' and wait for a response. - pipes::send_one(move message, ()); + comm::send_one(message, ()); // Unkillable wait. Message guaranteed to come. - if pipes::recv_one(move response) { + if comm::recv_one(response) { // Other task got the data. - cast::forget(move data); + cast::forget(data); } else { // Other task was killed. drop glue takes over. } @@ -157,7 +155,7 @@ struct ArcDestruct { // drop glue takes over. } } else { - cast::forget(move data); + cast::forget(data); } } } @@ -170,11 +168,11 @@ fn ArcDestruct(data: *libc::c_void) -> ArcDestruct { } } -pub unsafe fn unwrap_shared_mutable_state(rc: SharedMutableState) +pub unsafe fn unwrap_shared_mutable_state(rc: SharedMutableState) -> T { struct DeathThroes { mut ptr: Option<~ArcData>, - mut response: Option>, + mut response: Option>, drop { unsafe { let response = option::swap_unwrap(&mut self.response); @@ -182,13 +180,13 @@ pub unsafe fn unwrap_shared_mutable_state(rc: SharedMutableState) // tried to wake us whether they should hand-off the data to // us. if task::failing() { - pipes::send_one(move response, false); + comm::send_one(response, false); // Either this swap_unwrap or the one below (at "Got // here") ought to run. cast::forget(option::swap_unwrap(&mut self.ptr)); } else { assert self.ptr.is_none(); - pipes::send_one(move response, true); + comm::send_one(response, true); } } } @@ -196,31 +194,31 @@ pub unsafe fn unwrap_shared_mutable_state(rc: SharedMutableState) do task::unkillable { let ptr: ~ArcData = cast::reinterpret_cast(&rc.data); - let (p1,c1) = pipes::oneshot(); // () - let (p2,c2) = pipes::oneshot(); // bool - let server: UnwrapProto = ~mut Some((move c1,move p2)); - let serverp: int = cast::transmute(move server); + let (p1,c1) = comm::oneshot(); // () + let (p2,c2) = comm::oneshot(); // bool + let server: UnwrapProto = ~mut Some((c1,p2)); + let serverp: int = cast::transmute(server); // Try to put our server end in the unwrapper slot. if compare_and_swap(&mut ptr.unwrapper, 0, serverp) { // Got in. Step 0: Tell destructor not to run. We are now it. rc.data = ptr::null(); // Step 1 - drop our own reference. - let new_count = rusti::atomic_xsub(&mut ptr.count, 1) - 1; + let new_count = intrinsics::atomic_xsub(&mut ptr.count, 1) - 1; //assert new_count >= 0; if new_count == 0 { // We were the last owner. Can unwrap immediately. // Also we have to free the server endpoints. - let _server: UnwrapProto = cast::transmute(move serverp); + let _server: UnwrapProto = cast::transmute(serverp); option::swap_unwrap(&mut ptr.data) // drop glue takes over. } else { // The *next* person who sees the refcount hit 0 will wake us. let end_result = - DeathThroes { ptr: Some(move ptr), - response: Some(move c2) }; - let mut p1 = Some(move p1); // argh + DeathThroes { ptr: Some(ptr), + response: Some(c2) }; + let mut p1 = Some(p1); // argh do task::rekillable { - pipes::recv_one(option::swap_unwrap(&mut p1)); + comm::recv_one(option::swap_unwrap(&mut p1)); } // Got here. Back in the 'unkillable' without getting killed. // Recover ownership of ptr, then take the data out. @@ -230,9 +228,9 @@ pub unsafe fn unwrap_shared_mutable_state(rc: SharedMutableState) } } else { // Somebody else was trying to unwrap. Avoid guaranteed deadlock. - cast::forget(move ptr); + cast::forget(ptr); // Also we have to free the (rejected) server endpoints. - let _server: UnwrapProto = cast::transmute(move serverp); + let _server: UnwrapProto = cast::transmute(serverp); fail!(~"Another task is already unwrapping this ARC!"); } } @@ -246,52 +244,52 @@ pub unsafe fn unwrap_shared_mutable_state(rc: SharedMutableState) */ pub type SharedMutableState = ArcDestruct; -pub unsafe fn shared_mutable_state(data: T) -> +pub unsafe fn shared_mutable_state(data: T) -> SharedMutableState { - let data = ~ArcData { count: 1, unwrapper: 0, data: Some(move data) }; + let data = ~ArcData { count: 1, unwrapper: 0, data: Some(data) }; unsafe { - let ptr = cast::transmute(move data); + let ptr = cast::transmute(data); ArcDestruct(ptr) } } #[inline(always)] -pub unsafe fn get_shared_mutable_state( +pub unsafe fn get_shared_mutable_state( rc: *SharedMutableState) -> *mut T { unsafe { let ptr: ~ArcData = cast::reinterpret_cast(&(*rc).data); assert ptr.count > 0; let r = cast::transmute(option::get_ref(&ptr.data)); - cast::forget(move ptr); + cast::forget(ptr); return r; } } #[inline(always)] -pub unsafe fn get_shared_immutable_state( +pub unsafe fn get_shared_immutable_state( rc: &a/SharedMutableState) -> &a/T { unsafe { let ptr: ~ArcData = cast::reinterpret_cast(&(*rc).data); assert ptr.count > 0; // Cast us back into the correct region let r = cast::transmute_region(option::get_ref(&ptr.data)); - cast::forget(move ptr); + cast::forget(ptr); return r; } } -pub unsafe fn clone_shared_mutable_state(rc: &SharedMutableState) +pub unsafe fn clone_shared_mutable_state(rc: &SharedMutableState) -> SharedMutableState { unsafe { let ptr: ~ArcData = cast::reinterpret_cast(&(*rc).data); - let new_count = rusti::atomic_xadd(&mut ptr.count, 1) + 1; + let new_count = intrinsics::atomic_xadd(&mut ptr.count, 1) + 1; assert new_count >= 2; - cast::forget(move ptr); + cast::forget(ptr); } ArcDestruct((*rc).data) } -impl Clone for SharedMutableState { +impl Clone for SharedMutableState { fn clone(&self) -> SharedMutableState { unsafe { clone_shared_mutable_state(self) @@ -353,21 +351,21 @@ struct ExData { lock: LittleLock, mut failed: bool, mut data: T, } */ pub struct Exclusive { x: SharedMutableState> } -pub fn exclusive(user_data: T) -> Exclusive { +pub fn exclusive(user_data: T) -> Exclusive { let data = ExData { - lock: LittleLock(), mut failed: false, mut data: move user_data + lock: LittleLock(), mut failed: false, mut data: user_data }; - Exclusive { x: unsafe { shared_mutable_state(move data) } } + Exclusive { x: unsafe { shared_mutable_state(data) } } } -impl Clone for Exclusive { +impl Clone for Exclusive { // Duplicate an exclusive ARC, as std::arc::clone. fn clone(&self) -> Exclusive { Exclusive { x: unsafe { clone_shared_mutable_state(&self.x) } } } } -impl Exclusive { +impl Exclusive { // Exactly like std::arc::mutex_arc,access(), but with the little_lock // instead of a proper mutex. Same reason for being unsafe. // @@ -386,7 +384,7 @@ impl Exclusive { (*rec).failed = true; let result = f(&mut (*rec).data); (*rec).failed = false; - move result + result } } } @@ -400,11 +398,11 @@ impl Exclusive { } // FIXME(#3724) make this a by-move method on the exclusive -pub fn unwrap_exclusive(arc: Exclusive) -> T { - let Exclusive { x: x } = move arc; - let inner = unsafe { unwrap_shared_mutable_state(move x) }; - let ExData { data: data, _ } = move inner; - move data +pub fn unwrap_exclusive(arc: Exclusive) -> T { + let Exclusive { x: x } = arc; + let inner = unsafe { unwrap_shared_mutable_state(x) }; + let ExData { data: data, _ } = inner; + data } #[cfg(test)] @@ -412,7 +410,7 @@ pub mod tests { use core::option::{None, Some}; use option; - use pipes; + use comm; use private::{exclusive, unwrap_exclusive}; use result; use task; @@ -429,10 +427,10 @@ pub mod tests { for uint::range(0, num_tasks) |_i| { let total = total.clone(); - let (port, chan) = pipes::stream(); - futures.push(move port); + let (port, chan) = comm::stream(); + futures.push(port); - do task::spawn |move total, move chan| { + do task::spawn || { for uint::range(0, count) |_i| { do total.with |count| { **count += 1; @@ -455,7 +453,7 @@ pub mod tests { // accesses will also fail. let x = exclusive(1); let x2 = x.clone(); - do task::try |move x2| { + do task::try || { do x2.with |one| { assert *one == 2; } @@ -468,48 +466,49 @@ pub mod tests { #[test] pub fn exclusive_unwrap_basic() { let x = exclusive(~~"hello"); - assert unwrap_exclusive(move x) == ~~"hello"; + assert unwrap_exclusive(x) == ~~"hello"; } #[test] pub fn exclusive_unwrap_contended() { let x = exclusive(~~"hello"); let x2 = ~mut Some(x.clone()); - do task::spawn |move x2| { + do task::spawn || { let x2 = option::swap_unwrap(x2); do x2.with |_hello| { } task::yield(); } - assert unwrap_exclusive(move x) == ~~"hello"; + assert unwrap_exclusive(x) == ~~"hello"; // Now try the same thing, but with the child task blocking. let x = exclusive(~~"hello"); let x2 = ~mut Some(x.clone()); let mut res = None; - do task::task().future_result(|+r| res = Some(move r)).spawn - |move x2| { + do task::task().future_result(|+r| res = Some(r)).spawn + || { let x2 = option::swap_unwrap(x2); - assert unwrap_exclusive(move x2) == ~~"hello"; + assert unwrap_exclusive(x2) == ~~"hello"; } // Have to get rid of our reference before blocking. - { let _x = move x; } // FIXME(#3161) util::ignore doesn't work here + { let _x = x; } // FIXME(#3161) util::ignore doesn't work here let res = option::swap_unwrap(&mut res); res.recv(); } - #[test] #[should_fail] #[ignore(reason = "random red")] + #[test] #[should_fail] #[ignore(cfg(windows))] pub fn exclusive_unwrap_conflict() { let x = exclusive(~~"hello"); let x2 = ~mut Some(x.clone()); let mut res = None; - do task::task().future_result(|+r| res = Some(move r)).spawn - |move x2| { + do task::task().future_result(|+r| res = Some(r)).spawn + || { let x2 = option::swap_unwrap(x2); - assert unwrap_exclusive(move x2) == ~~"hello"; + assert unwrap_exclusive(x2) == ~~"hello"; } - assert unwrap_exclusive(move x) == ~~"hello"; + assert unwrap_exclusive(x) == ~~"hello"; let res = option::swap_unwrap(&mut res); - res.recv(); + // See #4689 for why this can't be just "res.recv()". + assert res.recv() == task::Success; } #[test] #[ignore(cfg(windows))] @@ -526,7 +525,7 @@ pub mod tests { for 10.times { task::yield(); } // try to let the unwrapper go fail!(); // punt it awake from its deadlock } - let _z = unwrap_exclusive(move x); + let _z = unwrap_exclusive(x); do x2.with |_hello| { } }; assert result.is_err(); diff --git a/src/libcore/private/at_exit.rs b/src/libcore/private/at_exit.rs index d80631a29ee60..4785cb622cbc5 100644 --- a/src/libcore/private/at_exit.rs +++ b/src/libcore/private/at_exit.rs @@ -70,12 +70,6 @@ fn exit_runner(exit_fns: *ExitFunctions) { } } -#[abi = "rust-intrinsic"] -pub extern mod rusti { - fn move_val_init(dst: &mut T, -src: T); - fn init() -> T; -} - #[test] fn test_at_exit() { let i = 10; diff --git a/src/libcore/private/exchange_alloc.rs b/src/libcore/private/exchange_alloc.rs index 4a3c8d59af59b..b6af9891e118b 100644 --- a/src/libcore/private/exchange_alloc.rs +++ b/src/libcore/private/exchange_alloc.rs @@ -14,7 +14,8 @@ use c_malloc = libc::malloc; use c_free = libc::free; use managed::raw::{BoxHeaderRepr, BoxRepr}; use cast::transmute; -use ptr::{set_memory, null}; +use private::intrinsics::{atomic_xadd,atomic_xsub}; +use ptr::null; use intrinsic::TyDesc; pub unsafe fn malloc(td: *TypeDesc, size: uint) -> *c_void { @@ -25,10 +26,6 @@ pub unsafe fn malloc(td: *TypeDesc, size: uint) -> *c_void { let p = c_malloc(total_size as size_t); assert p.is_not_null(); - // FIXME #4761: Would be very nice to not memset all allocations - let p: *mut u8 = transmute(p); - set_memory(p, 0, total_size); - // FIXME #3475: Converting between our two different tydesc types let td: *TyDesc = transmute(td); @@ -39,7 +36,7 @@ pub unsafe fn malloc(td: *TypeDesc, size: uint) -> *c_void { box.header.next = null(); let exchange_count = &mut *rust_get_exchange_count_ptr(); - rusti::atomic_xadd(exchange_count, 1); + atomic_xadd(exchange_count, 1); return transmute(box); } @@ -47,7 +44,7 @@ pub unsafe fn malloc(td: *TypeDesc, size: uint) -> *c_void { pub unsafe fn free(ptr: *c_void) { let exchange_count = &mut *rust_get_exchange_count_ptr(); - rusti::atomic_xsub(exchange_count, 1); + atomic_xsub(exchange_count, 1); assert ptr.is_not_null(); c_free(ptr); @@ -72,8 +69,3 @@ extern { fn rust_get_exchange_count_ptr() -> *mut int; } -#[abi = "rust-intrinsic"] -extern mod rusti { - fn atomic_xadd(dst: &mut int, src: int) -> int; - fn atomic_xsub(dst: &mut int, src: int) -> int; -} diff --git a/src/libcore/extfmt.rs b/src/libcore/private/extfmt.rs similarity index 97% rename from src/libcore/extfmt.rs rename to src/libcore/private/extfmt.rs index 3dbc3bef01733..36ea67ea6954e 100644 --- a/src/libcore/extfmt.rs +++ b/src/libcore/private/extfmt.rs @@ -510,7 +510,7 @@ pub mod rt { unsafe { str::unshift_char(&mut s, ' ') }; } } - return unsafe { pad(cv, move s, PadSigned) }; + return unsafe { pad(cv, s, PadSigned) }; } pub pure fn conv_uint(cv: Conv, u: uint) -> ~str { let prec = get_int_precision(cv); @@ -522,7 +522,7 @@ pub mod rt { TyBits => uint_to_str_prec(u, 2, prec), TyOctal => uint_to_str_prec(u, 8, prec) }; - return unsafe { pad(cv, move rs, PadUnsigned) }; + return unsafe { pad(cv, rs, PadUnsigned) }; } pub pure fn conv_bool(cv: Conv, b: bool) -> ~str { let s = if b { ~"true" } else { ~"false" }; @@ -532,7 +532,7 @@ pub mod rt { } pub pure fn conv_char(cv: Conv, c: char) -> ~str { let mut s = str::from_char(c); - return unsafe { pad(cv, move s, PadNozero) }; + return unsafe { pad(cv, s, PadNozero) }; } pub pure fn conv_str(cv: Conv, s: &str) -> ~str { // For strings, precision is the maximum characters @@ -545,7 +545,7 @@ pub mod rt { s.to_owned() } }; - return unsafe { pad(cv, move unpadded, PadNozero) }; + return unsafe { pad(cv, unpadded, PadNozero) }; } pub pure fn conv_float(cv: Conv, f: float) -> ~str { let (to_str, digits) = match cv.precision { @@ -560,7 +560,7 @@ pub mod rt { s = ~" " + s; } } - return unsafe { pad(cv, move s, PadFloat) }; + return unsafe { pad(cv, s, PadFloat) }; } pub pure fn conv_poly(cv: Conv, v: &T) -> ~str { let s = sys::log_str(v); @@ -589,7 +589,7 @@ pub mod rt { let diff = prec - len; let pad = str::from_chars(vec::from_elem(diff, '0')); pad + s - } else { move s } + } else { s } }; } pub pure fn get_int_precision(cv: Conv) -> uint { @@ -603,13 +603,13 @@ pub mod rt { pub enum PadMode { PadSigned, PadUnsigned, PadNozero, PadFloat } pub fn pad(cv: Conv, s: ~str, mode: PadMode) -> ~str { - let mut s = move s; // sadtimes + let mut s = s; // sadtimes let uwidth : uint = match cv.width { - CountImplied => return (move s), + CountImplied => return (s), CountIs(width) => { width as uint } }; let strlen = str::char_len(s); - if uwidth <= strlen { return (move s); } + if uwidth <= strlen { return (s); } let mut padchar = ' '; let diff = uwidth - strlen; if have_flag(cv.flags, flag_left_justify) { diff --git a/src/libcore/private/global.rs b/src/libcore/private/global.rs index 621ead48abc1a..77b61347250d2 100644 --- a/src/libcore/private/global.rs +++ b/src/libcore/private/global.rs @@ -36,6 +36,7 @@ use private::{Exclusive, exclusive}; use private::{SharedMutableState, shared_mutable_state}; use private::{get_shared_immutable_state}; use private::at_exit::at_exit; +use private::intrinsics::atomic_cxchg; use hashmap::linear::LinearMap; use sys::Closure; use task::spawn; @@ -43,7 +44,7 @@ use uint; pub type GlobalDataKey = &fn(v: T); -pub unsafe fn global_data_clone_create( +pub unsafe fn global_data_clone_create( key: GlobalDataKey, create: &fn() -> ~T) -> T { /*! * Clone a global value or, if it has not been created, @@ -59,7 +60,7 @@ pub unsafe fn global_data_clone_create( global_data_clone_create_(key_ptr(key), create) } -unsafe fn global_data_clone_create_( +unsafe fn global_data_clone_create_( key: uint, create: &fn() -> ~T) -> T { let mut clone_value: Option = None; @@ -79,13 +80,13 @@ unsafe fn global_data_clone_create_( return clone_value.unwrap(); } -unsafe fn global_data_modify( +unsafe fn global_data_modify( key: GlobalDataKey, op: &fn(Option<~T>) -> Option<~T>) { global_data_modify_(key_ptr(key), op) } -unsafe fn global_data_modify_( +unsafe fn global_data_modify_( key: uint, op: &fn(Option<~T>) -> Option<~T>) { let mut old_dtor = None; @@ -124,7 +125,7 @@ unsafe fn global_data_modify_( } } -pub unsafe fn global_data_clone( +pub unsafe fn global_data_clone( key: GlobalDataKey) -> Option { let mut maybe_clone: Option = None; do global_data_modify(key) |current| { @@ -220,7 +221,7 @@ fn get_global_state() -> Exclusive { } } -fn key_ptr(key: GlobalDataKey) -> uint { +fn key_ptr(key: GlobalDataKey) -> uint { unsafe { let closure: Closure = reinterpret_cast(&key); return transmute(closure.code); @@ -231,11 +232,6 @@ extern { fn rust_get_global_data_ptr() -> *mut int; } -#[abi = "rust-intrinsic"] -extern { - fn atomic_cxchg(dst: &mut int, old: int, src: int) -> int; -} - #[test] fn test_clone_rc() { type MyType = SharedMutableState; diff --git a/src/libcore/private/intrinsics.rs b/src/libcore/private/intrinsics.rs new file mode 100644 index 0000000000000..8f0067b739335 --- /dev/null +++ b/src/libcore/private/intrinsics.rs @@ -0,0 +1,131 @@ +// 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. + +/*! +An attempt to move all intrinsic declarations to a single place, +as mentioned in #3369 +The intrinsics are defined in librustc/middle/trans/foreign.rs. +*/ + +#[abi = "rust-intrinsic"] +pub extern { + pub fn atomic_cxchg(dst: &mut int, old: int, src: int) -> int; + pub fn atomic_cxchg_acq(dst: &mut int, old: int, src: int) -> int; + pub fn atomic_cxchg_rel(dst: &mut int, old: int, src: int) -> int; + + pub fn atomic_xchg(dst: &mut int, src: int) -> int; + pub fn atomic_xchg_acq(dst: &mut int, src: int) -> int; + pub fn atomic_xchg_rel(dst: &mut int, src: int) -> int; + + pub fn atomic_xadd(dst: &mut int, src: int) -> int; + pub fn atomic_xadd_acq(dst: &mut int, src: int) -> int; + pub fn atomic_xadd_rel(dst: &mut int, src: int) -> int; + + pub fn atomic_xsub(dst: &mut int, src: int) -> int; + pub fn atomic_xsub_acq(dst: &mut int, src: int) -> int; + pub fn atomic_xsub_rel(dst: &mut int, src: int) -> int; + + pub fn size_of() -> uint; + + pub fn move_val(dst: &mut T, -src: T); + pub fn move_val_init(dst: &mut T, -src: T); + + pub fn min_align_of() -> uint; + pub fn pref_align_of() -> uint; + + pub fn get_tydesc() -> *(); + + pub fn init() -> T; + + pub fn forget(_: T) -> (); + + // XXX: intrinsic uses legacy modes + fn reinterpret_cast(&&src: T) -> U; + // XXX: intrinsic uses legacy modes + fn addr_of(&&scr: T) -> *T; + + pub fn needs_drop() -> bool; + + // XXX: intrinsic uses legacy modes and has reference to TyDesc + // and TyVisitor which are in librustc + //fn visit_tydesc(++td: *TyDesc, &&tv: TyVisitor) -> (); + // XXX: intrinsic uses legacy modes + //fn frame_address(f: &once fn(*u8)); + + pub fn morestack_addr() -> *(); + + pub fn memmove32(dst: *mut u8, src: *u8, size: u32); + pub fn memmove64(dst: *mut u8, src: *u8, size: u64); + + pub fn sqrtf32(x: f32) -> f32; + pub fn sqrtf64(x: f64) -> f64; + + pub fn powif32(a: f32, x: i32) -> f32; + pub fn powif64(a: f64, x: i32) -> f64; + + pub fn sinf32(x: f32) -> f32; + pub fn sinf64(x: f64) -> f64; + + pub fn cosf32(x: f32) -> f32; + pub fn cosf64(x: f64) -> f64; + + pub fn powf32(a: f32, x: f32) -> f32; + pub fn powf64(a: f64, x: f64) -> f64; + + pub fn expf32(x: f32) -> f32; + pub fn expf64(x: f64) -> f64; + + pub fn exp2f32(x: f32) -> f32; + pub fn exp2f64(x: f64) -> f64; + + pub fn logf32(x: f32) -> f32; + pub fn logf64(x: f64) -> f64; + + pub fn log10f32(x: f32) -> f32; + pub fn log10f64(x: f64) -> f64; + + pub fn log2f32(x: f32) -> f32; + pub fn log2f64(x: f64) -> f64; + + pub fn fmaf32(a: f32, b: f32, c: f32) -> f32; + pub fn fmaf64(a: f64, b: f64, c: f64) -> f64; + + pub fn fabsf32(x: f32) -> f32; + pub fn fabsf64(x: f64) -> f64; + + pub fn floorf32(x: f32) -> f32; + pub fn floorf64(x: f64) -> f64; + + pub fn ceilf32(x: f32) -> f32; + pub fn ceilf64(x: f64) -> f64; + + pub fn truncf32(x: f32) -> f32; + pub fn truncf64(x: f64) -> f64; + + pub fn ctpop8(x: i8) -> i8; + pub fn ctpop16(x: i16) -> i16; + pub fn ctpop32(x: i32) -> i32; + pub fn ctpop64(x: i64) -> i64; + + pub fn ctlz8(x: i8) -> i8; + pub fn ctlz16(x: i16) -> i16; + pub fn ctlz32(x: i32) -> i32; + pub fn ctlz64(x: i64) -> i64; + + pub fn cttz8(x: i8) -> i8; + pub fn cttz16(x: i16) -> i16; + pub fn cttz32(x: i32) -> i32; + pub fn cttz64(x: i64) -> i64; + + pub fn bswap16(x: i16) -> i16; + pub fn bswap32(x: i32) -> i32; + pub fn bswap64(x: i64) -> i64; +} + diff --git a/src/libcore/private/weak_task.rs b/src/libcore/private/weak_task.rs index f285f811f15d0..f3df8ce72f146 100644 --- a/src/libcore/private/weak_task.rs +++ b/src/libcore/private/weak_task.rs @@ -22,8 +22,8 @@ use option::{Some, None, swap_unwrap}; use private::at_exit::at_exit; use private::global::global_data_clone_create; use private::finally::Finally; -use pipes::{Port, Chan, SharedChan, GenericChan, GenericPort, - GenericSmartChan, stream}; +use comm::{Port, Chan, SharedChan, GenericChan, + GenericPort, GenericSmartChan, stream}; use task::{Task, task, spawn}; use task::rt::{task_id, get_task_id}; use hashmap::linear::LinearMap; @@ -186,7 +186,7 @@ fn test_wait_for_signal_many() { #[test] fn test_select_stream_and_oneshot() { - use pipes::select2i; + use comm::select2i; use either::{Left, Right}; let (port, chan) = stream(); diff --git a/src/libcore/ptr.rs b/src/libcore/ptr.rs index acadf079b3b67..2266c2511f8f3 100644 --- a/src/libcore/ptr.rs +++ b/src/libcore/ptr.rs @@ -14,6 +14,7 @@ use cast; use cmp::{Eq, Ord}; use libc; use libc::{c_void, size_t}; +use private::intrinsics::{memmove32,memmove64}; use ptr; use str; use sys; @@ -44,14 +45,6 @@ extern mod rusti { #[inline(always)] pub pure fn addr_of(val: &T) -> *T { unsafe { rusti::addr_of(*val) } } -/// Get an unsafe mut pointer to a value -#[inline(always)] -pub pure fn mut_addr_of(val: &T) -> *mut T { - unsafe { - cast::reinterpret_cast(&rusti::addr_of(*val)) - } -} - /// Calculate the offset from a pointer #[inline(always)] pub pure fn offset(ptr: *T, count: uint) -> *T { @@ -187,12 +180,6 @@ pub trait Ptr { pure fn offset(count: uint) -> Self; } -#[abi="rust-intrinsic"] -pub extern { - fn memmove32(dst: *mut u8, src: *u8, size: u32); - fn memmove64(dst: *mut u8, src: *u8, size: u64); -} - /// Extension methods for immutable pointers impl Ptr for *T { /// Returns true if the pointer is equal to the null pointer. @@ -313,8 +300,8 @@ impl Ord for &const T { pub fn test() { unsafe { struct Pair {mut fst: int, mut snd: int}; - let p = Pair {mut fst: 10, mut snd: 20}; - let pptr: *mut Pair = mut_addr_of(&p); + let mut p = Pair {mut fst: 10, mut snd: 20}; + let pptr: *mut Pair = &mut p; let iptr: *mut int = cast::reinterpret_cast(&pptr); assert (*iptr == 10);; *iptr = 30; diff --git a/src/libcore/rand.rs b/src/libcore/rand.rs index 47a0e11941cb0..a88b83465161d 100644 --- a/src/libcore/rand.rs +++ b/src/libcore/rand.rs @@ -18,6 +18,7 @@ use u32; use uint; use util; use vec; +use libc::size_t; /// A type that can be randomly generated using an RNG pub trait Rand { @@ -108,7 +109,7 @@ impl Rand for bool { } } -impl Rand for Option { +impl Rand for Option { static fn rand(rng: rand::Rng) -> Option { if rng.gen_bool() { Some(Rand::rand(rng)) } else { None } @@ -116,15 +117,15 @@ impl Rand for Option { } #[allow(non_camel_case_types)] // runtime type -enum rctx {} +enum rust_rng {} #[abi = "cdecl"] extern mod rustrt { - unsafe fn rand_seed() -> ~[u8]; - unsafe fn rand_new() -> *rctx; - unsafe fn rand_new_seeded2(&&seed: ~[u8]) -> *rctx; - unsafe fn rand_next(c: *rctx) -> u32; - unsafe fn rand_free(c: *rctx); + unsafe fn rand_seed_size() -> size_t; + unsafe fn rand_gen_seed(buf: *mut u8, sz: size_t); + unsafe fn rand_new_seeded(buf: *u8, sz: size_t) -> *rust_rng; + unsafe fn rand_next(rng: *rust_rng) -> u32; + unsafe fn rand_free(rng: *rust_rng); } /// A random number generator @@ -142,7 +143,7 @@ pub struct Weighted { /// Extension methods for random number generators impl Rng { /// Return a random value for a Rand type - fn gen() -> T { + fn gen() -> T { Rand::rand(self) } @@ -273,7 +274,7 @@ impl Rng { s = s + str::from_char(self.gen_char_from(charset)); i += 1u; } - move s + s } /// Return a random byte string of the specified length @@ -301,7 +302,7 @@ impl Rng { * Choose an item respecting the relative weights, failing if the sum of * the weights is 0 */ - fn choose_weighted(v : &[Weighted]) -> T { + fn choose_weighted(v : &[Weighted]) -> T { self.choose_weighted_option(v).get() } @@ -339,14 +340,14 @@ impl Rng { r.push(item.item); } } - move r + r } /// Shuffle a vec fn shuffle(values: &[T]) -> ~[T] { let mut m = vec::from_slice(values); self.shuffle_mut(m); - move m + m } /// Shuffle a mutable vec in place @@ -363,24 +364,24 @@ impl Rng { } struct RandRes { - c: *rctx, + rng: *rust_rng, drop { unsafe { - rustrt::rand_free(self.c); + rustrt::rand_free(self.rng); } } } -fn RandRes(c: *rctx) -> RandRes { +fn RandRes(rng: *rust_rng) -> RandRes { RandRes { - c: c + rng: rng } } impl Rng for @RandRes { fn next() -> u32 { unsafe { - return rustrt::rand_next((*self).c); + return rustrt::rand_next((*self).rng); } } } @@ -388,15 +389,18 @@ impl Rng for @RandRes { /// Create a new random seed for seeded_rng pub fn seed() -> ~[u8] { unsafe { - rustrt::rand_seed() + let n = rustrt::rand_seed_size() as uint; + let mut s = vec::from_elem(n, 0_u8); + do vec::as_mut_buf(s) |p, sz| { + rustrt::rand_gen_seed(p, sz as size_t) + } + s } } /// Create a random number generator with a system specified seed pub fn Rng() -> Rng { - unsafe { - @RandRes(rustrt::rand_new()) as Rng - } + seeded_rng(seed()) } /** @@ -405,9 +409,15 @@ pub fn Rng() -> Rng { * all other generators constructed with the same seed. The seed may be any * length. */ -pub fn seeded_rng(seed: &~[u8]) -> Rng { +pub fn seeded_rng(seed: &[u8]) -> Rng { + seeded_randres(seed) as Rng +} + +fn seeded_randres(seed: &[u8]) -> @RandRes { unsafe { - @RandRes(rustrt::rand_new_seeded2(*seed)) as Rng + do vec::as_imm_buf(seed) |p, sz| { + @RandRes(rustrt::rand_new_seeded(p, sz as size_t)) + } } } @@ -457,7 +467,7 @@ pub fn task_rng() -> Rng { match r { None => { unsafe { - let rng = @RandRes(rustrt::rand_new()); + let rng = seeded_randres(seed()); task::local_data::local_data_set(tls_rng_state, rng); rng as Rng } @@ -483,24 +493,24 @@ pub mod tests { #[test] pub fn rng_seeded() { let seed = rand::seed(); - let ra = rand::seeded_rng(&seed); - let rb = rand::seeded_rng(&seed); + let ra = rand::seeded_rng(seed); + let rb = rand::seeded_rng(seed); assert ra.gen_str(100u) == rb.gen_str(100u); } #[test] pub fn rng_seeded_custom_seed() { // much shorter than generated seeds which are 1024 bytes - let seed = ~[2u8, 32u8, 4u8, 32u8, 51u8]; - let ra = rand::seeded_rng(&seed); - let rb = rand::seeded_rng(&seed); + let seed = [2u8, 32u8, 4u8, 32u8, 51u8]; + let ra = rand::seeded_rng(seed); + let rb = rand::seeded_rng(seed); assert ra.gen_str(100u) == rb.gen_str(100u); } #[test] pub fn rng_seeded_custom_seed2() { - let seed = ~[2u8, 32u8, 4u8, 32u8, 51u8]; - let ra = rand::seeded_rng(&seed); + let seed = [2u8, 32u8, 4u8, 32u8, 51u8]; + let ra = rand::seeded_rng(seed); // Regression test that isaac is actually using the above vector let r = ra.next(); error!("%?", r); diff --git a/src/libcore/reflect.rs b/src/libcore/reflect.rs index eb407cf1128e9..ed7e485678e10 100644 --- a/src/libcore/reflect.rs +++ b/src/libcore/reflect.rs @@ -41,11 +41,11 @@ pub fn align(size: uint, align: uint) -> uint { pub struct MovePtrAdaptor { inner: V } -pub fn MovePtrAdaptor(v: V) -> MovePtrAdaptor { - MovePtrAdaptor { inner: move v } +pub fn MovePtrAdaptor(v: V) -> MovePtrAdaptor { + MovePtrAdaptor { inner: v } } -impl MovePtrAdaptor { +impl MovePtrAdaptor { #[inline(always)] fn bump(sz: uint) { do self.inner.move_ptr() |p| { @@ -72,7 +72,7 @@ impl MovePtrAdaptor { } /// Abstract type-directed pointer-movement using the MovePtr trait -impl TyVisitor for MovePtrAdaptor { +impl TyVisitor for MovePtrAdaptor { fn visit_bot(&self) -> bool { self.align_to::<()>(); if ! self.inner.visit_bot() { return false; } diff --git a/src/libcore/repr.rs b/src/libcore/repr.rs index c2266f4fdb042..7f1687b08608a 100644 --- a/src/libcore/repr.rs +++ b/src/libcore/repr.rs @@ -200,8 +200,8 @@ impl ReprVisitor { fn visit_ptr_inner(ptr: *c_void, inner: *TyDesc) -> bool { unsafe { let mut u = ReprVisitor(ptr, self.writer); - let v = reflect::MovePtrAdaptor(move u); - visit_tydesc(inner, (move v) as @TyVisitor); + let v = reflect::MovePtrAdaptor(u); + visit_tydesc(inner, (v) as @TyVisitor); true } } @@ -569,8 +569,8 @@ pub fn write_repr(writer: @Writer, object: &T) { let ptr = ptr::to_unsafe_ptr(object) as *c_void; let tydesc = intrinsic::get_tydesc::(); let mut u = ReprVisitor(ptr, writer); - let v = reflect::MovePtrAdaptor(move u); - visit_tydesc(tydesc, (move v) as @TyVisitor) + let v = reflect::MovePtrAdaptor(u); + visit_tydesc(tydesc, (v) as @TyVisitor) } } diff --git a/src/libcore/result.rs b/src/libcore/result.rs index fb824087f2199..b03eaeab3e0cc 100644 --- a/src/libcore/result.rs +++ b/src/libcore/result.rs @@ -37,7 +37,7 @@ pub enum Result { * If the result is an error */ #[inline(always)] -pub pure fn get(res: &Result) -> T { +pub pure fn get(res: &Result) -> T { match *res { Ok(copy t) => t, Err(ref the_err) => unsafe { @@ -100,7 +100,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 pure fn to_either(res: &Result) -> Either { match *res { Ok(copy res) => either::Right(res), @@ -125,9 +125,9 @@ pub pure fn to_either(res: &Result) #[inline(always)] pub pure fn chain(res: Result, op: fn(T) -> Result) -> Result { - match move res { - Ok(move t) => op(move t), - Err(move e) => Err(move e) + match res { + Ok(t) => op(t), + Err(e) => Err(e) } } @@ -144,9 +144,9 @@ pub pure fn chain_err( res: Result, op: fn(t: V) -> Result) -> Result { - match move res { - Ok(move t) => Ok(move t), - Err(move v) => op(move v) + match res { + Ok(t) => Ok(t), + Err(v) => op(v) } } @@ -220,7 +220,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 pure fn map_err(res: &Result, op: fn(&E) -> F) -> Result { match *res { Ok(copy t) => Ok(t), @@ -261,7 +261,7 @@ impl Result { } } -impl Result { +impl Result { #[inline(always)] pure fn get(&self) -> T { get(self) } @@ -309,7 +309,7 @@ pub fn map_vec( Err(copy u) => return Err(u) } } - return Ok(move vs); + return Ok(vs); } #[inline(always)] @@ -349,7 +349,7 @@ pub fn map_vec2(ss: &[S], ts: &[T], } i += 1u; } - return Ok(move vs); + return Ok(vs); } /** @@ -377,8 +377,8 @@ 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 { - match move res { - Ok(move t) => move t, + match res { + Ok(t) => t, Err(_) => fail!(~"unwrap called on an err result") } } @@ -386,8 +386,8 @@ 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 { - match move res { - Err(move u) => move u, + match res { + Err(u) => u, Ok(_) => fail!(~"unwrap called on an ok result") } } diff --git a/src/libcore/rt.rs b/src/libcore/rt.rs index 769c0b3c70703..60e6118057d6a 100644 --- a/src/libcore/rt.rs +++ b/src/libcore/rt.rs @@ -62,7 +62,7 @@ pub unsafe fn rt_fail_borrowed() { } } -// XXX: Make these signatures agree with exchange_alloc's signatures +// FIXME #4942: Make these signatures agree with exchange_alloc's signatures #[rt(exchange_malloc)] #[lang="exchange_malloc"] pub unsafe fn rt_exchange_malloc(td: *c_char, size: uintptr_t) -> *c_char { diff --git a/src/libcore/run.rs b/src/libcore/run.rs index 1761d7658386f..4e2337b833133 100644 --- a/src/libcore/run.rs +++ b/src/libcore/run.rs @@ -14,7 +14,7 @@ use io; use io::ReaderUtil; use libc; use libc::{pid_t, c_void, c_int}; -use pipes::{stream, SharedChan, GenericChan, GenericPort}; +use comm::{stream, SharedChan, GenericChan, GenericPort}; use option::{Some, None}; use os; use prelude::*; @@ -250,7 +250,7 @@ pub fn start_program(prog: &str, args: &[~str]) -> Program { r: ProgRepr, drop { unsafe { - // XXX: This is bad. + // FIXME #4943: This is bad. destroy_repr(cast::transmute(&self.r)); } } @@ -258,7 +258,7 @@ pub fn start_program(prog: &str, args: &[~str]) -> Program { fn ProgRes(r: ProgRepr) -> ProgRes { ProgRes { - r: move r + r: r } } @@ -344,11 +344,11 @@ pub fn program_output(prog: &str, args: &[~str]) -> ProgramOutput { let ch_clone = ch.clone(); do task::spawn_sched(task::SingleThreaded) { let errput = readclose(pipe_err.in); - ch.send((2, move errput)); + ch.send((2, errput)); }; do task::spawn_sched(task::SingleThreaded) { let output = readclose(pipe_out.in); - ch_clone.send((1, move output)); + ch_clone.send((1, output)); }; let status = run::waitpid(pid); let mut errs = ~""; @@ -358,10 +358,10 @@ pub fn program_output(prog: &str, args: &[~str]) -> ProgramOutput { let stream = p.recv(); match stream { (1, copy s) => { - outs = move s; + outs = s; } (2, copy s) => { - errs = move s; + errs = s; } (n, _) => { fail!(fmt!("program_output received an unexpected file \ @@ -371,8 +371,8 @@ pub fn program_output(prog: &str, args: &[~str]) -> ProgramOutput { count -= 1; }; return ProgramOutput {status: status, - out: move outs, - err: move errs}; + out: outs, + err: errs}; } } diff --git a/src/libcore/str.rs b/src/libcore/str.rs index 7e7a34f1bab0c..3c15a89081d7f 100644 --- a/src/libcore/str.rs +++ b/src/libcore/str.rs @@ -2110,7 +2110,7 @@ pub mod raw { let v: **vec::raw::VecRepr = cast::transmute(v); let repr: *vec::raw::VecRepr = *v; (*repr).unboxed.fill = new_len + 1u; - let null = ptr::mut_offset(ptr::mut_addr_of(&((*repr).unboxed.data)), + let null = ptr::mut_offset(cast::transmute(&((*repr).unboxed.data)), new_len); *null = 0u8; } @@ -2328,7 +2328,7 @@ pub trait OwnedStr { fn push_char(&mut self, c: char); } -pub impl ~str : OwnedStr { +pub impl OwnedStr for ~str { fn push_str(&mut self, v: &str) { push_str(self, v); } diff --git a/src/libcore/sys.rs b/src/libcore/sys.rs index 1571e64511784..afc9d7f1417e4 100644 --- a/src/libcore/sys.rs +++ b/src/libcore/sys.rs @@ -216,7 +216,7 @@ pub mod tests { assert f(20) == 30; - let original_closure: Closure = cast::transmute(move f); + let original_closure: Closure = cast::transmute(f); let actual_function_pointer = original_closure.code; let environment = original_closure.env; @@ -226,7 +226,7 @@ pub mod tests { env: environment }; - let new_f: fn(int) -> int = cast::transmute(move new_closure); + let new_f: fn(int) -> int = cast::transmute(new_closure); assert new_f(20) == 30; } } diff --git a/src/libcore/task/local_data.rs b/src/libcore/task/local_data.rs index fe37a2e155f0b..ae101faaf0264 100644 --- a/src/libcore/task/local_data.rs +++ b/src/libcore/task/local_data.rs @@ -51,7 +51,7 @@ pub type LocalDataKey = &fn(v: @T); * Remove a task-local data value from the table, returning the * reference that was originally created to insert it. */ -pub unsafe fn local_data_pop( +pub unsafe fn local_data_pop( key: LocalDataKey) -> Option<@T> { local_pop(rt::rust_get_task(), key) @@ -60,7 +60,7 @@ pub unsafe fn local_data_pop( * Retrieve a task-local data value. It will also be kept alive in the * table until explicitly removed. */ -pub unsafe fn local_data_get( +pub unsafe fn local_data_get( key: LocalDataKey) -> Option<@T> { local_get(rt::rust_get_task(), key) @@ -69,7 +69,7 @@ pub unsafe fn local_data_get( * Store a value in task-local data. If this key already has a value, * that value is overwritten (and its destructor is run). */ -pub unsafe fn local_data_set( +pub unsafe fn local_data_set( key: LocalDataKey, data: @T) { local_set(rt::rust_get_task(), key, data) @@ -78,7 +78,7 @@ pub unsafe fn local_data_set( * Modify a task-local data value. If the function returns 'None', the * data is removed (and its reference dropped). */ -pub unsafe fn local_data_modify( +pub unsafe fn local_data_modify( key: LocalDataKey, modify_fn: fn(Option<@T>) -> Option<@T>) { diff --git a/src/libcore/task/local_data_priv.rs b/src/libcore/task/local_data_priv.rs index 35bbc0347ee11..3ac457b23d16e 100644 --- a/src/libcore/task/local_data_priv.rs +++ b/src/libcore/task/local_data_priv.rs @@ -26,7 +26,7 @@ use rt::rust_task; type rust_task = libc::c_void; pub trait LocalData { } -impl LocalData for @T { } +impl LocalData for @T { } impl Eq for LocalData { pure fn eq(&self, other: &@LocalData) -> bool { @@ -73,13 +73,13 @@ unsafe fn get_task_local_map(task: *rust_task) -> TaskLocalMap { cast::bump_box_refcount(map); map } else { - let map = cast::transmute(move map_ptr); + let map = cast::transmute(map_ptr); cast::bump_box_refcount(map); map } } -unsafe fn key_to_key_value( +unsafe fn key_to_key_value( key: LocalDataKey) -> *libc::c_void { // Keys are closures, which are (fnptr,envptr) pairs. Use fnptr. @@ -89,7 +89,7 @@ unsafe fn key_to_key_value( } // If returning Some(..), returns with @T with the map's reference. Careful! -unsafe fn local_data_lookup( +unsafe fn local_data_lookup( map: TaskLocalMap, key: LocalDataKey) -> Option<(uint, *libc::c_void)> { @@ -107,7 +107,7 @@ unsafe fn local_data_lookup( } } -unsafe fn local_get_helper( +unsafe fn local_get_helper( task: *rust_task, key: LocalDataKey, do_pop: bool) -> Option<@T> { @@ -119,7 +119,7 @@ unsafe fn local_get_helper( // overwriting the local_data_box we need to give an extra reference. // We must also give an extra reference when not removing. let (index, data_ptr) = *result; - let data: @T = cast::transmute(move data_ptr); + let data: @T = cast::transmute(data_ptr); cast::bump_box_refcount(data); if do_pop { (*map).set_elt(index, None); @@ -129,21 +129,21 @@ unsafe fn local_get_helper( } -pub unsafe fn local_pop( +pub unsafe fn local_pop( task: *rust_task, key: LocalDataKey) -> Option<@T> { local_get_helper(task, key, true) } -pub unsafe fn local_get( +pub unsafe fn local_get( task: *rust_task, key: LocalDataKey) -> Option<@T> { local_get_helper(task, key, false) } -pub unsafe fn local_set( +pub unsafe fn local_set( task: *rust_task, key: LocalDataKey, data: @T) { let map = get_task_local_map(task); @@ -175,13 +175,13 @@ pub unsafe fn local_set( } } -pub unsafe fn local_modify( +pub unsafe fn local_modify( task: *rust_task, key: LocalDataKey, modify_fn: fn(Option<@T>) -> Option<@T>) { // Could be more efficient by doing the lookup work, but this is easy. let newdata = modify_fn(local_pop(task, key)); if newdata.is_some() { - local_set(task, key, option::unwrap(move newdata)); + local_set(task, key, option::unwrap(newdata)); } } diff --git a/src/libcore/task/mod.rs b/src/libcore/task/mod.rs index 09c558e3be599..336e686193b91 100644 --- a/src/libcore/task/mod.rs +++ b/src/libcore/task/mod.rs @@ -40,7 +40,7 @@ use iter; use libc; use option; use result::Result; -use pipes::{stream, Chan, GenericChan, GenericPort, Port, SharedChan}; +use comm::{stream, Chan, GenericChan, GenericPort, Port, SharedChan}; use pipes; use prelude::*; use ptr; @@ -203,7 +203,7 @@ pub struct TaskBuilder { pub fn task() -> TaskBuilder { TaskBuilder { opts: default_task_opts(), - gen_body: |body| move body, // Identity function + gen_body: |body| body, // Identity function can_not_copy: None, mut consumed: false, } @@ -315,7 +315,7 @@ impl TaskBuilder { // Construct the future and give it to the caller. let (notify_pipe_po, notify_pipe_ch) = stream::(); - blk(move notify_pipe_po); + blk(notify_pipe_po); // Reconfigure self to use a notify channel. TaskBuilder { @@ -336,7 +336,7 @@ impl TaskBuilder { opts: TaskOpts { linked: self.opts.linked, supervised: self.opts.supervised, - notify_chan: move notify_chan, + notify_chan: notify_chan, sched: SchedOpts { mode: mode, foreign_stack_size: None} }, can_not_copy: None, @@ -366,11 +366,7 @@ impl TaskBuilder { notify_chan: notify_chan, sched: self.opts.sched }, - // tjc: I think this is the line that gets miscompiled - // w/ last-use off, if we leave out the move prev_gen_body? - // that makes no sense, though... - gen_body: |move prev_gen_body, - body| { wrapper(prev_gen_body(move body)) }, + gen_body: |body| { wrapper(prev_gen_body(body)) }, can_not_copy: None, .. self.consume() } @@ -397,12 +393,12 @@ impl TaskBuilder { notify_chan: notify_chan, sched: x.opts.sched }; - spawn::spawn_raw(move opts, (x.gen_body)(move f)); + spawn::spawn_raw(opts, (x.gen_body)(f)); } /// Runs a task, while transfering ownership of one argument to the child. - fn spawn_with(arg: A, f: fn~(v: A)) { - let arg = ~mut Some(move arg); - do self.spawn |move arg, move f| { + fn spawn_with(arg: A, f: fn~(v: A)) { + let arg = ~mut Some(arg); + do self.spawn || { f(option::swap_unwrap(arg)) } } @@ -420,17 +416,17 @@ impl TaskBuilder { * # Failure * Fails if a future_result was already set for this task. */ - fn try(f: fn~() -> T) -> Result { + fn try(f: fn~() -> T) -> Result { let (po, ch) = stream::(); let mut result = None; let fr_task_builder = self.future_result(|+r| { - result = Some(move r); + result = Some(r); }); - do fr_task_builder.spawn |move f, move ch| { + do fr_task_builder.spawn || { ch.send(f()); } - match option::unwrap(move result).recv() { + match option::unwrap(result).recv() { Success => result::Ok(po.recv()), Failure => result::Err(()) } @@ -471,7 +467,7 @@ pub fn spawn(f: fn~()) { * This function is equivalent to `task().spawn(f)`. */ - task().spawn(move f) + task().spawn(f) } pub fn spawn_unlinked(f: fn~()) { @@ -480,7 +476,7 @@ pub fn spawn_unlinked(f: fn~()) { * task or the child task fails, the other will not be killed. */ - task().unlinked().spawn(move f) + task().unlinked().spawn(f) } pub fn spawn_supervised(f: fn~()) { @@ -489,7 +485,7 @@ pub fn spawn_supervised(f: fn~()) { * task or the child task fails, the other will not be killed. */ - task().supervised().spawn(move f) + task().supervised().spawn(f) } pub fn spawn_with(arg: A, f: fn~(v: A)) { @@ -503,7 +499,7 @@ pub fn spawn_with(arg: A, f: fn~(v: A)) { * This function is equivalent to `task().spawn_with(arg, f)`. */ - task().spawn_with(move arg, move f) + task().spawn_with(arg, f) } pub fn spawn_sched(mode: SchedMode, f: fn~()) { @@ -519,7 +515,7 @@ pub fn spawn_sched(mode: SchedMode, f: fn~()) { * greater than zero. */ - task().sched_mode(mode).spawn(move f) + task().sched_mode(mode).spawn(f) } pub fn try(f: fn~() -> T) -> Result { @@ -530,7 +526,7 @@ pub fn try(f: fn~() -> T) -> Result { * This is equivalent to task().supervised().try. */ - task().supervised().try(move f) + task().supervised().try(f) } @@ -719,12 +715,12 @@ fn test_spawn_linked_sup_fail_up() { // child fails; parent fails let mut opts = default_task_opts(); opts.linked = true; opts.supervised = true; - move opts + opts }; let b0 = task(); let b1 = TaskBuilder { - opts: move opts, + opts: opts, can_not_copy: None, .. b0 }; @@ -739,12 +735,12 @@ fn test_spawn_linked_sup_fail_down() { // parent fails; child fails let mut opts = default_task_opts(); opts.linked = true; opts.supervised = true; - move opts + opts }; let b0 = task(); let b1 = TaskBuilder { - opts: move opts, + opts: opts, can_not_copy: None, .. b0 }; @@ -843,7 +839,7 @@ fn test_add_wrapper() { let ch = Wrapper { f: Some(ch) }; let b1 = do b0.add_wrapper |body| { let ch = Wrapper { f: Some(ch.f.swap_unwrap()) }; - fn~(move body) { + fn~() { let ch = ch.f.swap_unwrap(); body(); ch.send(()); @@ -857,15 +853,15 @@ fn test_add_wrapper() { #[ignore(cfg(windows))] fn test_future_result() { let mut result = None; - do task().future_result(|+r| { result = Some(move r); }).spawn { } - assert option::unwrap(move result).recv() == Success; + do task().future_result(|+r| { result = Some(r); }).spawn { } + assert option::unwrap(result).recv() == Success; result = None; do task().future_result(|+r| - { result = Some(move r); }).unlinked().spawn { + { result = Some(r); }).unlinked().spawn { fail!(); } - assert option::unwrap(move result).recv() == Failure; + assert option::unwrap(result).recv() == Failure; } #[test] #[should_fail] #[ignore(cfg(windows))] @@ -1024,7 +1020,7 @@ fn avoid_copying_the_body(spawnfn: fn(v: fn~())) { let x = ~1; let x_in_parent = ptr::addr_of(&(*x)) as uint; - do spawnfn |move x| { + do spawnfn || { let x_in_child = ptr::addr_of(&(*x)) as uint; ch.send(x_in_child); } @@ -1041,7 +1037,7 @@ fn test_avoid_copying_the_body_spawn() { #[test] fn test_avoid_copying_the_body_task_spawn() { do avoid_copying_the_body |f| { - do task().spawn |move f| { + do task().spawn || { f(); } } @@ -1050,7 +1046,7 @@ fn test_avoid_copying_the_body_task_spawn() { #[test] fn test_avoid_copying_the_body_try() { do avoid_copying_the_body |f| { - do try |move f| { + do try || { f() }; } @@ -1059,7 +1055,7 @@ fn test_avoid_copying_the_body_try() { #[test] fn test_avoid_copying_the_body_unlinked() { do avoid_copying_the_body |f| { - do spawn_unlinked |move f| { + do spawn_unlinked || { f(); } } @@ -1096,12 +1092,12 @@ fn test_unkillable() { unsafe { do unkillable { let p = ~0; - let pp: *uint = cast::transmute(move p); + let pp: *uint = cast::transmute(p); // If we are killed here then the box will leak po.recv(); - let _p: ~int = cast::transmute(move pp); + let _p: ~int = cast::transmute(pp); } } @@ -1113,10 +1109,10 @@ fn test_unkillable() { #[ignore(cfg(windows))] #[should_fail] fn test_unkillable_nested() { - let (po, ch) = pipes::stream(); + let (po, ch) = comm::stream(); // We want to do this after failing - do spawn_unlinked |move ch| { + do spawn_unlinked || { for iter::repeat(10) { yield() } ch.send(()); } @@ -1132,12 +1128,12 @@ fn test_unkillable_nested() { do unkillable { do unkillable {} // Here's the difference from the previous test. let p = ~0; - let pp: *uint = cast::transmute(move p); + let pp: *uint = cast::transmute(p); // If we are killed here then the box will leak po.recv(); - let _p: ~int = cast::transmute(move pp); + let _p: ~int = cast::transmute(pp); } } @@ -1179,9 +1175,9 @@ fn test_child_doesnt_ref_parent() { #[test] fn test_sched_thread_per_core() { - let (port, chan) = pipes::stream(); + let (port, chan) = comm::stream(); - do spawn_sched(ThreadPerCore) |move chan| { + do spawn_sched(ThreadPerCore) || { unsafe { let cores = rt::rust_num_threads(); let reported_threads = rt::rust_sched_threads(); @@ -1195,18 +1191,18 @@ fn test_sched_thread_per_core() { #[test] fn test_spawn_thread_on_demand() { - let (port, chan) = pipes::stream(); + let (port, chan) = comm::stream(); - do spawn_sched(ManualThreads(2)) |move chan| { + do spawn_sched(ManualThreads(2)) || { unsafe { let max_threads = rt::rust_sched_threads(); assert(max_threads as int == 2); let running_threads = rt::rust_sched_current_nonlazy_threads(); assert(running_threads as int == 1); - let (port2, chan2) = pipes::stream(); + let (port2, chan2) = comm::stream(); - do spawn_sched(CurrentScheduler) |move chan2| { + do spawn_sched(CurrentScheduler) || { chan2.send(()); } diff --git a/src/libcore/task/spawn.rs b/src/libcore/task/spawn.rs index a57e8a8ee44b7..e77af820079b6 100644 --- a/src/libcore/task/spawn.rs +++ b/src/libcore/task/spawn.rs @@ -75,7 +75,7 @@ use cast; use container::Map; use option; -use pipes::{Chan, GenericChan, GenericPort, Port, stream}; +use comm::{Chan, GenericChan, GenericPort, Port, stream}; use pipes; use prelude::*; use private; @@ -93,7 +93,7 @@ use uint; use util; macro_rules! move_it ( - { $x:expr } => ( unsafe { let y = move *ptr::addr_of(&($x)); move y } ) + { $x:expr } => ( unsafe { let y = *ptr::addr_of(&($x)); y } ) ) type TaskSet = LinearSet<*rust_task>; @@ -195,10 +195,10 @@ fn each_ancestor(list: &mut AncestorList, if coalesce_this.is_some() { // Needed coalesce. Our next ancestor becomes our old // ancestor's next ancestor. ("next = old_next->next;") - *list = move option::unwrap(move coalesce_this); + *list = option::unwrap(coalesce_this); } else { // No coalesce; restore from tmp. ("next = old_next;") - *list = move tmp_list; + *list = tmp_list; } return early_break; } @@ -279,7 +279,7 @@ fn each_ancestor(list: &mut AncestorList, // Swap the list out here; the caller replaces us with it. let rest = util::replace(&mut nobe.ancestors, AncestorList(None)); - (Some(move rest), need_unwind) + (Some(rest), need_unwind) } else { (None, need_unwind) } @@ -292,8 +292,8 @@ fn each_ancestor(list: &mut AncestorList, // If this trips, more likely the problem is 'blk' failed inside. let tmp_arc = option::swap_unwrap(&mut *parent_group); let result = do access_group(&tmp_arc) |tg_opt| { blk(tg_opt) }; - *parent_group = move Some(move tmp_arc); - move result + *parent_group = Some(tmp_arc); + result } } } @@ -337,15 +337,15 @@ struct TCB { fn TCB(me: *rust_task, tasks: TaskGroupArc, ancestors: AncestorList, is_main: bool, notifier: Option) -> TCB { - let notifier = move notifier; + let notifier = notifier; notifier.iter(|x| { x.failed = false; }); TCB { me: me, - tasks: move tasks, - ancestors: move ancestors, + tasks: tasks, + ancestors: ancestors, is_main: is_main, - notifier: move notifier + notifier: notifier } } @@ -360,7 +360,7 @@ struct AutoNotify { fn AutoNotify(chan: Chan) -> AutoNotify { AutoNotify { - notify_chan: move chan, + notify_chan: chan, failed: true // Un-set above when taskgroup successfully made. } } @@ -370,10 +370,10 @@ fn enlist_in_taskgroup(state: TaskGroupInner, me: *rust_task, let newstate = util::replace(&mut *state, None); // If 'None', the group was failing. Can't enlist. if newstate.is_some() { - let group = option::unwrap(move newstate); + let group = option::unwrap(newstate); taskset_insert(if is_member { &mut group.members } else { &mut group.descendants }, me); - *state = Some(move group); + *state = Some(group); true } else { false @@ -386,10 +386,10 @@ fn leave_taskgroup(state: TaskGroupInner, me: *rust_task, let newstate = util::replace(&mut *state, None); // If 'None', already failing and we've already gotten a kill signal. if newstate.is_some() { - let group = option::unwrap(move newstate); + let group = option::unwrap(newstate); taskset_remove(if is_member { &mut group.members } else { &mut group.descendants }, me); - *state = Some(move group); + *state = Some(group); } } @@ -410,7 +410,7 @@ fn kill_taskgroup(state: TaskGroupInner, me: *rust_task, is_main: bool) { // That's ok; only one task needs to do the dirty work. (Might also // see 'None' if Somebody already failed and we got a kill signal.) if newstate.is_some() { - let group = option::unwrap(move newstate); + let group = option::unwrap(newstate); for taskset_each(&group.members) |sibling| { // Skip self - killing ourself won't do much good. if sibling != me { @@ -457,7 +457,7 @@ fn gen_child_taskgroup(linked: bool, supervised: bool) })); // Main task/group has no ancestors, no notifier, etc. let group = - @TCB(spawner, move tasks, AncestorList(None), true, None); + @TCB(spawner, tasks, AncestorList(None), true, None); local_set(spawner, taskgroup_key!(), group); group } @@ -472,7 +472,7 @@ fn gen_child_taskgroup(linked: bool, supervised: bool) // Child's ancestors are spawner's ancestors. let a = share_ancestors(&mut spawner_group.ancestors); // Propagate main-ness. - (move g, move a, spawner_group.is_main) + (g, a, spawner_group.is_main) } else { // Child is in a separate group from spawner. let g = private::exclusive(Some(TaskGroupData { @@ -504,7 +504,7 @@ fn gen_child_taskgroup(linked: bool, supervised: bool) // Child has no ancestors. AncestorList(None) }; - (move g, move a, false) + (g, a, false) }; } @@ -515,10 +515,10 @@ fn gen_child_taskgroup(linked: bool, supervised: bool) // None { ancestor_list(None) } let tmp = util::replace(&mut **ancestors, None); if tmp.is_some() { - let ancestor_arc = option::unwrap(move tmp); + let ancestor_arc = option::unwrap(tmp); let result = ancestor_arc.clone(); - **ancestors = move Some(move ancestor_arc); - AncestorList(Some(move result)) + **ancestors = Some(ancestor_arc); + AncestorList(Some(result)) } else { AncestorList(None) } @@ -530,7 +530,7 @@ pub fn spawn_raw(opts: TaskOpts, f: fn~()) { gen_child_taskgroup(opts.linked, opts.supervised); unsafe { - let child_data = ~mut Some((move child_tg, move ancestors, move f)); + let child_data = ~mut Some((child_tg, ancestors, f)); // Being killed with the unsafe task/closure pointers would leak them. do unkillable { // Agh. Get move-mode items into the closure. FIXME (#2829) @@ -548,8 +548,8 @@ pub fn spawn_raw(opts: TaskOpts, f: fn~()) { Some(option::swap_unwrap(&mut opts.notify_chan)) }; - let child_wrapper = make_child_wrapper(new_task, move child_tg, - move ancestors, is_main, move notify_chan, move f); + let child_wrapper = make_child_wrapper(new_task, child_tg, + ancestors, is_main, notify_chan, f); let closure = cast::transmute(&child_wrapper); @@ -557,7 +557,7 @@ pub fn spawn_raw(opts: TaskOpts, f: fn~()) { // closure. (Reordering them wouldn't help - then getting killed // between them would leak.) rt::start_task(new_task, closure); - cast::forget(move child_wrapper); + cast::forget(child_wrapper); } } @@ -571,8 +571,8 @@ pub fn spawn_raw(opts: TaskOpts, f: fn~()) { ancestors: AncestorList, is_main: bool, notify_chan: Option>, f: fn~()) -> fn~() { - let child_data = ~mut Some((move child_arc, move ancestors)); - return fn~(move notify_chan, move child_data, move f) { + let child_data = ~mut Some((child_arc, ancestors)); + return fn~() { // Agh. Get move-mode items into the closure. FIXME (#2829) let mut (child_arc, ancestors) = option::swap_unwrap(child_data); // Child task runs this code. @@ -584,14 +584,14 @@ pub fn spawn_raw(opts: TaskOpts, f: fn~()) { let notifier = match notify_chan { Some(ref notify_chan_value) => { let moved_ncv = move_it!(*notify_chan_value); - Some(AutoNotify(move moved_ncv)) + Some(AutoNotify(moved_ncv)) } _ => None }; if enlist_many(child, &child_arc, &mut ancestors) { - let group = @TCB(child, move child_arc, move ancestors, - is_main, move notifier); + let group = @TCB(child, child_arc, ancestors, + is_main, notifier); unsafe { local_set(child, taskgroup_key!(), group); } @@ -694,7 +694,7 @@ fn test_spawn_raw_unsupervise() { notify_chan: None, .. default_task_opts() }; - do spawn_raw(move opts) { + do spawn_raw(opts) { fail!(); } } @@ -702,13 +702,13 @@ fn test_spawn_raw_unsupervise() { #[test] #[ignore(cfg(windows))] fn test_spawn_raw_notify_success() { - let (notify_po, notify_ch) = pipes::stream(); + let (notify_po, notify_ch) = comm::stream(); let opts = task::TaskOpts { notify_chan: Some(notify_ch), .. default_task_opts() }; - do spawn_raw(move opts) { + do spawn_raw(opts) { } assert notify_po.recv() == Success; } @@ -717,14 +717,14 @@ fn test_spawn_raw_notify_success() { #[ignore(cfg(windows))] fn test_spawn_raw_notify_failure() { // New bindings for these - let (notify_po, notify_ch) = pipes::stream(); + let (notify_po, notify_ch) = comm::stream(); let opts = task::TaskOpts { linked: false, notify_chan: Some(notify_ch), .. default_task_opts() }; - do spawn_raw(move opts) { + do spawn_raw(opts) { fail!(); } assert notify_po.recv() == Failure; diff --git a/src/libcore/to_bytes.rs b/src/libcore/to_bytes.rs index 58ecf2560ace0..4b2cd3c2fab5b 100644 --- a/src/libcore/to_bytes.rs +++ b/src/libcore/to_bytes.rs @@ -170,7 +170,7 @@ impl IterBytes for char { pub mod x32 { use to_bytes::{Cb, IterBytes}; - pub impl uint: IterBytes { + pub impl IterBytes for uint { #[inline(always)] pure fn iter_bytes(&self, lsb0: bool, f: Cb) { (*self as u32).iter_bytes(lsb0, f) @@ -182,7 +182,7 @@ pub mod x32 { pub mod x64 { use to_bytes::{Cb, IterBytes}; - pub impl uint: IterBytes { + pub impl IterBytes for uint { #[inline(always)] pure fn iter_bytes(&self, lsb0: bool, f: Cb) { (*self as u64).iter_bytes(lsb0, f) @@ -197,7 +197,7 @@ impl IterBytes for int { } } -impl IterBytes for &[A] { +impl IterBytes for &[A] { #[inline(always)] pure fn iter_bytes(&self, lsb0: bool, f: Cb) { for (*self).each |elt| { @@ -208,7 +208,7 @@ impl IterBytes for &[A] { } } -impl IterBytes for (A,B) { +impl IterBytes for (A,B) { #[inline(always)] pure fn iter_bytes(&self, lsb0: bool, f: Cb) { match *self { @@ -219,7 +219,7 @@ impl IterBytes for (A,B) { } } -impl IterBytes for (A,B,C) { +impl IterBytes for (A,B,C) { #[inline(always)] pure fn iter_bytes(&self, lsb0: bool, f: Cb) { match *self { @@ -235,21 +235,21 @@ pure fn borrow(a: &x/[A]) -> &x/[A] { a } -impl IterBytes for ~[A] { +impl IterBytes for ~[A] { #[inline(always)] pure fn iter_bytes(&self, lsb0: bool, f: Cb) { borrow(*self).iter_bytes(lsb0, f) } } -impl IterBytes for @[A] { +impl IterBytes for @[A] { #[inline(always)] pure 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 pure fn iter_bytes_2(a: &A, b: &B, lsb0: bool, z: Cb) { let mut flag = true; a.iter_bytes(lsb0, |bytes| {flag = z(bytes); flag}); @@ -379,7 +379,7 @@ impl IterBytes for @str { } } -impl IterBytes for Option { +impl IterBytes for Option { #[inline(always)] pure fn iter_bytes(&self, lsb0: bool, f: Cb) { match *self { @@ -389,21 +389,21 @@ impl IterBytes for Option { } } -impl IterBytes for &A { +impl IterBytes for &A { #[inline(always)] pure fn iter_bytes(&self, lsb0: bool, f: Cb) { (**self).iter_bytes(lsb0, f); } } -impl IterBytes for @A { +impl IterBytes for @A { #[inline(always)] pure fn iter_bytes(&self, lsb0: bool, f: Cb) { (**self).iter_bytes(lsb0, f); } } -impl IterBytes for ~A { +impl IterBytes for ~A { #[inline(always)] pure fn iter_bytes(&self, lsb0: bool, f: Cb) { (**self).iter_bytes(lsb0, f); @@ -424,7 +424,7 @@ trait ToBytes { fn to_bytes(&self, lsb0: bool) -> ~[u8]; } -impl ToBytes for A { +impl ToBytes for A { fn to_bytes(&self, lsb0: bool) -> ~[u8] { do io::with_bytes_writer |wr| { for self.iter_bytes(lsb0) |bytes| { diff --git a/src/libcore/to_str.rs b/src/libcore/to_str.rs index a1e77a494d5bd..0145adc77b826 100644 --- a/src/libcore/to_str.rs +++ b/src/libcore/to_str.rs @@ -43,7 +43,9 @@ impl ToStr for @str { pure fn to_str(&self) -> ~str { ::str::from_slice(*self) } } -impl ToStr for (A, B) { +// FIXME #4898: impl for one-tuples + +impl ToStr for (A, B) { #[inline(always)] pure fn to_str(&self) -> ~str { // FIXME(#4760): this causes an llvm assertion @@ -55,7 +57,7 @@ impl ToStr for (A, B) { } } } -impl ToStr for (A, B, C) { +impl ToStr for (A, B, C) { #[inline(always)] pure fn to_str(&self) -> ~str { // FIXME(#4760): this causes an llvm assertion @@ -72,7 +74,7 @@ impl ToStr for (A, B, C) { } } -impl ToStr for ~[A] { +impl ToStr for ~[A] { #[inline(always)] pure fn to_str(&self) -> ~str { unsafe { @@ -87,16 +89,16 @@ impl ToStr for ~[A] { } } str::push_char(&mut acc, ']'); - move acc + acc } } } -impl ToStr for @A { +impl ToStr for @A { #[inline(always)] pure fn to_str(&self) -> ~str { ~"@" + (**self).to_str() } } -impl ToStr for ~A { +impl ToStr for ~A { #[inline(always)] pure fn to_str(&self) -> ~str { ~"~" + (**self).to_str() } } diff --git a/src/libcore/tuple.rs b/src/libcore/tuple.rs index 23235104e9fc6..dde7d718c13d5 100644 --- a/src/libcore/tuple.rs +++ b/src/libcore/tuple.rs @@ -20,7 +20,7 @@ pub trait CopyableTuple { pure fn swap() -> (U, T); } -impl CopyableTuple for (T, U) { +impl CopyableTuple for (T, U) { /// Return the first element of self #[inline(always)] @@ -70,7 +70,7 @@ pub trait ExtendedTupleOps { fn map(&self, f: &fn(a: &A, b: &B) -> C) -> ~[C]; } -impl ExtendedTupleOps for (&[A], &[B]) { +impl ExtendedTupleOps for (&[A], &[B]) { #[inline(always)] fn zip(&self) -> ~[(A, B)] { match *self { @@ -90,7 +90,7 @@ impl ExtendedTupleOps for (&[A], &[B]) { } } -impl ExtendedTupleOps for (~[A], ~[B]) { +impl ExtendedTupleOps for (~[A], ~[B]) { #[inline(always)] fn zip(&self) -> ~[(A, B)] { @@ -111,8 +111,10 @@ impl ExtendedTupleOps for (~[A], ~[B]) { } } +// FIXME #4898: impl for one-tuples + #[cfg(notest)] -impl Eq for (A, B) { +impl Eq for (A, B) { #[inline(always)] pure fn eq(&self, other: &(A, B)) -> bool { match (*self) { @@ -128,7 +130,7 @@ impl Eq for (A, B) { } #[cfg(notest)] -impl Ord for (A, B) { +impl Ord for (A, B) { #[inline(always)] pure fn lt(&self, other: &(A, B)) -> bool { match (*self) { @@ -153,7 +155,7 @@ impl Ord for (A, B) { } #[cfg(notest)] -impl Eq for (A, B, C) { +impl Eq for (A, B, C) { #[inline(always)] pure fn eq(&self, other: &(A, B, C)) -> bool { match (*self) { @@ -170,7 +172,7 @@ impl Eq for (A, B, C) { } #[cfg(notest)] -impl Ord for (A, B, C) { +impl Ord for (A, B, C) { #[inline(always)] pure fn lt(&self, other: &(A, B, C)) -> bool { match (*self) { diff --git a/src/libcore/util.rs b/src/libcore/util.rs index 87cbcdfe30b9a..629c4a3291ce0 100644 --- a/src/libcore/util.rs +++ b/src/libcore/util.rs @@ -19,7 +19,7 @@ use prelude::*; /// The identity function. #[inline(always)] -pub pure fn id(x: T) -> T { move x } +pub pure fn id(x: T) -> T { x } /// Ignores a value. #[inline(always)] @@ -28,7 +28,7 @@ pub pure fn ignore(_x: T) { } /// Sets `*ptr` to `new_value`, invokes `op()`, and then restores the /// original value of `*ptr`. #[inline(always)] -pub fn with( +pub fn with( ptr: &mut T, new_value: T, op: &fn() -> R) -> R @@ -37,10 +37,10 @@ pub fn with( // we wouldn't need to copy... let old_value = *ptr; - *ptr = move new_value; + *ptr = new_value; let result = op(); - *ptr = move old_value; - return move result; + *ptr = old_value; + return result; } /** @@ -58,9 +58,9 @@ pub fn swap(x: &mut T, y: &mut T) { */ #[inline(always)] pub fn replace(dest: &mut T, src: T) -> T { - let mut tmp = move src; + let mut tmp = src; swap(dest, &mut tmp); - move tmp + tmp } /// A non-copyable dummy type. @@ -109,7 +109,7 @@ mod tests { let x = ~[(5, false)]; //FIXME #3387 assert x.eq(id(copy x)); let y = copy x; - assert x.eq(&id(move y)); + assert x.eq(&id(y)); } #[test] pub fn test_swap() { diff --git a/src/libcore/vec.rs b/src/libcore/vec.rs index 3808e13be1cbc..31c837e7e8a3a 100644 --- a/src/libcore/vec.rs +++ b/src/libcore/vec.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. // @@ -22,6 +22,7 @@ use kinds::Copy; use libc; use libc::size_t; use option::{None, Option, Some}; +use private::intrinsics; use ptr; use ptr::addr_of; use sys; @@ -30,18 +31,16 @@ use vec; #[abi = "cdecl"] pub extern mod rustrt { + // These names are terrible. reserve_shared applies + // to ~[] and reserve_shared_actual applies to @[]. unsafe fn vec_reserve_shared(++t: *sys::TypeDesc, ++v: **raw::VecRepr, ++n: libc::size_t); + unsafe fn vec_reserve_shared_actual(++t: *sys::TypeDesc, + ++v: **raw::VecRepr, + ++n: libc::size_t); } -#[abi = "rust-intrinsic"] -pub extern mod rusti { - fn move_val_init(dst: &mut T, -src: T); - fn init() -> T; -} - - /// Returns true if a vector contains no elements pub pure fn is_empty(v: &[const T]) -> bool { as_const_buf(v, |_p, len| len == 0u) @@ -65,11 +64,17 @@ pub pure fn same_length(xs: &[const T], ys: &[const U]) -> bool { */ pub fn reserve(v: &mut ~[T], n: uint) { // Only make the (slow) call into the runtime if we have to + use managed; if capacity(v) < n { unsafe { let ptr: **raw::VecRepr = cast::transmute(v); - rustrt::vec_reserve_shared(sys::get_type_desc::(), - ptr, n as size_t); + let td = sys::get_type_desc::(); + if ((**ptr).box_header.ref_count == + managed::raw::RC_MANAGED_UNIQUE) { + rustrt::vec_reserve_shared_actual(td, ptr, n as size_t); + } else { + rustrt::vec_reserve_shared(td, ptr, n as size_t); + } } } } @@ -120,7 +125,8 @@ pub pure fn from_fn(n_elts: uint, op: iter::InitOp) -> ~[T] { do as_mut_buf(v) |p, _len| { let mut i: uint = 0u; while i < n_elts { - rusti::move_val_init(&mut(*ptr::mut_offset(p, i)), op(i)); + intrinsics::move_val_init(&mut(*ptr::mut_offset(p, i)), + op(i)); i += 1u; } } @@ -135,12 +141,12 @@ 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 pure fn from_elem(n_elts: uint, t: T) -> ~[T] { from_fn(n_elts, |_i| copy t) } /// Creates a new unique vector with the same contents as the slice -pub pure fn from_slice(t: &[T]) -> ~[T] { +pub pure fn from_slice(t: &[T]) -> ~[T] { from_fn(t.len(), |i| t[i]) } @@ -216,29 +222,29 @@ pub pure fn cast_from_mut(v: ~[mut T]) -> ~[T] { // Accessors /// Returns the first element of a vector -pub pure fn head(v: &[const T]) -> T { v[0] } +pub pure fn head(v: &[const T]) -> T { v[0] } /// Returns a vector containing all but the first element of a slice -pub pure fn tail(v: &[const T]) -> ~[T] { - return slice(v, 1u, len(v)); +pub pure fn tail(v: &[const T]) -> ~[T] { + slice(v, 1u, len(v)).to_vec() } /** * Returns a vector containing all but the first `n` \ * elements of a slice */ -pub pure fn tailn(v: &[const T], n: uint) -> ~[T] { - slice(v, n, len(v)) +pub pure fn tailn(v: &[const T], n: uint) -> ~[T] { + slice(v, n, len(v)).to_vec() } /// Returns a vector containing all but the last element of a slice -pub pure fn init(v: &[const T]) -> ~[T] { +pub pure fn init(v: &[const T]) -> ~[T] { assert len(v) != 0u; - slice(v, 0u, len(v) - 1u) + slice(v, 0u, len(v) - 1u).to_vec() } /// Returns the last element of the slice `v`, failing if the slice is empty. -pub pure fn last(v: &[const T]) -> T { +pub pure fn last(v: &[const T]) -> T { if len(v) == 0u { fail!(~"last_unsafe: empty vector") } v[len(v) - 1u] } @@ -247,25 +253,14 @@ pub pure fn last(v: &[const T]) -> T { * Returns `Some(x)` where `x` is the last element of the slice `v`, * or `none` if the vector is empty. */ -pub pure fn last_opt(v: &[const T]) -> Option { +pub pure fn last_opt(v: &[const T]) -> Option { if len(v) == 0u { return None; } Some(v[len(v) - 1u]) } -/// Returns a copy of the elements from [`start`..`end`) from `v`. -pub pure fn slice(v: &[const T], start: uint, end: uint) -> ~[T] { - assert (start <= end); - assert (end <= len(v)); - let mut result = ~[]; - unsafe { - for uint::range(start, end) |i| { result.push(v[i]) } - } - result -} - /// Return a slice that points into another slice. #[inline(always)] -pub pure fn view(v: &r/[T], start: uint, end: uint) -> &r/[T] { +pub pure fn slice(v: &r/[T], start: uint, end: uint) -> &r/[T] { assert (start <= end); assert (end <= len(v)); do as_imm_buf(v) |p, _len| { @@ -279,7 +274,9 @@ pub pure fn view(v: &r/[T], start: uint, end: uint) -> &r/[T] { /// Return a slice that points into another slice. #[inline(always)] -pub pure fn mut_view(v: &r/[mut T], start: uint, end: uint) -> &r/[mut T] { +pub pure fn mut_slice(v: &r/[mut T], start: uint, + end: uint) -> &r/[mut T] { + assert (start <= end); assert (end <= len(v)); do as_mut_buf(v) |p, _len| { @@ -293,7 +290,7 @@ pub pure fn mut_view(v: &r/[mut T], start: uint, end: uint) -> &r/[mut T] { /// Return a slice that points into another slice. #[inline(always)] -pub pure fn const_view(v: &r/[const T], start: uint, +pub pure fn const_slice(v: &r/[const T], start: uint, end: uint) -> &r/[const T] { assert (start <= end); assert (end <= len(v)); @@ -309,7 +306,7 @@ pub pure fn const_view(v: &r/[const T], start: uint, /// Copies /// Split the vector `v` by applying each element against the predicate `f`. -pub fn split(v: &[T], f: fn(t: &T) -> bool) -> ~[~[T]] { +pub fn split(v: &[T], f: fn(t: &T) -> bool) -> ~[~[T]] { let ln = len(v); if (ln == 0u) { return ~[] } @@ -319,12 +316,12 @@ pub fn split(v: &[T], f: fn(t: &T) -> bool) -> ~[~[T]] { match position_between(v, start, ln, f) { None => break, Some(i) => { - result.push(slice(v, start, i)); + result.push(slice(v, start, i).to_vec()); start = i + 1u; } } } - result.push(slice(v, start, ln)); + result.push(slice(v, start, ln).to_vec()); result } @@ -332,7 +329,7 @@ pub fn split(v: &[T], f: fn(t: &T) -> bool) -> ~[~[T]] { * Split the vector `v` by applying each element against the predicate `f` up * to `n` times. */ -pub fn splitn(v: &[T], n: uint, f: fn(t: &T) -> bool) -> ~[~[T]] { +pub fn splitn(v: &[T], n: uint, f: fn(t: &T) -> bool) -> ~[~[T]] { let ln = len(v); if (ln == 0u) { return ~[] } @@ -343,14 +340,14 @@ pub fn splitn(v: &[T], n: uint, f: fn(t: &T) -> bool) -> ~[~[T]] { match position_between(v, start, ln, f) { None => break, Some(i) => { - result.push(slice(v, start, i)); + result.push(slice(v, start, i).to_vec()); // Make sure to skip the separator. start = i + 1u; count -= 1u; } } } - result.push(slice(v, start, ln)); + result.push(slice(v, start, ln).to_vec()); result } @@ -358,7 +355,7 @@ pub fn splitn(v: &[T], n: uint, f: fn(t: &T) -> bool) -> ~[~[T]] { * Reverse split the vector `v` by applying each element against the predicate * `f`. */ -pub fn rsplit(v: &[T], f: fn(t: &T) -> bool) -> ~[~[T]] { +pub fn rsplit(v: &[T], f: fn(t: &T) -> bool) -> ~[~[T]] { let ln = len(v); if (ln == 0) { return ~[] } @@ -368,12 +365,12 @@ pub fn rsplit(v: &[T], f: fn(t: &T) -> bool) -> ~[~[T]] { match rposition_between(v, 0, end, f) { None => break, Some(i) => { - result.push(slice(v, i + 1, end)); + result.push(slice(v, i + 1, end).to_vec()); end = i; } } } - result.push(slice(v, 0u, end)); + result.push(slice(v, 0u, end).to_vec()); reverse(result); return result; } @@ -382,7 +379,7 @@ pub fn rsplit(v: &[T], f: fn(t: &T) -> bool) -> ~[~[T]] { * Reverse split the vector `v` by applying each element against the predicate * `f` up to `n times. */ -pub fn rsplitn(v: &[T], n: uint, f: fn(t: &T) -> bool) -> ~[~[T]] { +pub fn rsplitn(v: &[T], n: uint, f: fn(t: &T) -> bool) -> ~[~[T]] { let ln = len(v); if (ln == 0u) { return ~[] } @@ -393,14 +390,14 @@ pub fn rsplitn(v: &[T], n: uint, f: fn(t: &T) -> bool) -> ~[~[T]] { match rposition_between(v, 0u, end, f) { None => break, Some(i) => { - result.push(slice(v, i + 1u, end)); + result.push(slice(v, i + 1u, end).to_vec()); // Make sure to skip the separator. end = i; count -= 1u; } } } - result.push(slice(v, 0u, end)); + result.push(slice(v, 0u, end).to_vec()); reverse(result); result } @@ -430,7 +427,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 pure fn partitioned(v: &[T], f: fn(&T) -> bool) -> (~[T], ~[T]) { let mut lefts = ~[]; let mut rights = ~[]; @@ -478,15 +475,15 @@ pub fn shift(v: &mut ~[T]) -> T { // popped. For the moment it unsafely exists at both the head and last // positions { - let first_slice = view(*v, 0, 1); - let last_slice = view(*v, next_ln, ln); + let first_slice = slice(*v, 0, 1); + let last_slice = slice(*v, next_ln, ln); raw::copy_memory(::cast::transmute(last_slice), first_slice, 1); } // Memcopy everything to the left one element { - let init_slice = view(*v, 0, next_ln); - let tail_slice = view(*v, 1, ln); + let init_slice = slice(*v, 0, next_ln); + let tail_slice = slice(*v, 1, ln); raw::copy_memory(::cast::transmute(init_slice), tail_slice, next_ln); @@ -547,7 +544,7 @@ pub fn consume(mut v: ~[T], f: fn(uint, v: T)) { // holes we create in the vector. That ensures that, if the // iterator fails then we won't try to clean up the consumed // elements during unwinding - let mut x = rusti::init(); + let mut x = intrinsics::init(); let p = ptr::mut_offset(p, i); x <-> *p; f(i, x); @@ -566,8 +563,8 @@ pub fn pop(v: &mut ~[T]) -> T { } let valptr = ptr::to_mut_unsafe_ptr(&mut v[ln - 1u]); unsafe { - // FIXME #4204: Should be rusti::uninit() - we don't need this zeroed - let mut val = rusti::init(); + // FIXME #4204: Should be uninit() - we don't need this zeroed + let mut val = intrinsics::init(); val <-> *valptr; raw::set_len(v, ln - 1u); val @@ -614,7 +611,7 @@ unsafe fn push_fast(v: &mut ~[T], initval: T) { (**repr).unboxed.fill += sys::nonzero_size_of::(); let p = addr_of(&((**repr).unboxed.data)); let p = ptr::offset(p, fill) as *mut T; - rusti::move_val_init(&mut(*p), move initval); + intrinsics::move_val_init(&mut(*p), initval); } #[inline(never)] @@ -625,7 +622,7 @@ fn push_slow(v: &mut ~[T], initval: T) { } #[inline(always)] -pub fn push_all(v: &mut ~[T], rhs: &[const T]) { +pub fn push_all(v: &mut ~[T], rhs: &[const T]) { let new_len = v.len() + rhs.len(); reserve(&mut *v, new_len); @@ -641,8 +638,8 @@ pub fn push_all_move(v: &mut ~[T], mut rhs: ~[T]) { unsafe { do as_mut_buf(rhs) |p, len| { for uint::range(0, len) |i| { - // FIXME #4204 Should be rusti::uninit() - don't need to zero - let mut x = rusti::init(); + // FIXME #4204 Should be uninit() - don't need to zero + let mut x = intrinsics::init(); x <-> *ptr::mut_offset(p, i); push(&mut *v, x); } @@ -658,8 +655,8 @@ pub fn truncate(v: &mut ~[T], newlen: uint) { unsafe { // This loop is optimized out for non-drop types. for uint::range(newlen, oldlen) |i| { - // FIXME #4204 Should be rusti::uninit() - don't need to zero - let mut dropped = rusti::init(); + // FIXME #4204 Should be uninit() - don't need to zero + let mut dropped = intrinsics::init(); dropped <-> *ptr::mut_offset(p, i); } } @@ -671,7 +668,7 @@ pub fn truncate(v: &mut ~[T], newlen: uint) { * Remove consecutive repeated elements from a vector; if the vector is * sorted, this removes all duplicates. */ -pub fn dedup(v: &mut ~[T]) { +pub fn dedup(v: &mut ~[T]) { unsafe { if v.len() < 1 { return; } let mut last_written = 0, next_to_read = 1; @@ -684,9 +681,9 @@ pub fn dedup(v: &mut ~[T]) { // last_written < next_to_read < ln if *ptr::mut_offset(p, next_to_read) == *ptr::mut_offset(p, last_written) { - // FIXME #4204 Should be rusti::uninit() - don't need to + // FIXME #4204 Should be uninit() - don't need to // zero - let mut dropped = rusti::init(); + let mut dropped = intrinsics::init(); dropped <-> *ptr::mut_offset(p, next_to_read); } else { last_written += 1; @@ -709,7 +706,7 @@ pub fn dedup(v: &mut ~[T]) { // Appending #[inline(always)] -pub pure fn append(lhs: ~[T], rhs: &[const T]) -> ~[T] { +pub pure fn append(lhs: ~[T], rhs: &[const T]) -> ~[T] { let mut v = lhs; unsafe { v.push_all(rhs); @@ -733,7 +730,7 @@ pub pure fn append_one(lhs: ~[T], x: T) -> ~[T] { * * n - The number of elements to add * * initval - The value for the new elements */ -pub fn grow(v: &mut ~[T], n: uint, initval: &T) { +pub fn grow(v: &mut ~[T], n: uint, initval: &T) { let new_len = v.len() + n; reserve_at_least(&mut *v, new_len); let mut i: uint = 0u; @@ -775,7 +772,7 @@ pub fn grow_fn(v: &mut ~[T], n: uint, op: iter::InitOp) { * of the vector, expands the vector by replicating `initval` to fill the * intervening space. */ -pub fn grow_set(v: &mut ~[T], index: uint, initval: &T, val: T) { +pub fn grow_set(v: &mut ~[T], index: uint, initval: &T, val: T) { let l = v.len(); if index >= l { grow(&mut *v, index - l + 1u, initval); } v[index] = val; @@ -822,7 +819,7 @@ pub pure fn flat_map(v: &[T], f: fn(t: &T) -> ~[U]) -> ~[U] { } /// Apply a function to each pair of elements and return the results -pub pure fn map2(v0: &[T], v1: &[U], +pub pure fn map2(v0: &[T], v1: &[U], f: fn(t: &T, v: &U) -> V) -> ~[V] { let v0_len = len(v0); if v0_len != len(v1) { fail!(); } @@ -900,7 +897,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 pure fn filtered(v: &[T], f: fn(t: &T) -> bool) -> ~[T] { let mut result = ~[]; for each(v) |elem| { if f(elem) { unsafe { result.push(*elem); } } @@ -933,14 +930,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 pure 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 pure fn connect(v: &[~[T]], sep: &T) -> ~[T] { let mut r: ~[T] = ~[]; let mut first = true; for each(v) |inner| { @@ -1069,13 +1066,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 pure fn contains(v: &[T], x: &T) -> bool { for each(v) |elt| { if *x == *elt { return true; } } return false; } /// Returns the number of elements that are equal to a given value -pub pure fn count(v: &[T], x: &T) -> uint { +pub pure fn count(v: &[T], x: &T) -> uint { let mut cnt = 0u; for each(v) |elt| { if *x == *elt { cnt += 1u; } } return cnt; @@ -1088,7 +1085,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 pure fn find(v: &[T], f: fn(t: &T) -> bool) -> Option { find_between(v, 0u, len(v), f) } @@ -1099,7 +1096,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 pure fn find_between(v: &[T], start: uint, end: uint, f: fn(t: &T) -> bool) -> Option { position_between(v, start, end, f).map(|i| v[*i]) } @@ -1111,7 +1108,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 pure fn rfind(v: &[T], f: fn(t: &T) -> bool) -> Option { rfind_between(v, 0u, len(v), f) } @@ -1122,13 +1119,13 @@ 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, +pub pure fn rfind_between(v: &[T], start: uint, end: uint, f: fn(t: &T) -> bool) -> Option { rposition_between(v, start, end, f).map(|i| v[*i]) } /// Find the first index containing a matching value -pub pure fn position_elem(v: &[T], x: &T) -> Option { +pub pure fn position_elem(v: &[T], x: &T) -> Option { position(v, |y| *x == *y) } @@ -1160,7 +1157,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 { +pure fn rposition_elem(v: &[T], x: &T) -> Option { rposition(v, |y| *x == *y) } @@ -1202,7 +1199,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]) { +pure fn unzip_slice(v: &[(T, U)]) -> (~[T], ~[U]) { let mut ts = ~[], us = ~[]; for each(v) |p| { let (t, u) = *p; @@ -1237,7 +1234,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 pure fn zip_slice(v: &[const T], u: &[const U]) -> ~[(T, U)] { let mut zipped = ~[]; let sz = len(v); @@ -1288,7 +1285,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 pure fn reversed(v: &[const T]) -> ~[T] { let mut rs: ~[T] = ~[]; let mut i = len::(v); if i == 0 { return (rs); } else { i -= 1; } @@ -1454,7 +1451,7 @@ pub 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. */ -pure fn each_permutation(v: &[T], put: fn(ts: &[T]) -> bool) { +pure fn each_permutation(v: &[T], put: fn(ts: &[T]) -> bool) { let ln = len(v); if ln <= 1 { put(v); @@ -1464,9 +1461,9 @@ pure fn each_permutation(v: &[T], put: fn(ts: &[T]) -> bool) { let mut i = 0u; while i < ln { let elt = v[i]; - let mut rest = slice(v, 0u, i); + let mut rest = slice(v, 0u, i).to_vec(); unsafe { - rest.push_all(const_view(v, i+1u, ln)); + rest.push_all(const_slice(v, i+1u, ln)); for each_permutation(rest) |permutation| { if !put(append(~[elt], permutation)) { return; @@ -1478,14 +1475,14 @@ pure fn each_permutation(v: &[T], put: fn(ts: &[T]) -> bool) { } } -pub pure fn windowed(nn: uint, xx: &[TT]) -> ~[~[TT]] { +pub pure fn windowed(nn: uint, xx: &[TT]) -> ~[~[TT]] { let mut ww = ~[]; assert 1u <= nn; for vec::eachi (xx) |ii, _x| { let len = vec::len(xx); if ii+nn <= len { unsafe { - ww.push(vec::slice(xx, ii, ii+nn)); + ww.push(slice(xx, ii, ii+nn).to_vec()); } } } @@ -1545,7 +1542,7 @@ pub pure fn as_mut_buf(s: &mut [T], // Equality -pure fn eq(a: &[T], b: &[T]) -> bool { +pure fn eq(a: &[T], b: &[T]) -> bool { let (a_len, b_len) = (a.len(), b.len()); if a_len != b_len { return false; } @@ -1559,7 +1556,7 @@ pure fn eq(a: &[T], b: &[T]) -> bool { } #[cfg(notest)] -impl Eq for &[T] { +impl Eq for &[T] { #[inline(always)] pure fn eq(&self, other: & &self/[T]) -> bool { eq((*self), (*other)) } #[inline(always)] @@ -1568,7 +1565,7 @@ impl Eq for &[T] { #[cfg(notest)] -impl Eq for ~[T] { +impl Eq for ~[T] { #[inline(always)] pure fn eq(&self, other: &~[T]) -> bool { eq((*self), (*other)) } #[inline(always)] @@ -1576,7 +1573,7 @@ impl Eq for ~[T] { } #[cfg(notest)] -impl Eq for @[T] { +impl Eq for @[T] { #[inline(always)] pure fn eq(&self, other: &@[T]) -> bool { eq((*self), (*other)) } #[inline(always)] @@ -1585,7 +1582,7 @@ impl Eq for @[T] { // Lexicographical comparison -pure fn lt(a: &[T], b: &[T]) -> bool { +pure 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); @@ -1600,12 +1597,12 @@ pure fn lt(a: &[T], b: &[T]) -> bool { return 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) } +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) } #[cfg(notest)] -impl Ord for &[T] { +impl Ord for &[T] { #[inline(always)] pure fn lt(&self, other: & &self/[T]) -> bool { lt((*self), (*other)) } #[inline(always)] @@ -1617,7 +1614,7 @@ impl Ord for &[T] { } #[cfg(notest)] -impl Ord for ~[T] { +impl Ord for ~[T] { #[inline(always)] pure fn lt(&self, other: &~[T]) -> bool { lt((*self), (*other)) } #[inline(always)] @@ -1629,7 +1626,7 @@ impl Ord for ~[T] { } #[cfg(notest)] -impl Ord for @[T] { +impl Ord for @[T] { #[inline(always)] pure fn lt(&self, other: &@[T]) -> bool { lt((*self), (*other)) } #[inline(always)] @@ -1646,7 +1643,7 @@ pub mod traits { use ops::Add; use vec::append; - impl Add<&[const T],~[T]> for ~[T] { + impl Add<&[const T],~[T]> for ~[T] { #[inline(always)] pure fn add(&self, rhs: & &self/[const T]) -> ~[T] { append(copy *self, (*rhs)) @@ -1673,7 +1670,7 @@ pub trait CopyableVector { } /// Extension methods for vectors -impl CopyableVector for &[const T] { +impl CopyableVector for &[const T] { /// Returns the first element of a vector #[inline] pure fn head(&self) -> T { head(*self) } @@ -1689,7 +1686,7 @@ impl CopyableVector for &[const T] { /// Returns a copy of the elements from [`start`..`end`) from `v`. #[inline] pure fn slice(&self, start: uint, end: uint) -> ~[T] { - slice(*self, start, end) + slice(*self, start, end).to_vec() } /// Returns all but the first element of a vector @@ -1699,13 +1696,13 @@ impl CopyableVector for &[const T] { pub trait ImmutableVector { pure fn view(&self, start: uint, end: uint) -> &self/[T]; - pure fn foldr(&self, z: U, p: fn(t: &T, u: U) -> U) -> U; + 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 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]; + pure fn filter_mapped(&self, f: fn(t: &T) -> Option) -> ~[U]; } /// Extension methods for vectors @@ -1713,12 +1710,12 @@ impl ImmutableVector for &[T] { /// Return a slice that points into another slice. #[inline] pure fn view(&self, start: uint, end: uint) -> &self/[T] { - view(*self, start, end) + slice(*self, start, end) } /// Reduce a vector from right to left #[inline] - pure fn foldr(&self, z: U, p: fn(t: &T, u: U) -> U) -> U { + pure fn foldr(&self, z: U, p: fn(t: &T, u: U) -> U) -> U { foldr(*self, z, p) } @@ -1768,19 +1765,19 @@ impl ImmutableVector for &[T] { * the resulting vector. */ #[inline] - pure fn filter_mapped(&self, f: fn(t: &T) -> Option) -> ~[U] { + pure fn filter_mapped(&self, f: fn(t: &T) -> Option) -> ~[U] { filter_mapped(*self, f) } } -pub trait ImmutableEqVector { +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; } -impl ImmutableEqVector for &[T] { +impl ImmutableEqVector for &[T] { /** * Find the first index matching some predicate * @@ -1825,7 +1822,7 @@ pub trait ImmutableCopyableVector { } /// Extension methods for vectors -impl ImmutableCopyableVector for &[T] { +impl ImmutableCopyableVector for &[T] { /** * Construct a new vector from the elements of a vector for which some * predicate holds. @@ -1874,6 +1871,7 @@ pub trait OwnedVector { 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 grow_fn(&mut self, n: uint, op: iter::InitOp); } impl OwnedVector for ~[T] { @@ -1945,6 +1943,11 @@ impl OwnedVector for ~[T] { fn partition(self, f: fn(&T) -> bool) -> (~[T], ~[T]) { partition(self, f) } + + #[inline] + fn grow_fn(&mut self, n: uint, op: iter::InitOp) { + grow_fn(self, n, op); + } } impl Mutable for ~[T] { @@ -1952,14 +1955,13 @@ impl Mutable for ~[T] { fn clear(&mut self) { self.truncate(0) } } -pub trait OwnedCopyableVector { +pub trait OwnedCopyableVector { fn push_all(&mut self, rhs: &[const T]); fn grow(&mut self, n: uint, initval: &T); - fn grow_fn(&mut self, n: uint, op: iter::InitOp); fn grow_set(&mut self, index: uint, initval: &T, val: T); } -impl OwnedCopyableVector for ~[T] { +impl OwnedCopyableVector for ~[T] { #[inline] fn push_all(&mut self, rhs: &[const T]) { push_all(self, rhs); @@ -1970,22 +1972,17 @@ impl OwnedCopyableVector for ~[T] { grow(self, n, initval); } - #[inline] - fn grow_fn(&mut self, n: uint, op: iter::InitOp) { - grow_fn(self, n, op); - } - #[inline] fn grow_set(&mut self, index: uint, initval: &T, val: T) { grow_set(self, index, initval, val); } } -trait OwnedEqVector { +trait OwnedEqVector { fn dedup(&mut self); } -impl OwnedEqVector for ~[T] { +impl OwnedEqVector for ~[T] { #[inline] fn dedup(&mut self) { dedup(self) @@ -2018,11 +2015,11 @@ pub mod raw { use managed; use option::{None, Some}; use option; + use private::intrinsics; use ptr::addr_of; use ptr; use sys; use vec::{UnboxedVecRepr, as_const_buf, as_mut_buf, len, with_capacity}; - use vec::rusti; /// The internal representation of a (boxed) vector pub struct VecRepr { @@ -2095,7 +2092,7 @@ pub mod raw { * Unchecked vector indexing. */ #[inline(always)] - pub unsafe fn get(v: &[const T], i: uint) -> T { + pub unsafe fn get(v: &[const T], i: uint) -> T { as_const_buf(v, |p, _len| *ptr::const_offset(p, i)) } @@ -2110,7 +2107,7 @@ pub mod raw { do as_mut_buf(v) |p, _len| { let mut box2 = None; box2 <-> box; - rusti::move_val_init(&mut(*ptr::mut_offset(p, i)), + intrinsics::move_val_init(&mut(*ptr::mut_offset(p, i)), option::unwrap(box2)); } } @@ -2333,24 +2330,24 @@ impl iter::ExtendedIter for @[A] { } } -impl iter::EqIter for &[A] { +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) } } // FIXME(#4148): This should be redundant -impl iter::EqIter for ~[A] { +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) } } // FIXME(#4148): This should be redundant -impl iter::EqIter for @[A] { +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) } } -impl iter::CopyableIter for &[A] { +impl iter::CopyableIter for &[A] { pure fn filter_to_vec(&self, pred: fn(&A) -> bool) -> ~[A] { iter::filter_to_vec(self, pred) } @@ -2361,7 +2358,7 @@ impl iter::CopyableIter for &[A] { } // FIXME(#4148): This should be redundant -impl iter::CopyableIter for ~[A] { +impl iter::CopyableIter for ~[A] { pure fn filter_to_vec(&self, pred: fn(&A) -> bool) -> ~[A] { iter::filter_to_vec(self, pred) } @@ -2372,7 +2369,7 @@ impl iter::CopyableIter for ~[A] { } // FIXME(#4148): This should be redundant -impl iter::CopyableIter for @[A] { +impl iter::CopyableIter for @[A] { pure fn filter_to_vec(&self, pred: fn(&A) -> bool) -> ~[A] { iter::filter_to_vec(self, pred) } @@ -2382,19 +2379,19 @@ impl iter::CopyableIter for @[A] { } } -impl iter::CopyableOrderedIter for &[A] { +impl iter::CopyableOrderedIter for &[A] { pure fn min(&self) -> A { iter::min(self) } pure fn max(&self) -> A { iter::max(self) } } // FIXME(#4148): This should be redundant -impl iter::CopyableOrderedIter for ~[A] { +impl iter::CopyableOrderedIter for ~[A] { pure fn min(&self) -> A { iter::min(self) } pure fn max(&self) -> A { iter::max(self) } } // FIXME(#4148): This should be redundant -impl iter::CopyableOrderedIter for @[A] { +impl iter::CopyableOrderedIter for @[A] { pure fn min(&self) -> A { iter::min(self) } pure fn max(&self) -> A { iter::max(self) } } @@ -2566,42 +2563,45 @@ mod tests { #[test] fn test_slice() { - // Test on-stack -> on-stack slice. - let mut v = slice(~[1, 2, 3], 1u, 3u); - assert (len(v) == 2u); - assert (v[0] == 2); - assert (v[1] == 3); - - // Test on-heap -> on-stack slice. - v = slice(~[1, 2, 3, 4, 5], 0u, 3u); - assert (len(v) == 3u); - assert (v[0] == 1); - assert (v[1] == 2); - assert (v[2] == 3); - - // Test on-heap -> on-heap slice. - v = slice(~[1, 2, 3, 4, 5, 6], 1u, 6u); - assert (len(v) == 5u); - assert (v[0] == 2); - assert (v[1] == 3); - assert (v[2] == 4); - assert (v[3] == 5); - assert (v[4] == 6); + // Test fixed length vector. + let vec_fixed = [1, 2, 3, 4]; + let v_a = slice(vec_fixed, 1u, len(vec_fixed)).to_vec(); + assert (len(v_a) == 3u); + assert (v_a[0] == 2); + assert (v_a[1] == 3); + assert (v_a[2] == 4); + + // Test on stack. + let vec_stack = &[1, 2, 3]; + let v_b = slice(vec_stack, 1u, 3u).to_vec(); + assert (len(v_b) == 2u); + assert (v_b[0] == 2); + assert (v_b[1] == 3); + + // Test on managed heap. + let vec_managed = @[1, 2, 3, 4, 5]; + let v_c = slice(vec_managed, 0u, 3u).to_vec(); + assert (len(v_c) == 3u); + assert (v_c[0] == 1); + assert (v_c[1] == 2); + assert (v_c[2] == 3); + + // Test on exchange heap. + let vec_unique = ~[1, 2, 3, 4, 5, 6]; + let v_d = slice(vec_unique, 1u, 6u).to_vec(); + assert (len(v_d) == 5u); + assert (v_d[0] == 2); + assert (v_d[1] == 3); + assert (v_d[2] == 4); + assert (v_d[3] == 5); + assert (v_d[4] == 6); } #[test] fn test_pop() { - // Test on-stack pop. - let mut v = ~[1, 2, 3]; - let mut e = v.pop(); - assert (len(v) == 2u); - assert (v[0] == 1); - assert (v[1] == 2); - assert (e == 3); - // Test on-heap pop. - v = ~[1, 2, 3, 4, 5]; - e = v.pop(); + let mut v = ~[1, 2, 3, 4, 5]; + let e = v.pop(); assert (len(v) == 4u); assert (v[0] == 1); assert (v[1] == 2); diff --git a/src/libfuzzer/cycles.rs b/src/libfuzzer/cycles.rs index a64700494c897..7288b6d261d2c 100644 --- a/src/libfuzzer/cycles.rs +++ b/src/libfuzzer/cycles.rs @@ -18,7 +18,7 @@ fn under(r : rand::rng, n : uint) -> uint { } // random choice from a vec -fn choice(r : rand::rng, v : ~[const T]) -> T { +fn choice(r : rand::rng, v : ~[const T]) -> T { assert vec::len(v) != 0u; v[under(r, vec::len(v))] } diff --git a/src/libfuzzer/fuzzer.rc b/src/libfuzzer/fuzzer.rc index 6d0b2f8a76205..a9ddfe8140455 100644 --- a/src/libfuzzer/fuzzer.rc +++ b/src/libfuzzer/fuzzer.rc @@ -466,7 +466,7 @@ pub fn parse_and_print(code: @~str) -> ~str { sess.cm, // Assuming there are no token_trees syntax::parse::token::mk_fake_ident_interner(), - sess.span_diagnostic, + copy sess.span_diagnostic, crate, filename.to_str(), rdr, a, @@ -622,7 +622,7 @@ pub fn check_variants(files: &[Path], cx: Context) { sess.cm, // Assuming no token_trees syntax::parse::token::mk_fake_ident_interner(), - sess.span_diagnostic, + copy sess.span_diagnostic, crate, file_str, rdr, a, diff --git a/src/libfuzzer/ivec_fuzz.rs b/src/libfuzzer/ivec_fuzz.rs index eadc706fe13b2..25dc14c3d7888 100644 --- a/src/libfuzzer/ivec_fuzz.rs +++ b/src/libfuzzer/ivec_fuzz.rs @@ -32,22 +32,22 @@ extern mod std; use vec::slice; use vec::len; -fn vec_omit(v: ~[T], i: uint) -> ~[T] { +fn vec_omit(v: ~[T], i: uint) -> ~[T] { slice(v, 0u, i) + slice(v, i + 1u, len(v)) } -fn vec_dup(v: ~[T], i: uint) -> ~[T] { +fn vec_dup(v: ~[T], i: uint) -> ~[T] { slice(v, 0u, i) + [v[i]] + slice(v, i, len(v)) } -fn vec_swadj(v: ~[T], i: uint) -> ~[T] { +fn vec_swadj(v: ~[T], i: uint) -> ~[T] { slice(v, 0u, i) + [v[i + 1u], v[i]] + slice(v, i + 2u, len(v)) } -fn vec_prefix(v: ~[T], i: uint) -> ~[T] { slice(v, 0u, i) } -fn vec_suffix(v: ~[T], i: uint) -> ~[T] { slice(v, i, len(v)) } +fn vec_prefix(v: ~[T], i: uint) -> ~[T] { slice(v, 0u, i) } +fn vec_suffix(v: ~[T], i: uint) -> ~[T] { slice(v, i, len(v)) } -fn vec_poke(v: ~[T], i: uint, x: T) -> ~[T] { +fn vec_poke(v: ~[T], i: uint, x: T) -> ~[T] { slice(v, 0u, i) + ~[x] + slice(v, i + 1u, len(v)) } -fn vec_insert(v: ~[T], i: uint, x: T) -> ~[T] { +fn vec_insert(v: ~[T], i: uint, x: T) -> ~[T] { slice(v, 0u, i) + ~[x] + slice(v, i, len(v)) } @@ -59,7 +59,7 @@ fn ix(skip_low: uint, skip_high: uint, length: uint, it: block(uint)) { // Returns a bunch of modified versions of v, some of which introduce // new elements (borrowed from xs). -fn vec_edits(v: ~[T], xs: ~[T]) -> ~[~[T]] { +fn vec_edits(v: ~[T], xs: ~[T]) -> ~[~[T]] { let edits: ~[~[T]] = ~[]; let Lv: uint = len(v); diff --git a/src/libfuzzer/rand_util.rs b/src/libfuzzer/rand_util.rs index cb074eecd6db4..507d0666da029 100644 --- a/src/libfuzzer/rand_util.rs +++ b/src/libfuzzer/rand_util.rs @@ -17,7 +17,7 @@ fn under(r : rand::rng, n : uint) -> uint { } // random choice from a vec -fn choice(r : rand::rng, v : ~[T]) -> T { +fn choice(r : rand::rng, v : ~[T]) -> T { assert vec::len(v) != 0u; v[under(r, vec::len(v))] } @@ -35,7 +35,7 @@ fn shuffle(r : rand::rng, &v : ~[T]) { } // create a shuffled copy of a vec -fn shuffled(r : rand::rng, v : ~[T]) -> ~[T] { +fn shuffled(r : rand::rng, v : ~[T]) -> ~[T] { let w = vec::to_mut(v); shuffle(r, w); vec::from_mut(w) // Shouldn't this happen automatically? @@ -48,7 +48,7 @@ fn shuffled(r : rand::rng, v : ~[T]) -> ~[T] { // * weighted_choice is O(number of choices) time // * weighted_vec is O(total weight) space type weighted = { weight: uint, item: T }; -fn weighted_choice(r : rand::rng, v : ~[weighted]) -> T { +fn weighted_choice(r : rand::rng, v : ~[weighted]) -> T { assert vec::len(v) != 0u; let total = 0u; for {weight: weight, item: _} in v { @@ -66,7 +66,7 @@ fn weighted_choice(r : rand::rng, v : ~[weighted]) -> T { core::unreachable(); } -fn weighted_vec(v : ~[weighted]) -> ~[T] { +fn weighted_vec(v : ~[weighted]) -> ~[T] { let r = ~[]; for {weight: weight, item: item} in v { let i = 0u; diff --git a/src/librust/rust.rc b/src/librust/rust.rc new file mode 100644 index 0000000000000..950623b876042 --- /dev/null +++ b/src/librust/rust.rc @@ -0,0 +1,235 @@ +// 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. + +// rust - central access to other rust tools +// XXX: Make commands run and test emit proper file endings on winds +// XXX: Make run only accept source that emits an executable + +#[link(name = "rust", + vers = "0.6", + uuid = "4a24da33-5cc8-4037-9352-2cbe9bd9d27c", + url = "https://github.com/mozilla/rust/tree/master/src/rust")]; + +#[crate_type = "lib"]; + +extern mod core(vers = "0.6"); + +use core::run; + +enum ValidUsage { + Valid, Invalid +} + +impl ValidUsage { + fn is_valid(&self) -> bool { match *self { + Valid => true, + Invalid => false + }} +} + +enum Action { + Exec(&str), + Call(&fn(args: &[~str]) -> ValidUsage) +} + +enum UsageSource { + UsgExec(&str), + UsgStr(&str) +} + +struct Command { + cmd: &str, + action: Action, + usage_line: &str, + usage_full: UsageSource +} + +const commands: &[Command] = &[ + Command{ + cmd: "build", + action: Exec("rustc"), + usage_line: "compile rust source files", + usage_full: UsgExec("rustc --help") + }, + Command{ + cmd: "run", + action: Call(cmd_run), + usage_line: "build a executable, and run it", + usage_full: UsgStr( + "The run command is an shortcut for the command line \n\ + \"rustc -o ~ && ./~\".\ + \n\nUsage:\trust run " + ) + }, + Command{ + cmd: "test", + action: Call(cmd_test), + usage_line: "build a test executable, and run it", + usage_full: UsgStr( + "The test command is an shortcut for the command line \n\ + \"rustc --test -o test~ && \ + ./test~\"\n\nUsage:\trust test " + ) + }, + Command{ + cmd: "doc", + action: Exec("rustdoc"), + usage_line: "generate documentation from doc comments", + usage_full: UsgExec("rustdoc --help") + }, + Command{ + cmd: "pkg", + action: Exec("rustpkg"), + usage_line: "download, build, install rust packages", + usage_full: UsgExec("rustpkg --help") + }, + Command{ + cmd: "sketch", + action: Exec("rusti"), + usage_line: "run a rust interpreter", + usage_full: UsgStr("\nUsage:\trusti") + }, + Command{ + cmd: "help", + action: Call(cmd_help), + usage_line: "show detailed usage of a command", + usage_full: UsgStr( + "The help command displays the usage text of another command.\n\ + The text is either build in, or provided by the corresponding \ + program.\n\nUsage:\trust help " + ) + } +]; + +fn find_cmd(command_string: &str) -> Option { + do commands.find |command| { + command.cmd == command_string + } +} + +fn cmd_help(args: &[~str]) -> ValidUsage { + fn print_usage(command_string: ~str) -> ValidUsage { + match find_cmd(command_string) { + Some(command) => { + match command.action { + Exec(s) => io::println(fmt!( + "The %s command is an alias for the %s program.", + command.cmd, s)), + _ => () + } + match command.usage_full { + UsgStr(msg) => io::println(fmt!("%s\n", msg)), + UsgExec(commandline) => { + let words = str::words(commandline); + let (prog, args) = (words.head(), words.tail()); + run::run_program(prog, args); + } + } + Valid + }, + None => Invalid + } + } + + match args { + [command_string] => print_usage(command_string), + _ => Invalid + } +} + +fn cmd_test(args: &[~str]) -> ValidUsage { + match args { + [filename] => { + let test_exec = Path(filename).filestem().unwrap() + "test~"; + if run::run_program("rustc", [ + ~"--test", + filename.to_owned(), + ~"-o", + test_exec.to_owned() + ]) == 0 { + run::run_program(~"./" + test_exec, []); + } + Valid + } + _ => Invalid + } +} + +fn cmd_run(args: &[~str]) -> ValidUsage { + match args { + [filename] => { + let exec = Path(filename).filestem().unwrap() + "~"; + if run::run_program("rustc", [ + filename.to_owned(), + ~"-o", + exec.to_owned() + ]) == 0 { + run::run_program(~"./"+exec, []); + } + Valid + } + _ => Invalid + } +} + +fn do_command(command: &Command, args: &[~str]) -> ValidUsage { + match command.action { + Call(f) => f(args), + Exec(commandline) => { + let words = str::words(commandline); + let (prog, prog_args) = (words.head(), words.tail()); + let exitstatus = run::run_program(prog, prog_args + args); + os::set_exit_status(exitstatus); + Valid + } + } +} + +fn usage() { + const indent: uint = 8; + + io::print( + "The rust tool is a convenience for managing rust source code.\n\ + It acts as a shortcut for programs of the rust tool chain.\n\ + \n\ + Usage:\trust [arguments]\n\ + \n\ + The commands are:\n\ + \n" + ); + + for commands.each |command| { + let padding = str::repeat(" ", indent - command.cmd.len()); + io::println(fmt!(" %s%s%s", + command.cmd, padding, command.usage_line)); + } + + io::print( + "\n\ + Use \"rust help \" for more information about a command.\n\ + \n" + ); + +} + +fn main() { + let args = os::args().tail(); + + if !args.is_empty() { + for commands.each |command| { + if command.cmd == args.head() { + let result = do_command(command, args.tail()); + if result.is_valid() { return; } + } + } + } + + usage(); +} diff --git a/src/librustc/back/arm.rs b/src/librustc/back/arm.rs index 6ea2c5918ae26..faaddfed1e8ba 100644 --- a/src/librustc/back/arm.rs +++ b/src/librustc/back/arm.rs @@ -14,7 +14,7 @@ use session::sess_os_to_meta_os; use metadata::loader::meta_section_name; pub fn get_target_strs(target_os: session::os) -> target_strs::t { - return { + return target_strs::t { module_asm: ~"", meta_sect_name: meta_section_name(sess_os_to_meta_os(target_os)), diff --git a/src/librustc/back/link.rs b/src/librustc/back/link.rs index df362b7798408..b30f9fcb9dd83 100644 --- a/src/librustc/back/link.rs +++ b/src/librustc/back/link.rs @@ -16,10 +16,10 @@ use lib::llvm::llvm; use lib::llvm::{ModuleRef, mk_pass_manager, mk_target_data, True, False}; use lib::llvm::{PassManagerRef, FileType}; use lib; -use metadata::common::link_meta; +use metadata::common::LinkMeta; use metadata::filesearch; use metadata::{encoder, cstore}; -use middle::trans::common::crate_ctxt; +use middle::trans::common::CrateContext; use middle::ty; use session::Session; use session; @@ -156,7 +156,7 @@ pub mod jit { code: entry, env: ptr::null() }; - let func: fn(++argv: ~[~str]) = cast::transmute(move closure); + let func: fn(++argv: ~[~str]) = cast::transmute(closure); func(~[/*bad*/copy sess.opts.binary]); } @@ -451,69 +451,81 @@ pub mod write { */ pub fn build_link_meta(sess: Session, c: &ast::crate, output: &Path, - symbol_hasher: &hash::State) -> link_meta { + symbol_hasher: &hash::State) -> LinkMeta { - type provided_metas = - {name: Option<@str>, - vers: Option<@str>, - cmh_items: ~[@ast::meta_item]}; + struct ProvidedMetas { + name: Option<@str>, + vers: Option<@str>, + cmh_items: ~[@ast::meta_item] + } fn provided_link_metas(sess: Session, c: &ast::crate) -> - provided_metas { + ProvidedMetas { let mut name = None; let mut vers = None; let mut cmh_items = ~[]; let linkage_metas = attr::find_linkage_metas(c.node.attrs); attr::require_unique_names(sess.diagnostic(), linkage_metas); for linkage_metas.each |meta| { - if attr::get_meta_item_name(*meta) == ~"name" { + if *attr::get_meta_item_name(*meta) == ~"name" { match attr::get_meta_item_value_str(*meta) { // Changing attr would avoid the need for the copy // here Some(v) => { name = Some(v.to_managed()); } None => cmh_items.push(*meta) } - } else if attr::get_meta_item_name(*meta) == ~"vers" { + } else if *attr::get_meta_item_name(*meta) == ~"vers" { match attr::get_meta_item_value_str(*meta) { Some(v) => { vers = Some(v.to_managed()); } None => cmh_items.push(*meta) } } else { cmh_items.push(*meta); } } - return {name: name, vers: vers, cmh_items: cmh_items}; + + ProvidedMetas { + name: name, + vers: vers, + cmh_items: cmh_items + } } // This calculates CMH as defined above fn crate_meta_extras_hash(symbol_hasher: &hash::State, -cmh_items: ~[@ast::meta_item], dep_hashes: ~[~str]) -> @str { - fn len_and_str(s: ~str) -> ~str { - return fmt!("%u_%s", str::len(s), s); + fn len_and_str(s: &str) -> ~str { + fmt!("%u_%s", s.len(), s) } fn len_and_str_lit(l: ast::lit) -> ~str { - return len_and_str(pprust::lit_to_str(@l)); + len_and_str(pprust::lit_to_str(@l)) } let cmh_items = attr::sort_meta_items(cmh_items); - symbol_hasher.reset(); - for cmh_items.each |m| { + fn hash(symbol_hasher: &hash::State, m: &@ast::meta_item) { match m.node { - ast::meta_name_value(ref key, value) => { - symbol_hasher.write_str(len_and_str((*key))); + ast::meta_name_value(key, value) => { + symbol_hasher.write_str(len_and_str(*key)); symbol_hasher.write_str(len_and_str_lit(value)); } - ast::meta_word(ref name) => { - symbol_hasher.write_str(len_and_str((*name))); + ast::meta_word(name) => { + symbol_hasher.write_str(len_and_str(*name)); } - ast::meta_list(_, _) => { - // FIXME (#607): Implement this - fail!(~"unimplemented meta_item variant"); + ast::meta_list(name, ref mis) => { + symbol_hasher.write_str(len_and_str(*name)); + for mis.each |m_| { + hash(symbol_hasher, m_); + } } } } + symbol_hasher.reset(); + for cmh_items.each |m| { + hash(symbol_hasher, m); + } + for dep_hashes.each |dh| { symbol_hasher.write_str(len_and_str(*dh)); } @@ -557,16 +569,23 @@ pub fn build_link_meta(sess: Session, c: &ast::crate, output: &Path, }; } - let {name: opt_name, vers: opt_vers, - cmh_items: cmh_items} = provided_link_metas(sess, c); - let name = crate_meta_name(sess, output, move opt_name); - let vers = crate_meta_vers(sess, move opt_vers); + let ProvidedMetas { + name: opt_name, + vers: opt_vers, + cmh_items: cmh_items + } = provided_link_metas(sess, c); + let name = crate_meta_name(sess, output, opt_name); + let vers = crate_meta_vers(sess, opt_vers); let dep_hashes = cstore::get_dep_hashes(sess.cstore); let extras_hash = - crate_meta_extras_hash(symbol_hasher, move cmh_items, + crate_meta_extras_hash(symbol_hasher, cmh_items, dep_hashes); - return {name: name, vers: vers, extras_hash: extras_hash}; + LinkMeta { + name: name, + vers: vers, + extras_hash: extras_hash + } } pub fn truncated_hash_result(symbol_hasher: &hash::State) -> ~str { @@ -578,7 +597,7 @@ pub fn truncated_hash_result(symbol_hasher: &hash::State) -> ~str { // This calculates STH for a symbol, as defined above pub fn symbol_hash(tcx: ty::ctxt, symbol_hasher: &hash::State, t: ty::t, - link_meta: link_meta) -> @str { + link_meta: LinkMeta) -> @str { // NB: do *not* use abbrevs here as we want the symbol names // to be independent of one another in the crate. @@ -595,7 +614,7 @@ pub fn symbol_hash(tcx: ty::ctxt, symbol_hasher: &hash::State, t: ty::t, hash.to_managed() } -pub fn get_symbol_hash(ccx: @crate_ctxt, t: ty::t) -> @str { +pub fn get_symbol_hash(ccx: @CrateContext, t: ty::t) -> @str { match ccx.type_hashcodes.find(&t) { Some(h) => h, None => { @@ -609,7 +628,7 @@ pub fn get_symbol_hash(ccx: @crate_ctxt, t: ty::t) -> @str { // Name sanitation. LLVM will happily accept identifiers with weird names, but // gas doesn't! -pub fn sanitize(s: ~str) -> ~str { +pub fn sanitize(s: &str) -> ~str { let mut result = ~""; for str::chars_each(s) |c| { match c { @@ -623,10 +642,10 @@ pub fn sanitize(s: ~str) -> ~str { 'a' .. 'z' | 'A' .. 'Z' | '0' .. '9' - | '_' => str::push_char(&mut result, c), + | '_' => result.push_char(c), _ => { if c > 'z' && char::is_XID_continue(c) { - str::push_char(&mut result, c); + result.push_char(c); } } } @@ -649,7 +668,7 @@ pub fn mangle(sess: Session, ss: path) -> ~str { for ss.each |s| { match *s { path_name(s) | path_mod(s) => { - let sani = sanitize(sess.str_of(s)); + let sani = sanitize(*sess.str_of(s)); n += fmt!("%u%s", str::len(sani), sani); } } } @@ -667,14 +686,16 @@ pub fn exported_name(sess: Session, path_name(sess.ident_of(vers.to_owned())))); } -pub fn mangle_exported_name(ccx: @crate_ctxt, +path: path, t: ty::t) -> ~str { +pub fn mangle_exported_name(ccx: @CrateContext, + +path: path, + t: ty::t) -> ~str { let hash = get_symbol_hash(ccx, t); return exported_name(ccx.sess, path, hash, ccx.link_meta.vers); } -pub fn mangle_internal_name_by_type_only(ccx: @crate_ctxt, +pub fn mangle_internal_name_by_type_only(ccx: @CrateContext, t: ty::t, name: &str) -> ~str { let s = ppaux::ty_to_short_str(ccx.tcx, t); @@ -685,23 +706,23 @@ pub fn mangle_internal_name_by_type_only(ccx: @crate_ctxt, path_name(ccx.sess.ident_of(hash.to_owned()))]); } -pub fn mangle_internal_name_by_path_and_seq(ccx: @crate_ctxt, +pub fn mangle_internal_name_by_path_and_seq(ccx: @CrateContext, +path: path, +flav: ~str) -> ~str { return mangle(ccx.sess, vec::append_one(path, path_name((ccx.names)(flav)))); } -pub fn mangle_internal_name_by_path(ccx: @crate_ctxt, +path: path) -> ~str { +pub fn mangle_internal_name_by_path(ccx: @CrateContext, +path: path) -> ~str { return mangle(ccx.sess, path); } -pub fn mangle_internal_name_by_seq(ccx: @crate_ctxt, +flav: ~str) -> ~str { +pub fn mangle_internal_name_by_seq(ccx: @CrateContext, +flav: ~str) -> ~str { return fmt!("%s_%u", flav, (ccx.names)(flav).repr); } -pub fn output_dll_filename(os: session::os, lm: link_meta) -> ~str { +pub fn output_dll_filename(os: session::os, lm: LinkMeta) -> ~str { let libname = fmt!("%s-%s-%s", lm.name, lm.extras_hash, lm.vers); let (dll_prefix, dll_suffix) = match os { session::os_win32 => (win32::DLL_PREFIX, win32::DLL_SUFFIX), @@ -719,7 +740,7 @@ pub fn output_dll_filename(os: session::os, lm: link_meta) -> ~str { pub fn link_binary(sess: Session, obj_filename: &Path, out_filename: &Path, - lm: link_meta) { + lm: LinkMeta) { // Converts a library file-stem into a cc -l argument fn unlib(config: @session::config, +stem: ~str) -> ~str { if stem.starts_with("lib") && diff --git a/src/librustc/back/rpath.rs b/src/librustc/back/rpath.rs index 18e89635ab298..1bcd67bd67b53 100644 --- a/src/librustc/back/rpath.rs +++ b/src/librustc/back/rpath.rs @@ -157,7 +157,7 @@ pub fn get_relative_to(abs1: &Path, abs2: &Path) -> Path { let mut path = ~[]; for uint::range(start_idx, len1 - 1) |_i| { path.push(~".."); }; - path.push_all(vec::view(split2, start_idx, len2 - 1)); + path.push_all(vec::slice(split2, start_idx, len2 - 1)); if !path.is_empty() { return Path("").push_many(path); diff --git a/src/librustc/back/target_strs.rs b/src/librustc/back/target_strs.rs index da7e1056982cc..7baaac4fc9537 100644 --- a/src/librustc/back/target_strs.rs +++ b/src/librustc/back/target_strs.rs @@ -9,10 +9,10 @@ // except according to those terms. -pub type t = { +pub struct t { module_asm: ~str, meta_sect_name: ~str, data_layout: ~str, target_triple: ~str, cc_args: ~[~str] -}; +} diff --git a/src/librustc/back/upcall.rs b/src/librustc/back/upcall.rs index aa1189bb1143a..d9c4b27298ea8 100644 --- a/src/librustc/back/upcall.rs +++ b/src/librustc/back/upcall.rs @@ -15,17 +15,18 @@ use middle::trans::common::{T_fn, T_i1, T_i8, T_i32, T_int, T_nil, T_opaque_vec, T_ptr, T_unique_ptr, T_size_t, T_void, T_vec2}; -use lib::llvm::{type_names, ModuleRef, ValueRef, TypeRef}; +use lib::llvm::{TypeNames, ModuleRef, ValueRef, TypeRef}; -pub type upcalls = - {trace: ValueRef, - call_shim_on_c_stack: ValueRef, - call_shim_on_rust_stack: ValueRef, - rust_personality: ValueRef, - reset_stack_limit: ValueRef}; +pub struct Upcalls { + trace: ValueRef, + call_shim_on_c_stack: ValueRef, + call_shim_on_rust_stack: ValueRef, + rust_personality: ValueRef, + reset_stack_limit: ValueRef +} pub fn declare_upcalls(targ_cfg: @session::config, - llmod: ModuleRef) -> @upcalls { + llmod: ModuleRef) -> @Upcalls { fn decl(llmod: ModuleRef, prefix: ~str, name: ~str, tys: ~[TypeRef], rv: TypeRef) -> ValueRef { @@ -43,22 +44,23 @@ pub fn declare_upcalls(targ_cfg: @session::config, let int_t = T_int(targ_cfg); - return @{trace: dv(~"trace", ~[T_ptr(T_i8()), + @Upcalls { + trace: dv(~"trace", ~[T_ptr(T_i8()), T_ptr(T_i8()), int_t]), - call_shim_on_c_stack: - d(~"call_shim_on_c_stack", - // arguments: void *args, void *fn_ptr - ~[T_ptr(T_i8()), T_ptr(T_i8())], - int_t), - call_shim_on_rust_stack: - d(~"call_shim_on_rust_stack", - ~[T_ptr(T_i8()), T_ptr(T_i8())], int_t), - rust_personality: - nothrow(d(~"rust_personality", ~[], T_i32())), - reset_stack_limit: - nothrow(dv(~"reset_stack_limit", ~[])) - }; + call_shim_on_c_stack: + d(~"call_shim_on_c_stack", + // arguments: void *args, void *fn_ptr + ~[T_ptr(T_i8()), T_ptr(T_i8())], + int_t), + call_shim_on_rust_stack: + d(~"call_shim_on_rust_stack", + ~[T_ptr(T_i8()), T_ptr(T_i8())], int_t), + rust_personality: + nothrow(d(~"rust_personality", ~[], T_i32())), + reset_stack_limit: + nothrow(dv(~"reset_stack_limit", ~[])) + } } // // Local Variables: diff --git a/src/librustc/back/x86.rs b/src/librustc/back/x86.rs index 19cce9bf61999..a768edcc00bb9 100644 --- a/src/librustc/back/x86.rs +++ b/src/librustc/back/x86.rs @@ -15,7 +15,7 @@ use metadata::loader::meta_section_name; use session::sess_os_to_meta_os; pub fn get_target_strs(target_os: session::os) -> target_strs::t { - return { + return target_strs::t { module_asm: ~"", meta_sect_name: meta_section_name(sess_os_to_meta_os(target_os)), diff --git a/src/librustc/back/x86_64.rs b/src/librustc/back/x86_64.rs index f3a400506964b..dc48831375960 100644 --- a/src/librustc/back/x86_64.rs +++ b/src/librustc/back/x86_64.rs @@ -15,7 +15,7 @@ use metadata::loader::meta_section_name; use session::sess_os_to_meta_os; pub fn get_target_strs(target_os: session::os) -> target_strs::t { - return { + return target_strs::t { module_asm: ~"", meta_sect_name: meta_section_name(sess_os_to_meta_os(target_os)), diff --git a/src/librustc/driver/driver.rs b/src/librustc/driver/driver.rs index b0024bace37e0..45bbe5d091e06 100644 --- a/src/librustc/driver/driver.rs +++ b/src/librustc/driver/driver.rs @@ -62,7 +62,7 @@ pub fn anon_src() -> ~str { ~"" } pub fn source_name(input: input) -> ~str { match input { - file_input(ref ifile) => (*ifile).to_str(), + file_input(ref ifile) => ifile.to_str(), str_input(_) => anon_src() } } @@ -88,30 +88,33 @@ pub fn default_configuration(sess: Session, +argv0: ~str, input: input) -> let mk = attr::mk_name_value_item_str; - let (arch,wordsz) = match sess.targ_cfg.arch { - session::arch_x86 => (~"x86",~"32"), - session::arch_x86_64 => (~"x86_64",~"64"), - session::arch_arm => (~"arm",~"32") + // ARM is bi-endian, however using NDK seems to default + // to little-endian unless a flag is provided. + let (end,arch,wordsz) = match sess.targ_cfg.arch { + session::arch_x86 => (~"little",~"x86",~"32"), + session::arch_x86_64 => (~"little",~"x86_64",~"64"), + session::arch_arm => (~"little",~"arm",~"32") }; return ~[ // Target bindings. - attr::mk_word_item(str::from_slice(os::FAMILY)), - mk(~"target_os", tos), - mk(~"target_family", str::from_slice(os::FAMILY)), - mk(~"target_arch", arch), - mk(~"target_word_size", wordsz), - mk(~"target_libc", libc), + attr::mk_word_item(@str::from_slice(os::FAMILY)), + mk(@~"target_os", @tos), + mk(@~"target_family", @str::from_slice(os::FAMILY)), + mk(@~"target_arch", @arch), + mk(@~"target_endian", @end), + mk(@~"target_word_size", @wordsz), + mk(@~"target_libc", @libc), // Build bindings. - mk(~"build_compiler", argv0), - mk(~"build_input", source_name(input))]; + mk(@~"build_compiler", @argv0), + mk(@~"build_input", @source_name(input))]; } pub fn append_configuration(+cfg: ast::crate_cfg, +name: ~str) -> ast::crate_cfg { if attr::contains_name(cfg, name) { - return cfg; + cfg } else { - return vec::append_one(cfg, attr::mk_word_item(name)); + vec::append_one(cfg, attr::mk_word_item(@name)) } } @@ -139,7 +142,7 @@ pub fn parse_cfgspecs(cfgspecs: ~[~str]) -> ast::crate_cfg { // meta_word variant. let mut words = ~[]; for cfgspecs.each |s| { - words.push(attr::mk_word_item(/*bad*/copy *s)); + words.push(attr::mk_word_item(@/*bad*/copy *s)); } return words; } @@ -172,9 +175,10 @@ pub fn time(do_it: bool, what: ~str, thunk: fn() -> T) -> T { let end = std::time::precise_time_s(); io::stdout().write_str(fmt!("time: %3.3f s\t%s\n", end - start, what)); - move rv + rv } +#[deriving_eq] pub enum compile_upto { cu_parse, cu_expand, @@ -183,21 +187,14 @@ pub enum compile_upto { cu_everything, } -pub impl compile_upto : cmp::Eq { - pure fn eq(&self, other: &compile_upto) -> bool { - ((*self) as uint) == ((*other) as uint) - } - pure fn ne(&self, other: &compile_upto) -> bool { !(*self).eq(other) } -} - -pub fn compile_upto(sess: Session, cfg: ast::crate_cfg, - input: input, upto: compile_upto, - outputs: Option) - -> {crate: @ast::crate, tcx: Option} { +// For continuing compilation after a parsed crate has been +// modified +pub fn compile_rest(sess: Session, cfg: ast::crate_cfg, + upto: compile_upto, outputs: Option<@OutputFilenames>, + curr: Option<@ast::crate>) + -> (@ast::crate, Option) { let time_passes = sess.time_passes(); - let mut crate = time(time_passes, ~"parsing", - || parse_input(sess, copy cfg, input) ); - if upto == cu_parse { return {crate: crate, tcx: None}; } + let mut crate = curr.get(); *sess.building_library = session::building_library( sess.opts.crate_type, crate, sess.opts.test); @@ -212,7 +209,7 @@ pub fn compile_upto(sess: Session, cfg: ast::crate_cfg, syntax::ext::expand::expand_crate(sess.parse_sess, copy cfg, crate)); - if upto == cu_expand { return {crate: crate, tcx: None}; } + if upto == cu_expand { return (crate, None); } crate = time(time_passes, ~"intrinsic injection", || front::intrinsic_inject::inject_intrinsic(sess, crate)); @@ -230,15 +227,17 @@ pub fn compile_upto(sess: Session, cfg: ast::crate_cfg, creader::read_crates(sess.diagnostic(), *crate, sess.cstore, sess.filesearch, session::sess_os_to_meta_os(sess.targ_cfg.os), - sess.opts.static, + sess.opts.is_static, sess.parse_sess.interner)); let lang_items = time(time_passes, ~"language item collection", || middle::lang_items::collect_language_items(crate, sess)); - let { def_map: def_map, - exp_map2: exp_map2, - trait_map: trait_map } = + let middle::resolve::CrateMap { + def_map: def_map, + exp_map2: exp_map2, + trait_map: trait_map + } = time(time_passes, ~"resolution", || middle::resolve::resolve_crate(sess, lang_items, crate)); @@ -257,7 +256,7 @@ pub fn compile_upto(sess: Session, cfg: ast::crate_cfg, let (llmod, link_meta) = { let ty_cx = ty::mk_ctxt(sess, def_map, ast_map, freevars, - region_map, rp_set, move lang_items, crate); + region_map, rp_set, lang_items, crate); let (method_map, vtable_map) = time(time_passes, ~"typechecking", || @@ -273,7 +272,7 @@ pub fn compile_upto(sess: Session, cfg: ast::crate_cfg, middle::check_const::check_crate(sess, crate, ast_map, def_map, method_map, ty_cx)); - if upto == cu_typeck { return {crate: crate, tcx: Some(ty_cx)}; } + if upto == cu_typeck { return (crate, Some(ty_cx)); } time(time_passes, ~"privacy checking", || middle::privacy::check_crate(ty_cx, &method_map, crate)); @@ -308,7 +307,7 @@ pub fn compile_upto(sess: Session, cfg: ast::crate_cfg, time(time_passes, ~"lint checking", || lint::check_crate(ty_cx, crate)); - if upto == cu_no_trans { return {crate: crate, tcx: Some(ty_cx)}; } + if upto == cu_no_trans { return (crate, Some(ty_cx)); } let maps = astencode::Maps { mutbl_map: mutbl_map, @@ -328,29 +327,39 @@ pub fn compile_upto(sess: Session, cfg: ast::crate_cfg, }; - time(time_passes, ~"LLVM passes", || link::write::run_passes(sess, llmod, &outputs.obj_filename)); let stop_after_codegen = sess.opts.output_type != link::output_type_exe || - (sess.opts.static && *sess.building_library) || + (sess.opts.is_static && *sess.building_library) || sess.opts.jit; - if stop_after_codegen { return {crate: crate, tcx: None}; } + if stop_after_codegen { return (crate, None); } time(time_passes, ~"linking", || link::link_binary(sess, &outputs.obj_filename, &outputs.out_filename, link_meta)); - return {crate: crate, tcx: None}; + return (crate, None); +} + +pub fn compile_upto(sess: Session, +cfg: ast::crate_cfg, + input: input, upto: compile_upto, + outputs: Option<@OutputFilenames>) + -> (@ast::crate, Option) { + let time_passes = sess.time_passes(); + let mut crate = time(time_passes, ~"parsing", + || parse_input(sess, copy cfg, input) ); + if upto == cu_parse { return (crate, None); } + + compile_rest(sess, cfg, upto, outputs, Some(crate)) } pub fn compile_input(sess: Session, +cfg: ast::crate_cfg, input: input, outdir: &Option, output: &Option) { - let upto = if sess.opts.parse_only { cu_parse } else if sess.opts.no_trans { cu_no_trans } else { cu_everything }; @@ -410,7 +419,7 @@ pub fn pretty_print_input(sess: Session, +cfg: ast::crate_cfg, input: input, ppm_typed => cu_typeck, _ => cu_parse }; - let {crate, tcx} = compile_upto(sess, cfg, input, upto, None); + let (crate, tcx) = compile_upto(sess, cfg, input, upto, None); let ann = match ppm { ppm_typed => { @@ -487,9 +496,14 @@ pub fn build_target_config(sopts: @session::options, session::arch_x86_64 => x86_64::get_target_strs(os), session::arch_arm => arm::get_target_strs(os) }; - let target_cfg: @session::config = - @{os: os, arch: arch, target_strs: target_strs, int_type: int_type, - uint_type: uint_type, float_type: float_type}; + let target_cfg = @session::config { + os: os, + arch: arch, + target_strs: target_strs, + int_type: int_type, + uint_type: uint_type, + float_type: float_type + }; return target_cfg; } @@ -534,11 +548,11 @@ pub fn build_session_options(+binary: ~str, let flags = vec::append(getopts::opt_strs(matches, level_short), getopts::opt_strs(matches, level_name)); for flags.each |lint_name| { - let lint_name = str::replace(*lint_name, ~"-", ~"_"); + let lint_name = @str::replace(*lint_name, ~"-", ~"_"); match lint_dict.find(&lint_name) { None => { early_error(demitter, fmt!("unknown %s flag: %s", - level_name, lint_name)); + level_name, *lint_name)); } Some(lint) => { lint_opts.push((lint.lint, *level)); @@ -627,26 +641,27 @@ pub fn build_session_options(+binary: ~str, .map(|s| Path(*s)); let cfg = parse_cfgspecs(getopts::opt_strs(matches, ~"cfg")); let test = opt_present(matches, ~"test"); - let sopts: @session::options = - @{crate_type: crate_type, - static: static, - gc: gc, - optimize: opt_level, - debuginfo: debuginfo, - extra_debuginfo: extra_debuginfo, - lint_opts: lint_opts, - save_temps: save_temps, - jit: jit, - output_type: output_type, - addl_lib_search_paths: addl_lib_search_paths, - maybe_sysroot: sysroot_opt, - target_triple: target, - cfg: cfg, - binary: binary, - test: test, - parse_only: parse_only, - no_trans: no_trans, - debugging_opts: debugging_opts}; + let sopts = @session::options { + crate_type: crate_type, + is_static: static, + gc: gc, + optimize: opt_level, + debuginfo: debuginfo, + extra_debuginfo: extra_debuginfo, + lint_opts: lint_opts, + save_temps: save_temps, + jit: jit, + output_type: output_type, + addl_lib_search_paths: addl_lib_search_paths, + maybe_sysroot: sysroot_opt, + target_triple: target, + cfg: cfg, + binary: binary, + test: test, + parse_only: parse_only, + no_trans: no_trans, + debugging_opts: debugging_opts + }; return sopts; } @@ -763,19 +778,22 @@ pub fn optgroups() -> ~[getopts::groups::OptGroup] { ] } -pub type output_filenames = @{out_filename:Path, obj_filename:Path}; +pub struct OutputFilenames { + out_filename: Path, + obj_filename: Path +} pub fn build_output_filenames(input: input, odir: &Option, ofile: &Option, sess: Session) - -> output_filenames { + -> @OutputFilenames { let obj_path; let out_path; let sopts = sess.opts; let stop_after_codegen = sopts.output_type != link::output_type_exe || - sopts.static && *sess.building_library; + sopts.is_static && *sess.building_library; let obj_suffix = @@ -835,8 +853,11 @@ pub fn build_output_filenames(input: input, } } } - return @{out_filename: out_path, - obj_filename: obj_path}; + + @OutputFilenames { + out_filename: out_path, + obj_filename: obj_path + } } pub fn early_error(emitter: diagnostic::Emitter, msg: ~str) -> ! { diff --git a/src/librustc/driver/session.rs b/src/librustc/driver/session.rs index cb55051c57f09..bd35bf50cefc0 100644 --- a/src/librustc/driver/session.rs +++ b/src/librustc/driver/session.rs @@ -25,37 +25,26 @@ use syntax::ast::node_id; use syntax::ast::{int_ty, uint_ty, float_ty}; use syntax::codemap::span; use syntax::diagnostic; -use syntax::parse::parse_sess; +use syntax::parse::ParseSess; use syntax::{ast, codemap}; use syntax; +#[deriving_eq] pub enum os { os_win32, os_macos, os_linux, os_android, os_freebsd, } -pub impl os : cmp::Eq { - pure fn eq(&self, other: &os) -> bool { - ((*self) as uint) == ((*other) as uint) - } - pure fn ne(&self, other: &os) -> bool { !(*self).eq(other) } -} - +#[deriving_eq] pub enum arch { arch_x86, arch_x86_64, arch_arm, } -pub impl arch : cmp::Eq { - pure fn eq(&self, other: &arch) -> bool { - ((*self) as uint) == ((*other) as uint) - } - pure fn ne(&self, other: &arch) -> bool { !(*self).eq(other) } -} - pub enum crate_type { bin_crate, lib_crate, unknown_crate, } -pub type config = - {os: os, - arch: arch, - target_strs: target_strs::t, - int_type: int_ty, - uint_type: uint_ty, - float_type: float_ty}; +pub struct config { + os: os, + arch: arch, + target_strs: target_strs::t, + int_type: int_ty, + uint_type: uint_ty, + float_type: float_ty +} pub const verbose: uint = 1 << 0; pub const time_passes: uint = 1 << 1; @@ -117,6 +106,7 @@ pub fn debugging_opts_map() -> ~[(~str, ~str, uint)] { ] } +#[deriving_eq] pub enum OptLevel { No, // -O0 Less, // -O1 @@ -124,48 +114,44 @@ pub enum OptLevel { Aggressive // -O3 } -pub impl OptLevel : cmp::Eq { - pure fn eq(&self, other: &OptLevel) -> bool { - ((*self) as uint) == ((*other) as uint) - } - pure fn ne(&self, other: &OptLevel) -> bool { !(*self).eq(other) } -} - -pub type options = +pub struct options { // The crate config requested for the session, which may be combined // with additional crate configurations during the compile process - {crate_type: crate_type, - static: bool, - gc: bool, - optimize: OptLevel, - debuginfo: bool, - extra_debuginfo: bool, - lint_opts: ~[(lint::lint, lint::level)], - save_temps: bool, - jit: bool, - output_type: back::link::output_type, - addl_lib_search_paths: ~[Path], - maybe_sysroot: Option, - target_triple: ~str, - // User-specified cfg meta items. The compiler itself will add additional - // items to the crate config, and during parsing the entire crate config - // will be added to the crate AST node. This should not be used for - // anything except building the full crate config prior to parsing. - cfg: ast::crate_cfg, - binary: ~str, - test: bool, - parse_only: bool, - no_trans: bool, - debugging_opts: uint, - }; - -pub type crate_metadata = {name: ~str, data: ~[u8]}; + crate_type: crate_type, + is_static: bool, + gc: bool, + optimize: OptLevel, + debuginfo: bool, + extra_debuginfo: bool, + lint_opts: ~[(lint::lint, lint::level)], + save_temps: bool, + jit: bool, + output_type: back::link::output_type, + addl_lib_search_paths: ~[Path], + maybe_sysroot: Option, + target_triple: ~str, + // User-specified cfg meta items. The compiler itself will add additional + // items to the crate config, and during parsing the entire crate config + // will be added to the crate AST node. This should not be used for + // anything except building the full crate config prior to parsing. + cfg: ast::crate_cfg, + binary: ~str, + test: bool, + parse_only: bool, + no_trans: bool, + debugging_opts: uint, +} + +pub struct crate_metadata { + name: ~str, + data: ~[u8] +} pub struct Session_ { targ_cfg: @config, opts: @options, cstore: @mut metadata::cstore::CStore, - parse_sess: parse_sess, + parse_sess: @mut ParseSess, codemap: @codemap::CodeMap, // For a library crate, this is always none main_fn: @mut Option<(node_id, codemap::span)>, @@ -173,55 +159,55 @@ pub struct Session_ { filesearch: filesearch::FileSearch, building_library: @mut bool, working_dir: Path, - lint_settings: lint::lint_settings + lint_settings: lint::LintSettings } pub type Session = @Session_; pub impl Session { - fn span_fatal(sp: span, msg: ~str) -> ! { + fn span_fatal(&self, sp: span, msg: ~str) -> ! { self.span_diagnostic.span_fatal(sp, msg) } - fn fatal(msg: ~str) -> ! { + fn fatal(&self, msg: ~str) -> ! { self.span_diagnostic.handler().fatal(msg) } - fn span_err(sp: span, msg: ~str) { + fn span_err(&self, sp: span, msg: ~str) { self.span_diagnostic.span_err(sp, msg) } - fn err(msg: ~str) { + fn err(&self, msg: ~str) { self.span_diagnostic.handler().err(msg) } - fn has_errors() -> bool { + fn has_errors(&self) -> bool { self.span_diagnostic.handler().has_errors() } - fn abort_if_errors() { + fn abort_if_errors(&self) { self.span_diagnostic.handler().abort_if_errors() } - fn span_warn(sp: span, msg: ~str) { + fn span_warn(&self, sp: span, msg: ~str) { self.span_diagnostic.span_warn(sp, msg) } - fn warn(msg: ~str) { + fn warn(&self, msg: ~str) { self.span_diagnostic.handler().warn(msg) } - fn span_note(sp: span, msg: ~str) { + fn span_note(&self, sp: span, msg: ~str) { self.span_diagnostic.span_note(sp, msg) } - fn note(msg: ~str) { + fn note(&self, msg: ~str) { self.span_diagnostic.handler().note(msg) } - fn span_bug(sp: span, msg: ~str) -> ! { + fn span_bug(&self, sp: span, msg: ~str) -> ! { self.span_diagnostic.span_bug(sp, msg) } - fn bug(msg: ~str) -> ! { + fn bug(&self, msg: ~str) -> ! { self.span_diagnostic.handler().bug(msg) } - fn span_unimpl(sp: span, msg: ~str) -> ! { + fn span_unimpl(&self, sp: span, msg: ~str) -> ! { self.span_diagnostic.span_unimpl(sp, msg) } - fn unimpl(msg: ~str) -> ! { + fn unimpl(&self, msg: ~str) -> ! { self.span_diagnostic.handler().unimpl(msg) } - fn span_lint_level(level: lint::level, sp: span, +msg: ~str) { + fn span_lint_level(&self, level: lint::level, sp: span, +msg: ~str) { match level { lint::allow => { }, lint::warn => self.span_warn(sp, msg), @@ -230,7 +216,7 @@ pub impl Session { } } } - fn span_lint(lint_mode: lint::lint, + fn span_lint(&self, lint_mode: lint::lint, expr_id: ast::node_id, item_id: ast::node_id, span: span, @@ -239,54 +225,64 @@ pub impl Session { self.lint_settings, lint_mode, expr_id, item_id); self.span_lint_level(level, span, msg); } - fn next_node_id() -> ast::node_id { + fn next_node_id(&self) -> ast::node_id { return syntax::parse::next_node_id(self.parse_sess); } - fn diagnostic() -> diagnostic::span_handler { + fn diagnostic(&self) -> diagnostic::span_handler { self.span_diagnostic } - fn debugging_opt(opt: uint) -> bool { + fn debugging_opt(&self, opt: uint) -> bool { (self.opts.debugging_opts & opt) != 0u } // This exists to help with refactoring to eliminate impossible // cases later on - fn impossible_case(sp: span, msg: &str) -> ! { + fn impossible_case(&self, sp: span, msg: &str) -> ! { self.span_bug(sp, fmt!("Impossible case reached: %s", msg)); } - fn verbose() -> bool { self.debugging_opt(verbose) } - fn time_passes() -> bool { self.debugging_opt(time_passes) } - fn count_llvm_insns() -> bool { self.debugging_opt(count_llvm_insns) } - fn count_type_sizes() -> bool { self.debugging_opt(count_type_sizes) } - fn time_llvm_passes() -> bool { self.debugging_opt(time_llvm_passes) } - fn trans_stats() -> bool { self.debugging_opt(trans_stats) } - fn meta_stats() -> bool { self.debugging_opt(meta_stats) } - fn no_asm_comments() -> bool { self.debugging_opt(no_asm_comments) } - fn no_verify() -> bool { self.debugging_opt(no_verify) } - fn trace() -> bool { self.debugging_opt(trace) } - fn coherence() -> bool { self.debugging_opt(coherence) } - fn borrowck_stats() -> bool { self.debugging_opt(borrowck_stats) } - fn borrowck_note_pure() -> bool { self.debugging_opt(borrowck_note_pure) } - fn borrowck_note_loan() -> bool { self.debugging_opt(borrowck_note_loan) } - fn no_monomorphic_collapse() -> bool { + fn verbose(&self) -> bool { self.debugging_opt(verbose) } + fn time_passes(&self) -> bool { self.debugging_opt(time_passes) } + fn count_llvm_insns(&self) -> bool { + self.debugging_opt(count_llvm_insns) + } + fn count_type_sizes(&self) -> bool { + self.debugging_opt(count_type_sizes) + } + fn time_llvm_passes(&self) -> bool { + self.debugging_opt(time_llvm_passes) + } + fn trans_stats(&self) -> bool { self.debugging_opt(trans_stats) } + fn meta_stats(&self) -> bool { self.debugging_opt(meta_stats) } + fn no_asm_comments(&self) -> bool { self.debugging_opt(no_asm_comments) } + fn no_verify(&self) -> bool { self.debugging_opt(no_verify) } + fn trace(&self) -> bool { self.debugging_opt(trace) } + fn coherence(&self) -> bool { self.debugging_opt(coherence) } + fn borrowck_stats(&self) -> bool { self.debugging_opt(borrowck_stats) } + fn borrowck_note_pure(&self) -> bool { + self.debugging_opt(borrowck_note_pure) + } + fn borrowck_note_loan(&self) -> bool { + self.debugging_opt(borrowck_note_loan) + } + fn no_monomorphic_collapse(&self) -> bool { self.debugging_opt(no_monomorphic_collapse) } - fn str_of(id: ast::ident) -> ~str { - /*bad*/copy *self.parse_sess.interner.get(id) + fn str_of(&self, id: ast::ident) -> @~str { + self.parse_sess.interner.get(id) } - fn ident_of(+st: ~str) -> ast::ident { + fn ident_of(&self, +st: ~str) -> ast::ident { self.parse_sess.interner.intern(@st) } - fn intr() -> @syntax::parse::token::ident_interner { + fn intr(&self) -> @syntax::parse::token::ident_interner { self.parse_sess.interner } } /// Some reasonable defaults pub fn basic_options() -> @options { - @{ + @options { crate_type: session::lib_crate, - static: false, + is_static: false, gc: false, optimize: No, debuginfo: false, @@ -308,7 +304,7 @@ pub fn basic_options() -> @options { } // Seems out of place, but it uses session, so I'm putting it here -pub fn expect(sess: Session, +pub fn expect(sess: Session, opt: Option, msg: fn() -> ~str) -> T { @@ -328,7 +324,7 @@ pub fn building_library(req_crate_type: crate_type, match syntax::attr::first_attr_value_str_by_name( crate.node.attrs, ~"crate_type") { - option::Some(~"lib") => true, + Some(@~"lib") => true, _ => false } } @@ -364,7 +360,7 @@ pub mod test { style: ast::attr_outer, value: codemap::respan(codemap::dummy_sp(), ast::meta_name_value( - ~"crate_type", + @~"crate_type", codemap::respan(codemap::dummy_sp(), ast::lit_str(@t)))), is_sugared_doc: false diff --git a/src/librustc/front/config.rs b/src/librustc/front/config.rs index cf75db3a90014..afb73a6e7c35c 100644 --- a/src/librustc/front/config.rs +++ b/src/librustc/front/config.rs @@ -17,9 +17,9 @@ use core::vec; type in_cfg_pred = fn@(+attrs: ~[ast::attribute]) -> bool; -type ctxt = @{ +struct Context { in_cfg: in_cfg_pred -}; +} // Support conditional compilation by transforming the AST, stripping out // any items that do not belong in the current configuration @@ -32,7 +32,7 @@ pub fn strip_unconfigured_items(crate: @ast::crate) -> @ast::crate { pub fn strip_items(crate: @ast::crate, in_cfg: in_cfg_pred) -> @ast::crate { - let ctxt = @{in_cfg: in_cfg}; + let ctxt = @Context { in_cfg: in_cfg }; let precursor = @fold::AstFoldFns { fold_mod: |a,b| fold_mod(ctxt, a, b), @@ -49,12 +49,12 @@ pub fn strip_items(crate: @ast::crate, in_cfg: in_cfg_pred) return res; } -fn filter_item(cx: ctxt, &&item: @ast::item) -> +fn filter_item(cx: @Context, &&item: @ast::item) -> Option<@ast::item> { if item_in_cfg(cx, item) { option::Some(item) } else { option::None } } -fn filter_view_item(cx: ctxt, &&view_item: @ast::view_item +fn filter_view_item(cx: @Context, &&view_item: @ast::view_item )-> Option<@ast::view_item> { if view_item_in_cfg(cx, view_item) { option::Some(view_item) @@ -63,7 +63,7 @@ fn filter_view_item(cx: ctxt, &&view_item: @ast::view_item } } -fn fold_mod(cx: ctxt, m: ast::_mod, fld: fold::ast_fold) -> ast::_mod { +fn fold_mod(cx: @Context, m: ast::_mod, fld: fold::ast_fold) -> ast::_mod { let filtered_items = m.items.filter_mapped(|a| filter_item(cx, *a)); let filtered_view_items = @@ -74,7 +74,7 @@ fn fold_mod(cx: ctxt, m: ast::_mod, fld: fold::ast_fold) -> ast::_mod { } } -fn filter_foreign_item(cx: ctxt, &&item: @ast::foreign_item) -> +fn filter_foreign_item(cx: @Context, &&item: @ast::foreign_item) -> Option<@ast::foreign_item> { if foreign_item_in_cfg(cx, item) { option::Some(item) @@ -82,7 +82,7 @@ fn filter_foreign_item(cx: ctxt, &&item: @ast::foreign_item) -> } fn fold_foreign_mod( - cx: ctxt, + cx: @Context, nm: ast::foreign_mod, fld: fold::ast_fold ) -> ast::foreign_mod { @@ -98,7 +98,7 @@ fn fold_foreign_mod( } } -fn fold_item_underscore(cx: ctxt, +item: ast::item_, +fn fold_item_underscore(cx: @Context, +item: ast::item_, fld: fold::ast_fold) -> ast::item_ { let item = match item { ast::item_impl(a, b, c, methods) => { @@ -115,7 +115,7 @@ fn fold_item_underscore(cx: ctxt, +item: ast::item_, fold::noop_fold_item_underscore(item, fld) } -fn filter_stmt(cx: ctxt, &&stmt: @ast::stmt) -> +fn filter_stmt(cx: @Context, &&stmt: @ast::stmt) -> Option<@ast::stmt> { match stmt.node { ast::stmt_decl(decl, _) => { @@ -133,7 +133,7 @@ fn filter_stmt(cx: ctxt, &&stmt: @ast::stmt) -> } fn fold_block( - cx: ctxt, + cx: @Context, b: ast::blk_, fld: fold::ast_fold ) -> ast::blk_ { @@ -148,23 +148,23 @@ fn fold_block( } } -fn item_in_cfg(cx: ctxt, item: @ast::item) -> bool { +fn item_in_cfg(cx: @Context, item: @ast::item) -> bool { return (cx.in_cfg)(/*bad*/copy item.attrs); } -fn foreign_item_in_cfg(cx: ctxt, item: @ast::foreign_item) -> bool { +fn foreign_item_in_cfg(cx: @Context, item: @ast::foreign_item) -> bool { return (cx.in_cfg)(/*bad*/copy item.attrs); } -fn view_item_in_cfg(cx: ctxt, item: @ast::view_item) -> bool { +fn view_item_in_cfg(cx: @Context, item: @ast::view_item) -> bool { return (cx.in_cfg)(/*bad*/copy item.attrs); } -fn method_in_cfg(cx: ctxt, meth: @ast::method) -> bool { +fn method_in_cfg(cx: @Context, meth: @ast::method) -> bool { return (cx.in_cfg)(/*bad*/copy meth.attrs); } -fn trait_method_in_cfg(cx: ctxt, meth: &ast::trait_method) -> bool { +fn trait_method_in_cfg(cx: @Context, meth: &ast::trait_method) -> bool { match *meth { ast::required(ref meth) => (cx.in_cfg)(/*bad*/copy meth.attrs), ast::provided(@ref meth) => (cx.in_cfg)(/*bad*/copy meth.attrs) diff --git a/src/librustc/front/core_inject.rs b/src/librustc/front/core_inject.rs index 143eb556f96de..51b25854bc751 100644 --- a/src/librustc/front/core_inject.rs +++ b/src/librustc/front/core_inject.rs @@ -37,7 +37,7 @@ fn use_core(crate: @ast::crate) -> bool { fn inject_libcore_ref(sess: Session, crate: @ast::crate) -> @ast::crate { - fn spanned(x: T) -> codemap::spanned { + fn spanned(x: T) -> codemap::spanned { codemap::spanned { node: x, span: dummy_sp() } } @@ -45,12 +45,13 @@ fn inject_libcore_ref(sess: Session, fold_crate: |crate, span, fld| { let n1 = sess.next_node_id(); let vi1 = @ast::view_item { - node: ast::view_item_use(sess.ident_of(~"core"), ~[], n1), + node: ast::view_item_extern_mod( + sess.ident_of(~"core"), ~[], n1), attrs: ~[ spanned(ast::attribute_ { style: ast::attr_inner, value: spanned(ast::meta_name_value( - ~"vers", + @~"vers", spanned(ast::lit_str(@CORE_VERSION.to_str())) )), is_sugared_doc: false @@ -86,7 +87,7 @@ fn inject_libcore_ref(sess: Session, }; let vp = @spanned(ast::view_path_glob(prelude_path, n2)); - let vi2 = @ast::view_item { node: ast::view_item_import(~[vp]), + let vi2 = @ast::view_item { node: ast::view_item_use(~[vp]), attrs: ~[], vis: ast::private, span: dummy_sp() }; diff --git a/src/librustc/front/test.rs b/src/librustc/front/test.rs index caa2035389d63..f19b52661f210 100644 --- a/src/librustc/front/test.rs +++ b/src/librustc/front/test.rs @@ -21,7 +21,7 @@ use core::option; use core::vec; use syntax::ast_util::*; use syntax::attr; -use syntax::codemap::{dummy_sp, span, ExpandedFrom}; +use syntax::codemap::{dummy_sp, span, ExpandedFrom, CallInfo, NameAndSpan}; use syntax::codemap; use syntax::fold; use syntax::print::pprust; @@ -32,20 +32,20 @@ use syntax::ext::base::{mk_ctxt, ext_ctxt}; type node_id_gen = fn@() -> ast::node_id; -type test = { +struct Test { span: span, path: ~[ast::ident], bench: bool, ignore: bool, should_fail: bool -}; +} struct TestCtxt { sess: session::Session, crate: @ast::crate, path: ~[ast::ident], - ext_cx: ext_ctxt, - testfns: ~[test] + ext_cx: ext_ctxt, + testfns: ~[Test] } // Traverse the crate, collecting all the test functions, eliding any @@ -57,7 +57,7 @@ pub fn modify_for_testing(sess: session::Session, // configuration, either with the '--test' or '--cfg test' // command line options. let should_test = attr::contains(crate.node.config, - attr::mk_word_item(~"test")); + attr::mk_word_item(@~"test")); if should_test { generate_test_harness(sess, crate) @@ -77,9 +77,13 @@ fn generate_test_harness(sess: session::Session, testfns: ~[] }; - cx.ext_cx.bt_push(ExpandedFrom({call_site: dummy_sp(), - callie: {name: ~"test", - span: None}})); + cx.ext_cx.bt_push(ExpandedFrom(CallInfo { + call_site: dummy_sp(), + callee: NameAndSpan { + name: ~"test", + span: None + } + })); let precursor = @fold::AstFoldFns { fold_crate: fold::wrap(|a,b| fold_crate(cx, a, b) ), @@ -111,7 +115,7 @@ fn fold_mod(cx: @mut TestCtxt, fn nomain(cx: @mut TestCtxt, item: @ast::item) -> @ast::item { if !*cx.sess.building_library { @ast::item{attrs: item.attrs.filtered(|attr| { - attr::get_attr_name(*attr) != ~"main" + *attr::get_attr_name(attr) != ~"main" }),.. copy *item} } else { item } } @@ -153,11 +157,13 @@ fn fold_item(cx: @mut TestCtxt, &&i: @ast::item, fld: fold::ast_fold) } _ => { debug!("this is a test function"); - let test = {span: i.span, - path: /*bad*/copy cx.path, - bench: is_bench_fn(i), - ignore: is_ignored(cx, i), - should_fail: should_fail(i)}; + let test = Test { + span: i.span, + path: /*bad*/copy cx.path, + bench: is_bench_fn(i), + ignore: is_ignored(cx, i), + should_fail: should_fail(i) + }; cx.testfns.push(test); debug!("have %u test/bench functions", cx.testfns.len()); } @@ -262,17 +268,17 @@ mod __test { fn mk_std(cx: &TestCtxt) -> @ast::view_item { let vers = ast::lit_str(@~"0.6"); let vers = nospan(vers); - let mi = ast::meta_name_value(~"vers", vers); + let mi = ast::meta_name_value(@~"vers", vers); let mi = nospan(mi); let id_std = cx.sess.ident_of(~"std"); let vi = if is_std(cx) { - ast::view_item_import( + ast::view_item_use( ~[@nospan(ast::view_path_simple(id_std, path_node(~[id_std]), ast::type_value_ns, cx.sess.next_node_id()))]) } else { - ast::view_item_use(id_std, ~[@mi], + ast::view_item_extern_mod(id_std, ~[@mi], cx.sess.next_node_id()) }; let vi = ast::view_item { @@ -310,7 +316,7 @@ fn mk_test_module(cx: &TestCtxt) -> @ast::item { // This attribute tells resolve to let us call unexported functions let resolve_unexported_attr = - attr::mk_attr(attr::mk_word_item(~"!resolve_unexported")); + attr::mk_attr(attr::mk_word_item(@~"!resolve_unexported")); let item = ast::item { ident: cx.sess.ident_of(~"__test"), @@ -327,7 +333,7 @@ fn mk_test_module(cx: &TestCtxt) -> @ast::item { return @item; } -fn nospan(t: T) -> codemap::spanned { +fn nospan(t: T) -> codemap::spanned { codemap::spanned { node: t, span: dummy_sp() } } @@ -366,7 +372,7 @@ fn is_std(cx: &TestCtxt) -> bool { let is_std = { let items = attr::find_linkage_metas(cx.crate.node.attrs); match attr::last_meta_item_value_str_by_name(items, ~"name") { - Some(~"std") => true, + Some(@~"std") => true, _ => false } }; @@ -396,7 +402,7 @@ fn mk_test_descs(cx: &TestCtxt) -> @ast::expr { } } -fn mk_test_desc_and_fn_rec(cx: &TestCtxt, test: test) -> @ast::expr { +fn mk_test_desc_and_fn_rec(cx: &TestCtxt, test: Test) -> @ast::expr { let span = test.span; let path = /*bad*/copy test.path; diff --git a/src/librustc/lib/llvm.rs b/src/librustc/lib/llvm.rs index 4b63bb3721538..e42d3aeaf144c 100644 --- a/src/librustc/lib/llvm.rs +++ b/src/librustc/lib/llvm.rs @@ -132,6 +132,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] pub enum TypeKind { Void = 0, Half = 1, @@ -151,46 +152,6 @@ pub enum TypeKind { X86_MMX = 15 } -pub impl TypeKind : cmp::Eq { - pure fn eq(&self, other: &TypeKind) -> bool { - match ((*self), (*other)) { - (Void, Void) => true, - (Half, Half) => true, - (Float, Float) => true, - (Double, Double) => true, - (X86_FP80, X86_FP80) => true, - (FP128, FP128) => true, - (PPC_FP128, PPC_FP128) => true, - (Label, Label) => true, - (Integer, Integer) => true, - (Function, Function) => true, - (Struct, Struct) => true, - (Array, Array) => true, - (Pointer, Pointer) => true, - (Vector, Vector) => true, - (Metadata, Metadata) => true, - (X86_MMX, X86_MMX) => true, - (Void, _) => false, - (Half, _) => false, - (Float, _) => false, - (Double, _) => false, - (X86_FP80, _) => false, - (FP128, _) => false, - (PPC_FP128, _) => false, - (Label, _) => false, - (Integer, _) => false, - (Function, _) => false, - (Struct, _) => false, - (Array, _) => false, - (Pointer, _) => false, - (Vector, _) => false, - (Metadata, _) => false, - (X86_MMX, _) => false, - } - } - pure fn ne(&self, other: &TypeKind) -> bool { !(*self).eq(other) } -} - pub enum AtomicBinOp { Xchg = 0, Add = 1, @@ -223,6 +184,15 @@ pub enum FileType { ObjectFile = 1 } +pub enum Metadata { + MD_dbg = 0, + MD_tbaa = 1, + MD_prof = 2, + MD_fpmath = 3, + MD_range = 4, + MD_tbaa_struct = 5 +} + // Opaque pointer types pub enum Module_opaque {} pub type ModuleRef = *Module_opaque; @@ -1328,32 +1298,36 @@ pub fn SetLinkage(Global: ValueRef, Link: Linkage) { /* Memory-managed object interface to type handles. */ -pub type type_names = @{type_names: HashMap, - named_types: HashMap<@str, TypeRef>}; +pub struct TypeNames { + type_names: HashMap, + named_types: HashMap<@str, TypeRef> +} -pub fn associate_type(tn: type_names, s: @str, t: TypeRef) { +pub fn associate_type(tn: @TypeNames, s: @str, t: TypeRef) { assert tn.type_names.insert(t, s); assert tn.named_types.insert(s, t); } -pub fn type_has_name(tn: type_names, t: TypeRef) -> Option<@str> { +pub fn type_has_name(tn: @TypeNames, t: TypeRef) -> Option<@str> { return tn.type_names.find(&t); } -pub fn name_has_type(tn: type_names, s: @str) -> Option { +pub fn name_has_type(tn: @TypeNames, s: @str) -> Option { return tn.named_types.find(&s); } -pub fn mk_type_names() -> type_names { - @{type_names: HashMap(), - named_types: HashMap()} +pub fn mk_type_names() -> @TypeNames { + @TypeNames { + type_names: HashMap(), + named_types: HashMap() + } } -pub fn type_to_str(names: type_names, ty: TypeRef) -> @str { +pub fn type_to_str(names: @TypeNames, ty: TypeRef) -> @str { return type_to_str_inner(names, [], ty); } -pub fn type_to_str_inner(names: type_names, +outer0: &[TypeRef], ty: TypeRef) +pub fn type_to_str_inner(names: @TypeNames, +outer0: &[TypeRef], ty: TypeRef) -> @str { unsafe { match type_has_name(names, ty) { @@ -1365,7 +1339,7 @@ pub fn type_to_str_inner(names: type_names, +outer0: &[TypeRef], ty: TypeRef) let kind = llvm::LLVMGetTypeKind(ty); - fn tys_str(names: type_names, outer: &[TypeRef], + fn tys_str(names: @TypeNames, outer: &[TypeRef], tys: ~[TypeRef]) -> @str { let mut s = ~""; let mut first: bool = true; @@ -1481,7 +1455,7 @@ pub fn struct_element_types(struct_ty: TypeRef) -> ~[TypeRef] { llvm::LLVMGetStructElementTypes( struct_ty, ptr::to_mut_unsafe_ptr(&mut buf[0])); } - return move buf; + return buf; } } @@ -1503,14 +1477,21 @@ pub fn target_data_res(TD: TargetDataRef) -> target_data_res { } } -pub type target_data = {lltd: TargetDataRef, dtor: @target_data_res}; +pub struct TargetData { + lltd: TargetDataRef, + dtor: @target_data_res +} -pub fn mk_target_data(string_rep: ~str) -> target_data { +pub fn mk_target_data(string_rep: ~str) -> TargetData { let lltd = str::as_c_str(string_rep, |buf| unsafe { llvm::LLVMCreateTargetData(buf) }); - return {lltd: lltd, dtor: @target_data_res(lltd)}; + + TargetData { + lltd: lltd, + dtor: @target_data_res(lltd) + } } /* Memory-managed interface to pass managers. */ @@ -1530,12 +1511,19 @@ pub fn pass_manager_res(PM: PassManagerRef) -> pass_manager_res { } } -pub type pass_manager = {llpm: PassManagerRef, dtor: @pass_manager_res}; +pub struct PassManager { + llpm: PassManagerRef, + dtor: @pass_manager_res +} -pub fn mk_pass_manager() -> pass_manager { +pub fn mk_pass_manager() -> PassManager { unsafe { let llpm = llvm::LLVMCreatePassManager(); - return {llpm: llpm, dtor: @pass_manager_res(llpm)}; + + PassManager { + llpm: llpm, + dtor: @pass_manager_res(llpm) + } } } @@ -1556,13 +1544,20 @@ pub fn object_file_res(ObjFile: ObjectFileRef) -> object_file_res { } } -pub type object_file = {llof: ObjectFileRef, dtor: @object_file_res}; +pub struct ObjectFile { + llof: ObjectFileRef, + dtor: @object_file_res +} -pub fn mk_object_file(llmb: MemoryBufferRef) -> Option { +pub fn mk_object_file(llmb: MemoryBufferRef) -> Option { unsafe { let llof = llvm::LLVMCreateObjectFile(llmb); - if llof as int == 0 { return option::None::; } - return option::Some({llof: llof, dtor: @object_file_res(llof)}); + if llof as int == 0 { return option::None::; } + + option::Some(ObjectFile { + llof: llof, + dtor: @object_file_res(llof) + }) } } @@ -1583,12 +1578,18 @@ pub fn section_iter_res(SI: SectionIteratorRef) -> section_iter_res { } } -pub type section_iter = {llsi: SectionIteratorRef, dtor: @section_iter_res}; +pub struct SectionIter { + llsi: SectionIteratorRef, + dtor: @section_iter_res +} -pub fn mk_section_iter(llof: ObjectFileRef) -> section_iter { +pub fn mk_section_iter(llof: ObjectFileRef) -> SectionIter { unsafe { let llsi = llvm::LLVMGetSections(llof); - return {llsi: llsi, dtor: @section_iter_res(llsi)}; + SectionIter { + llsi: llsi, + dtor: @section_iter_res(llsi) + } } } diff --git a/src/librustc/metadata/common.rs b/src/librustc/metadata/common.rs index 27c9435bcbcca..877098ed49fe6 100644 --- a/src/librustc/metadata/common.rs +++ b/src/librustc/metadata/common.rs @@ -156,5 +156,9 @@ pub const 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 type link_meta = {name: @str, vers: @str, extras_hash: @str}; +pub struct LinkMeta { + name: @str, + vers: @str, + extras_hash: @str +} diff --git a/src/librustc/metadata/creader.rs b/src/librustc/metadata/creader.rs index a2203f0a3998a..79dec35e4abb8 100644 --- a/src/librustc/metadata/creader.rs +++ b/src/librustc/metadata/creader.rs @@ -55,17 +55,18 @@ pub fn read_crates(diag: span_handler, visit_view_item: |a| visit_view_item(e, a), visit_item: |a| visit_item(e, a), .. *visit::default_simple_visitor()}); + visit_crate(e, crate); visit::visit_crate(crate, (), v); dump_crates(e.crate_cache); warn_if_multiple_versions(e, diag, e.crate_cache); } -type cache_entry = { +struct cache_entry { cnum: int, span: span, - hash: ~str, + hash: @~str, metas: @~[@ast::meta_item] -}; +} fn dump_crates(+crate_cache: @mut ~[cache_entry]) { debug!("resolved crates:"); @@ -99,12 +100,12 @@ fn warn_if_multiple_versions(e: @mut Env, if matches.len() != 1u { diag.handler().warn( - fmt!("using multiple versions of crate `%s`", name)); + fmt!("using multiple versions of crate `%s`", *name)); for matches.each |match_| { diag.span_note(match_.span, ~"used here"); let attrs = ~[ attr::mk_attr(attr::mk_list_item( - ~"link", /*bad*/copy *match_.metas)) + @~"link", /*bad*/copy *match_.metas)) ]; loader::note_linkage_attrs(e.intr, diag, attrs); } @@ -125,12 +126,27 @@ struct Env { intr: @ident_interner } +fn visit_crate(e: @mut Env, c: ast::crate) { + let cstore = e.cstore; + let link_args = attr::find_attrs_by_name(c.node.attrs, "link_args"); + + for link_args.each |a| { + match attr::get_meta_item_value_str(attr::attr_meta(*a)) { + Some(ref linkarg) => { + cstore::add_used_link_args(cstore, **linkarg); + } + None => {/* fallthrough */ } + } + } +} + fn visit_view_item(e: @mut Env, i: @ast::view_item) { match /*bad*/copy i.node { - ast::view_item_use(ident, meta_items, id) => { - debug!("resolving use stmt. ident: %?, meta: %?", ident, meta_items); - let cnum = resolve_crate(e, ident, meta_items, ~"", i.span); - cstore::add_use_stmt_cnum(e.cstore, id, cnum); + ast::view_item_extern_mod(ident, meta_items, id) => { + debug!("resolving extern mod stmt. ident: %?, meta: %?", + ident, meta_items); + let cnum = resolve_crate(e, ident, meta_items, @~"", i.span); + cstore::add_extern_mod_stmt_cnum(e.cstore, id, cnum); } _ => () } @@ -152,38 +168,39 @@ fn visit_item(e: @mut Env, i: @ast::item) { let link_args = attr::find_attrs_by_name(i.attrs, "link_args"); match fm.sort { - ast::named => { - let foreign_name = - match attr::first_attr_value_str_by_name(i.attrs, - ~"link_name") { - Some(ref nn) => { - if (*nn) == ~"" { - e.diag.span_fatal( - i.span, - ~"empty #[link_name] not allowed; use #[nolink]."); - } - (/*bad*/copy *nn) - } - None => /*bad*/copy *e.intr.get(i.ident) - }; - if attr::find_attrs_by_name(i.attrs, ~"nolink").is_empty() { - already_added = - !cstore::add_used_library(cstore, copy foreign_name); - } - if !link_args.is_empty() && already_added { - e.diag.span_fatal(i.span, ~"library '" + foreign_name + - ~"' already added: can't specify link_args."); + ast::named => { + let foreign_name = + match attr::first_attr_value_str_by_name(i.attrs, + ~"link_name") { + Some(nn) => { + if *nn == ~"" { + e.diag.span_fatal( + i.span, + ~"empty #[link_name] not allowed; use " + + ~"#[nolink]."); + } + nn + } + None => e.intr.get(i.ident) + }; + if attr::find_attrs_by_name(i.attrs, ~"nolink").is_empty() { + already_added = + !cstore::add_used_library(cstore, foreign_name); + } + if !link_args.is_empty() && already_added { + e.diag.span_fatal(i.span, ~"library '" + *foreign_name + + ~"' already added: can't specify link_args."); + } } - } - ast::anonymous => { /* do nothing */ } + ast::anonymous => { /* do nothing */ } } for link_args.each |a| { match attr::get_meta_item_value_str(attr::attr_meta(*a)) { - Some(ref linkarg) => { - cstore::add_used_link_args(cstore, (/*bad*/copy *linkarg)); - } - None => {/* fallthrough */ } + Some(linkarg) => { + cstore::add_used_link_args(cstore, *linkarg); + } + None => { /* fallthrough */ } } } } @@ -191,9 +208,9 @@ fn visit_item(e: @mut Env, i: @ast::item) { } } -fn metas_with(+ident: ~str, +key: ~str, +metas: ~[@ast::meta_item]) +fn metas_with(ident: @~str, key: @~str, +metas: ~[@ast::meta_item]) -> ~[@ast::meta_item] { - let name_items = attr::find_meta_items_by_name(metas, key); + let name_items = attr::find_meta_items_by_name(metas, *key); if name_items.is_empty() { vec::append_one(metas, attr::mk_name_value_item_str(key, ident)) } else { @@ -201,12 +218,12 @@ fn metas_with(+ident: ~str, +key: ~str, +metas: ~[@ast::meta_item]) } } -fn metas_with_ident(+ident: ~str, +metas: ~[@ast::meta_item]) +fn metas_with_ident(ident: @~str, +metas: ~[@ast::meta_item]) -> ~[@ast::meta_item] { - metas_with(ident, ~"name", metas) + metas_with(ident, @~"name", metas) } -fn existing_match(e: @mut Env, metas: ~[@ast::meta_item], hash: ~str) +fn existing_match(e: @mut Env, metas: ~[@ast::meta_item], hash: @~str) -> Option { for e.crate_cache.each |c| { if loader::metadata_matches(*c.metas, metas) @@ -220,14 +237,14 @@ fn existing_match(e: @mut Env, metas: ~[@ast::meta_item], hash: ~str) fn resolve_crate(e: @mut Env, ident: ast::ident, +metas: ~[@ast::meta_item], - +hash: ~str, + hash: @~str, span: span) -> ast::crate_num { - let metas = metas_with_ident(/*bad*/copy *e.intr.get(ident), metas); + let metas = metas_with_ident(@/*bad*/copy *e.intr.get(ident), metas); match existing_match(e, metas, hash) { None => { - let load_ctxt: loader::ctxt = { + let load_ctxt = loader::Context { diag: e.diag, filesearch: e.filesearch, span: span, @@ -235,13 +252,13 @@ fn resolve_crate(e: @mut Env, metas: metas, hash: hash, os: e.os, - static: e.statik, + is_static: e.statik, intr: e.intr }; - let cinfo = loader::load_library_crate(load_ctxt); + let (lident, ldata) = loader::load_library_crate(load_ctxt); - let cfilename = Path(cinfo.ident); - let cdata = cinfo.data; + let cfilename = Path(lident); + let cdata = ldata; let attrs = decoder::get_crate_attributes(cdata); let linkage_metas = attr::find_linkage_metas(attrs); @@ -249,8 +266,12 @@ fn resolve_crate(e: @mut Env, // Claim this crate number and cache it let cnum = e.next_crate_num; - e.crate_cache.push({cnum: cnum, span: span, - hash: hash, metas: @linkage_metas}); + e.crate_cache.push(cache_entry { + cnum: cnum, + span: span, + hash: hash, + metas: @linkage_metas + }); e.next_crate_num += 1; // Now resolve the crates referenced by this crate @@ -259,11 +280,15 @@ fn resolve_crate(e: @mut Env, let cname = match attr::last_meta_item_value_str_by_name(load_ctxt.metas, ~"name") { - option::Some(ref v) => (/*bad*/copy *v), - option::None => /*bad*/copy *e.intr.get(ident) + Some(v) => v, + None => e.intr.get(ident), }; - let cmeta = @{name: cname, data: cdata, - cnum_map: cnum_map, cnum: cnum}; + let cmeta = @cstore::crate_metadata { + name: cname, + data: cdata, + cnum_map: cnum_map, + cnum: cnum + }; let cstore = e.cstore; cstore::set_crate_data(cstore, cnum, cmeta); @@ -285,10 +310,10 @@ fn resolve_crate_deps(e: @mut Env, cdata: @~[u8]) -> cstore::cnum_map { for decoder::get_crate_deps(e.intr, cdata).each |dep| { let extrn_cnum = dep.cnum; let cname = dep.name; - let cmetas = metas_with(/*bad*/copy dep.vers, ~"vers", ~[]); + let cmetas = metas_with(dep.vers, @~"vers", ~[]); debug!("resolving dep crate %s ver: %s hash: %s", - *e.intr.get(dep.name), dep.vers, dep.hash); - match existing_match(e, metas_with_ident(copy *e.intr.get(cname), + *e.intr.get(dep.name), *dep.vers, *dep.hash); + match existing_match(e, metas_with_ident(e.intr.get(cname), copy cmetas), dep.hash) { Some(local_cnum) => { @@ -302,8 +327,8 @@ fn resolve_crate_deps(e: @mut Env, cdata: @~[u8]) -> cstore::cnum_map { // FIXME (#2404): Need better error reporting than just a bogus // span. let fake_span = dummy_sp(); - let local_cnum = resolve_crate(e, cname, cmetas, - /*bad*/copy dep.hash, fake_span); + let local_cnum = resolve_crate(e, cname, cmetas, dep.hash, + fake_span); cnum_map.insert(extrn_cnum, local_cnum); } } diff --git a/src/librustc/metadata/csearch.rs b/src/librustc/metadata/csearch.rs index fa82e6c92c098..eda7362b9c177 100644 --- a/src/librustc/metadata/csearch.rs +++ b/src/librustc/metadata/csearch.rs @@ -17,7 +17,7 @@ use metadata::common::*; use metadata::cstore; use metadata::decoder; use metadata; -use middle::ty; +use middle::{ty, resolve}; use core::dvec::DVec; use core::vec; @@ -80,7 +80,7 @@ pub fn get_item_path(tcx: ty::ctxt, def: ast::def_id) -> ast_map::path { // FIXME #1920: This path is not always correct if the crate is not linked // into the root namespace. vec::append(~[ast_map::path_mod(tcx.sess.ident_of( - /*bad*/copy cdata.name))], path) + /*bad*/copy *cdata.name))], path) } pub enum found_ast { @@ -110,7 +110,7 @@ pub fn get_enum_variants(tcx: ty::ctxt, def: ast::def_id) pub fn get_impls_for_mod(cstore: @mut cstore::CStore, def: ast::def_id, name: Option) - -> @~[@decoder::_impl] { + -> @~[@resolve::Impl] { let cdata = cstore::get_crate_data(cstore, def.crate); do decoder::get_impls_for_mod(cstore.intr, cdata, def.node, name) |cnum| { cstore::get_crate_data(cstore, cnum) @@ -204,9 +204,11 @@ pub fn get_field_type(tcx: ty::ctxt, class_id: ast::def_id, class_id, def) ); debug!("got field data %?", the_field); let ty = decoder::item_type(def, the_field, tcx, cdata); - return {bounds: @~[], - region_param: None, - ty: ty}; + ty::ty_param_bounds_and_ty { + bounds: @~[], + region_param: None, + ty: ty + } } // Given a def_id for an impl or class, return the traits it implements, diff --git a/src/librustc/metadata/cstore.rs b/src/librustc/metadata/cstore.rs index 73ec872b6a6ec..667a9c200580f 100644 --- a/src/librustc/metadata/cstore.rs +++ b/src/librustc/metadata/cstore.rs @@ -33,29 +33,31 @@ use syntax::parse::token::ident_interner; // own crate numbers. pub type cnum_map = oldmap::HashMap; -pub type crate_metadata = @{name: ~str, - data: @~[u8], - cnum_map: cnum_map, - cnum: ast::crate_num}; +pub struct crate_metadata { + name: @~str, + data: @~[u8], + cnum_map: cnum_map, + cnum: ast::crate_num +} pub struct CStore { - priv metas: oldmap::HashMap, - priv use_crate_map: use_crate_map, + priv metas: oldmap::HashMap, + priv extern_mod_crate_map: extern_mod_crate_map, priv used_crate_files: ~[Path], priv used_libraries: ~[~str], priv used_link_args: ~[~str], intr: @ident_interner } -// Map from node_id's of local use statements to crate numbers -type use_crate_map = oldmap::HashMap; +// Map from node_id's of local extern mod statements to crate numbers +type extern_mod_crate_map = oldmap::HashMap; pub fn mk_cstore(intr: @ident_interner) -> CStore { let meta_cache = oldmap::HashMap(); let crate_map = oldmap::HashMap(); return CStore { metas: meta_cache, - use_crate_map: crate_map, + extern_mod_crate_map: crate_map, used_crate_files: ~[], used_libraries: ~[], used_link_args: ~[], @@ -64,23 +66,23 @@ pub fn mk_cstore(intr: @ident_interner) -> CStore { } pub fn get_crate_data(cstore: @mut CStore, cnum: ast::crate_num) - -> crate_metadata { + -> @crate_metadata { return cstore.metas.get(&cnum); } -pub fn get_crate_hash(cstore: @mut CStore, cnum: ast::crate_num) -> ~str { +pub fn get_crate_hash(cstore: @mut CStore, cnum: ast::crate_num) -> @~str { let cdata = get_crate_data(cstore, cnum); - return decoder::get_crate_hash(cdata.data); + decoder::get_crate_hash(cdata.data) } -pub fn get_crate_vers(cstore: @mut CStore, cnum: ast::crate_num) -> ~str { +pub fn get_crate_vers(cstore: @mut CStore, cnum: ast::crate_num) -> @~str { let cdata = get_crate_data(cstore, cnum); - return decoder::get_crate_vers(cdata.data); + decoder::get_crate_vers(cdata.data) } pub fn set_crate_data(cstore: @mut CStore, cnum: ast::crate_num, - data: crate_metadata) { + data: @crate_metadata) { let metas = cstore.metas; metas.insert(cnum, data); } @@ -90,7 +92,7 @@ pub fn have_crate_data(cstore: @mut CStore, cnum: ast::crate_num) -> bool { } pub fn iter_crate_data(cstore: @mut CStore, - i: fn(ast::crate_num, crate_metadata)) { + i: fn(ast::crate_num, @crate_metadata)) { let metas = cstore.metas; for metas.each |&k, &v| { i(k, v); @@ -107,69 +109,65 @@ pub fn get_used_crate_files(cstore: @mut CStore) -> ~[Path] { return /*bad*/copy cstore.used_crate_files; } -pub fn add_used_library(cstore: @mut CStore, +lib: ~str) -> bool { - assert lib != ~""; +pub fn add_used_library(cstore: @mut CStore, lib: @~str) -> bool { + assert *lib != ~""; - if vec::contains(cstore.used_libraries, &lib) { return false; } - cstore.used_libraries.push(lib); - return true; + if cstore.used_libraries.contains(&*lib) { return false; } + cstore.used_libraries.push(/*bad*/ copy *lib); + true } pub fn get_used_libraries(cstore: @mut CStore) -> ~[~str] { - return /*bad*/copy cstore.used_libraries; + /*bad*/copy cstore.used_libraries } -pub fn add_used_link_args(cstore: @mut CStore, args: ~str) { - cstore.used_link_args.push_all(str::split_char(args, ' ')); +pub fn add_used_link_args(cstore: @mut CStore, args: &str) { + cstore.used_link_args.push_all(args.split_char(' ')); } pub fn get_used_link_args(cstore: @mut CStore) -> ~[~str] { - return /*bad*/copy cstore.used_link_args; + /*bad*/copy cstore.used_link_args } -pub fn add_use_stmt_cnum(cstore: @mut CStore, - use_id: ast::node_id, - cnum: ast::crate_num) { - let use_crate_map = cstore.use_crate_map; - use_crate_map.insert(use_id, cnum); +pub fn add_extern_mod_stmt_cnum(cstore: @mut CStore, + emod_id: ast::node_id, + cnum: ast::crate_num) { + let extern_mod_crate_map = cstore.extern_mod_crate_map; + extern_mod_crate_map.insert(emod_id, cnum); } -pub fn find_use_stmt_cnum(cstore: @mut CStore, - use_id: ast::node_id) +pub fn find_extern_mod_stmt_cnum(cstore: @mut CStore, + emod_id: ast::node_id) -> Option { - let use_crate_map = cstore.use_crate_map; - use_crate_map.find(&use_id) + let extern_mod_crate_map = cstore.extern_mod_crate_map; + extern_mod_crate_map.find(&emod_id) } // returns hashes of crates directly used by this crate. Hashes are // sorted by crate name. pub fn get_dep_hashes(cstore: @mut CStore) -> ~[~str] { - type crate_hash = {name: ~str, hash: ~str}; + struct crate_hash { name: @~str, hash: @~str } let mut result = ~[]; - let use_crate_map = cstore.use_crate_map; - for use_crate_map.each_value |&cnum| { + 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); - result.push({name: /*bad*/copy cdata.name, hash: hash}); + debug!("Add hash[%s]: %s", *cdata.name, *hash); + result.push(crate_hash { + name: cdata.name, + hash: hash + }); } - pure fn lteq(a: &crate_hash, b: &crate_hash) -> bool { - a.name <= b.name - } + let sorted = std::sort::merge_sort(result, |a, b| a.name <= b.name); - let sorted = std::sort::merge_sort(result, lteq); debug!("sorted:"); for sorted.each |x| { - debug!(" hash[%s]: %s", x.name, x.hash); - } - - fn mapper(ch: &crate_hash) -> ~str { - return /*bad*/copy ch.hash; + debug!(" hash[%s]: %s", *x.name, *x.hash); } - return vec::map(sorted, mapper); + sorted.map(|ch| /*bad*/copy *ch.hash) } // Local Variables: diff --git a/src/librustc/metadata/decoder.rs b/src/librustc/metadata/decoder.rs index 3564e10790d3a..ca55c8a407276 100644 --- a/src/librustc/metadata/decoder.rs +++ b/src/librustc/metadata/decoder.rs @@ -13,7 +13,7 @@ use core::prelude::*; -use cmd = metadata::cstore::crate_metadata; +use metadata::cstore::crate_metadata; use dvec::DVec; use hash::{Hash, HashUtil}; use io::WriterUtil; @@ -24,7 +24,7 @@ use metadata::cstore; use metadata::decoder; use metadata::tydecode::{parse_ty_data, parse_def_id, parse_bounds_data}; use metadata::tydecode::{parse_ident}; -use middle::ty; +use middle::{ty, resolve}; use util::ppaux::ty_to_str; use core::cmp; @@ -47,6 +47,8 @@ use syntax::print::pprust; use syntax::{ast, ast_util}; use syntax::codemap; +type cmd = @crate_metadata; + // A function that takes a def_id relative to the crate being searched and // returns a def_id relative to the compilation environment, i.e. if we hit a // def_id for an item defined in another crate, somebody needs to figure out @@ -64,7 +66,7 @@ fn lookup_hash(d: ebml::Doc, eq_fn: fn(x:&[u8]) -> bool, hash: uint) -> let belt = tag_index_buckets_bucket_elt; for reader::tagged_docs(tagged_doc.doc, belt) |elt| { let pos = io::u64_from_be_bytes(*elt.data, elt.start, 4u) as uint; - if eq_fn(vec::view(*elt.data, elt.start + 4u, elt.end)) { + if eq_fn(vec::slice(*elt.data, elt.start + 4u, elt.end)) { return Some(reader::doc_at(d.data, pos).doc); } }; @@ -75,7 +77,8 @@ pub type GetCrateDataCb = &fn(ast::crate_num) -> cmd; pub fn maybe_find_item(item_id: int, items: ebml::Doc) -> Option { fn eq_item(bytes: &[u8], item_id: int) -> bool { - return io::u64_from_be_bytes(vec::view(bytes, 0u, 4u), 0u, 4u) as int + return io::u64_from_be_bytes( + vec::slice(bytes, 0u, 4u), 0u, 4u) as int == item_id; } lookup_hash(items, @@ -97,6 +100,7 @@ fn lookup_item(item_id: int, data: @~[u8]) -> ebml::Doc { } } +#[deriving_eq] enum Family { Const, // c Fn, // f @@ -120,13 +124,6 @@ enum Family { InheritedField // N } -impl cmp::Eq for Family { - pure fn eq(&self, other: &Family) -> bool { - ((*self) as uint) == ((*other) as uint) - } - pure fn ne(&self, other: &Family) -> bool { !(*self).eq(other) } -} - fn item_family(item: ebml::Doc) -> Family { let fam = reader::get_doc(item, tag_items_data_item_family); match reader::doc_as_u8(fam) as char { @@ -359,9 +356,11 @@ pub fn get_type(cdata: cmd, id: ast::node_id, tcx: ty::ctxt) item_ty_param_bounds(item, tcx, cdata) } else { @~[] }; let rp = item_ty_region_param(item); - return {bounds: tp_bounds, - region_param: rp, - ty: t}; + ty::ty_param_bounds_and_ty { + bounds: tp_bounds, + region_param: rp, + ty: t + } } pub fn get_region_param(cdata: cmd, id: ast::node_id) @@ -543,7 +542,7 @@ pub fn get_item_path(intr: @ident_interner, cdata: cmd, id: ast::node_id) } pub type decode_inlined_item = fn( - cdata: cstore::crate_metadata, + cdata: @cstore::crate_metadata, tcx: ty::ctxt, path: ast_map::path, par_doc: ebml::Doc) -> Option; @@ -605,20 +604,6 @@ pub fn get_enum_variants(intr: @ident_interner, cdata: cmd, id: ast::node_id, return infos; } -// NB: These types are duplicated in resolve.rs -pub type method_info = { - did: ast::def_id, - n_tps: uint, - ident: ast::ident, - self_type: ast::self_ty_ -}; - -pub type _impl = { - did: ast::def_id, - ident: ast::ident, - methods: ~[@method_info] -}; - fn get_self_ty(item: ebml::Doc) -> ast::self_ty_ { fn get_mutability(ch: u8) -> ast::mutability { match ch as char { @@ -649,16 +634,17 @@ fn get_self_ty(item: ebml::Doc) -> ast::self_ty_ { } fn item_impl_methods(intr: @ident_interner, cdata: cmd, item: ebml::Doc, - base_tps: uint) -> ~[@method_info] { + base_tps: uint) -> ~[@resolve::MethodInfo] { let mut rslt = ~[]; for reader::tagged_docs(item, tag_item_impl_method) |doc| { let m_did = reader::with_doc_data(doc, |d| parse_def_id(d)); let mth_item = lookup_item(m_did.node, cdata.data); let self_ty = get_self_ty(mth_item); - rslt.push(@{did: translate_def_id(cdata, m_did), - n_tps: item_ty_param_count(mth_item) - base_tps, - ident: item_name(intr, mth_item), - self_type: self_ty}); + rslt.push(@resolve::MethodInfo { + did: translate_def_id(cdata, m_did), + n_tps: item_ty_param_count(mth_item) - base_tps, + ident: item_name(intr, mth_item), + self_type: self_ty}); } rslt } @@ -668,7 +654,7 @@ pub fn get_impls_for_mod(intr: @ident_interner, m_id: ast::node_id, name: Option, get_cdata: &fn(ast::crate_num) -> cmd) - -> @~[@_impl] { + -> @~[@resolve::Impl] { let data = cdata.data; let mod_item = lookup_item(m_id, data); let mut result = ~[]; @@ -685,7 +671,7 @@ pub fn get_impls_for_mod(intr: @ident_interner, let nm = item_name(intr, item); if match name { Some(n) => { n == nm } None => { true } } { let base_tps = item_ty_param_count(item); - result.push(@{ + result.push(@resolve::Impl { did: local_did, ident: nm, methods: item_impl_methods(intr, impl_cdata, item, base_tps) }); @@ -713,8 +699,14 @@ pub fn get_trait_methods(intr: @ident_interner, cdata: cmd, id: ast::node_id, } }; let self_ty = get_self_ty(mth); - result.push({ident: name, tps: bounds, fty: fty, self_ty: self_ty, - vis: ast::public, def_id: def_id}); + result.push(ty::method { + ident: name, + tps: bounds, + fty: fty, + self_ty: self_ty, + vis: ast::public, + def_id: def_id + }); } debug!("get_trait_methods: }"); @result @@ -745,17 +737,23 @@ pub fn get_provided_trait_methods(intr: @ident_interner, cdata: cmd, }; let self_ty = get_self_ty(mth); - let ty_method = {ident: name, tps: bounds, fty: fty, self_ty: self_ty, - vis: ast::public, def_id: did}; + let ty_method = ty::method { + ident: name, + tps: bounds, + fty: fty, + self_ty: self_ty, + vis: ast::public, + def_id: did + }; let provided_trait_method_info = ProvidedTraitMethodInfo { ty: ty_method, def_id: did }; - vec::push(&mut result, move provided_trait_method_info); + vec::push(&mut result, provided_trait_method_info); } - return move result; + return result; } /// Returns the supertraits of the given trait. @@ -766,7 +764,7 @@ pub fn get_supertraits(cdata: cmd, id: ast::node_id, tcx: ty::ctxt) for reader::tagged_docs(item_doc, tag_impl_trait) |trait_doc| { results.push(doc_type(trait_doc, tcx, cdata)); } - return dvec::unwrap(move results); + return dvec::unwrap(results); } // If the item in question is a trait, returns its set of methods and @@ -847,7 +845,7 @@ pub fn get_static_methods_if_impl(intr: @ident_interner, } } - return Some(dvec::unwrap(move static_impl_methods)); + return Some(dvec::unwrap(static_impl_methods)); } pub fn get_item_attrs(cdata: cmd, @@ -914,12 +912,13 @@ fn family_names_type(fam: Family) -> bool { match fam { Type | Mod | Trait => true, _ => false } } -fn read_path(d: ebml::Doc) -> {path: ~str, pos: uint} { +fn read_path(d: ebml::Doc) -> (~str, uint) { let desc = reader::doc_data(d); let pos = io::u64_from_be_bytes(desc, 0u, 4u) as uint; let pathbytes = vec::slice::(desc, 4u, vec::len::(desc)); let path = str::from_bytes(pathbytes); - return {path: path, pos: pos}; + + (path, pos) } fn describe_def(items: ebml::Doc, id: ast::def_id) -> ~str { @@ -961,7 +960,7 @@ fn get_meta_items(md: ebml::Doc) -> ~[@ast::meta_item] { for reader::tagged_docs(md, tag_meta_item_word) |meta_item_doc| { let nd = reader::get_doc(meta_item_doc, tag_meta_item_name); let n = str::from_bytes(reader::doc_data(nd)); - items.push(attr::mk_word_item(n)); + items.push(attr::mk_word_item(@n)); }; for reader::tagged_docs(md, tag_meta_item_name_value) |meta_item_doc| { let nd = reader::get_doc(meta_item_doc, tag_meta_item_name); @@ -970,13 +969,13 @@ fn get_meta_items(md: ebml::Doc) -> ~[@ast::meta_item] { let v = str::from_bytes(reader::doc_data(vd)); // FIXME (#623): Should be able to decode meta_name_value variants, // but currently the encoder just drops them - items.push(attr::mk_name_value_item_str(n, v)); + items.push(attr::mk_name_value_item_str(@n, @v)); }; for reader::tagged_docs(md, tag_meta_item_list) |meta_item_doc| { let nd = reader::get_doc(meta_item_doc, tag_meta_item_name); let n = str::from_bytes(reader::doc_data(nd)); let subitems = get_meta_items(meta_item_doc); - items.push(attr::mk_list_item(n, subitems)); + items.push(attr::mk_list_item(@n, subitems)); }; return items; } @@ -1014,7 +1013,7 @@ fn list_meta_items(intr: @ident_interner, } } -fn list_crate_attributes(intr: @ident_interner, md: ebml::Doc, hash: ~str, +fn list_crate_attributes(intr: @ident_interner, md: ebml::Doc, hash: &str, out: io::Writer) { out.write_str(fmt!("=Crate Attributes (%s)=\n", hash)); @@ -1029,8 +1028,12 @@ pub fn get_crate_attributes(data: @~[u8]) -> ~[ast::attribute] { return get_attributes(reader::Doc(data)); } -pub type crate_dep = {cnum: ast::crate_num, name: ast::ident, - vers: ~str, hash: ~str}; +pub struct crate_dep { + cnum: ast::crate_num, + name: ast::ident, + vers: @~str, + hash: @~str +} pub fn get_crate_deps(intr: @ident_interner, data: @~[u8]) -> ~[crate_dep] { let mut deps: ~[crate_dep] = ~[]; @@ -1041,10 +1044,10 @@ pub fn get_crate_deps(intr: @ident_interner, data: @~[u8]) -> ~[crate_dep] { str::from_bytes(reader::doc_data(reader::get_doc(doc, tag_))) } for reader::tagged_docs(depsdoc, tag_crate_dep) |depdoc| { - deps.push({cnum: crate_num, + deps.push(crate_dep {cnum: crate_num, name: intr.intern(@docstr(depdoc, tag_crate_dep_name)), - vers: docstr(depdoc, tag_crate_dep_vers), - hash: docstr(depdoc, tag_crate_dep_hash)}); + vers: @docstr(depdoc, tag_crate_dep_vers), + hash: @docstr(depdoc, tag_crate_dep_hash)}); crate_num += 1; }; return deps; @@ -1056,25 +1059,26 @@ fn list_crate_deps(intr: @ident_interner, data: @~[u8], out: io::Writer) { for get_crate_deps(intr, data).each |dep| { out.write_str( fmt!("%d %s-%s-%s\n", - dep.cnum, *intr.get(dep.name), dep.hash, dep.vers)); + dep.cnum, *intr.get(dep.name), *dep.hash, *dep.vers)); } out.write_str(~"\n"); } -pub fn get_crate_hash(data: @~[u8]) -> ~str { +pub fn get_crate_hash(data: @~[u8]) -> @~str { let cratedoc = reader::Doc(data); let hashdoc = reader::get_doc(cratedoc, tag_crate_hash); - return str::from_bytes(reader::doc_data(hashdoc)); + @str::from_bytes(reader::doc_data(hashdoc)) } -pub fn get_crate_vers(data: @~[u8]) -> ~str { +pub fn get_crate_vers(data: @~[u8]) -> @~str { let attrs = decoder::get_crate_attributes(data); - return match attr::last_meta_item_value_str_by_name( - attr::find_linkage_metas(attrs), ~"vers") { - Some(ref ver) => (/*bad*/copy *ver), - None => ~"0.0" - }; + let linkage_attrs = attr::find_linkage_metas(attrs); + + match attr::last_meta_item_value_str_by_name(linkage_attrs, ~"vers") { + Some(ver) => ver, + None => @~"0.0" + } } fn iter_crate_items(intr: @ident_interner, cdata: cmd, @@ -1095,7 +1099,7 @@ pub fn list_crate_metadata(intr: @ident_interner, bytes: @~[u8], out: io::Writer) { let hash = get_crate_hash(bytes); let md = reader::Doc(bytes); - list_crate_attributes(intr, md, hash, out); + list_crate_attributes(intr, md, *hash, out); list_crate_deps(intr, bytes, out); } diff --git a/src/librustc/metadata/encoder.rs b/src/librustc/metadata/encoder.rs index 12c5e3388dbe7..86b07abffc2e9 100644 --- a/src/librustc/metadata/encoder.rs +++ b/src/librustc/metadata/encoder.rs @@ -55,22 +55,22 @@ use writer = std::ebml::writer; // used by astencode: type abbrev_map = oldmap::HashMap; -pub type encode_inlined_item = fn@(ecx: @encode_ctxt, +pub type encode_inlined_item = fn@(ecx: @EncodeContext, ebml_w: writer::Encoder, path: &[ast_map::path_elt], ii: ast::inlined_item); -pub type encode_parms = { +pub struct EncodeParams { diag: span_handler, tcx: ty::ctxt, reachable: HashMap, reexports2: middle::resolve::ExportMap2, item_symbols: HashMap, discrim_symbols: HashMap, - link_meta: link_meta, + link_meta: LinkMeta, cstore: @mut cstore::CStore, encode_inlined_item: encode_inlined_item -}; +} struct Stats { inline_bytes: uint, @@ -85,7 +85,7 @@ struct Stats { n_inlines: uint } -pub enum encode_ctxt = { +pub struct EncodeContext { diag: span_handler, tcx: ty::ctxt, stats: @mut Stats, @@ -93,31 +93,31 @@ pub enum encode_ctxt = { reexports2: middle::resolve::ExportMap2, item_symbols: HashMap, discrim_symbols: HashMap, - link_meta: link_meta, + link_meta: LinkMeta, cstore: @mut cstore::CStore, encode_inlined_item: encode_inlined_item, type_abbrevs: abbrev_map -}; +} -pub fn reachable(ecx: @encode_ctxt, id: node_id) -> bool { +pub fn reachable(ecx: @EncodeContext, id: node_id) -> bool { ecx.reachable.contains_key(&id) } -fn encode_name(ecx: @encode_ctxt, ebml_w: writer::Encoder, name: ident) { - ebml_w.wr_tagged_str(tag_paths_data_name, ecx.tcx.sess.str_of(name)); +fn encode_name(ecx: @EncodeContext, ebml_w: writer::Encoder, name: ident) { + ebml_w.wr_tagged_str(tag_paths_data_name, *ecx.tcx.sess.str_of(name)); } -fn encode_impl_type_basename(ecx: @encode_ctxt, ebml_w: writer::Encoder, +fn encode_impl_type_basename(ecx: @EncodeContext, ebml_w: writer::Encoder, name: ident) { ebml_w.wr_tagged_str(tag_item_impl_type_basename, - ecx.tcx.sess.str_of(name)); + *ecx.tcx.sess.str_of(name)); } pub fn encode_def_id(ebml_w: writer::Encoder, id: def_id) { ebml_w.wr_tagged_str(tag_def_id, def_to_str(id)); } -fn encode_region_param(ecx: @encode_ctxt, ebml_w: writer::Encoder, +fn encode_region_param(ecx: @EncodeContext, ebml_w: writer::Encoder, it: @ast::item) { let opt_rp = ecx.tcx.region_paramd_items.find(&it.id); for opt_rp.each |rp| { @@ -137,20 +137,25 @@ fn encode_mutability(ebml_w: writer::Encoder, mt: struct_mutability) { } } -type entry = {val: T, pos: uint}; +struct entry { + val: T, + pos: uint +} -fn add_to_index(ecx: @encode_ctxt, ebml_w: writer::Encoder, path: &[ident], +fn add_to_index(ecx: @EncodeContext, ebml_w: writer::Encoder, path: &[ident], index: &mut ~[entry<~str>], name: ident) { let mut full_path = ~[]; full_path.push_all(path); full_path.push(name); index.push( - {val: ast_util::path_name_i(full_path, - ecx.tcx.sess.parse_sess.interner), - pos: ebml_w.writer.tell()}); + entry { + val: ast_util::path_name_i(full_path, + ecx.tcx.sess.parse_sess.interner), + pos: ebml_w.writer.tell() + }); } -fn encode_trait_ref(ebml_w: writer::Encoder, ecx: @encode_ctxt, +fn encode_trait_ref(ebml_w: writer::Encoder, ecx: @EncodeContext, t: @trait_ref) { ebml_w.start_tag(tag_impl_trait); encode_type(ecx, ebml_w, node_id_to_type(ecx.tcx, t.ref_id)); @@ -167,7 +172,7 @@ fn encode_family(ebml_w: writer::Encoder, c: char) { pub fn def_to_str(did: def_id) -> ~str { fmt!("%d:%d", did.crate, did.node) } -fn encode_ty_type_param_bounds(ebml_w: writer::Encoder, ecx: @encode_ctxt, +fn encode_ty_type_param_bounds(ebml_w: writer::Encoder, ecx: @EncodeContext, params: @~[ty::param_bounds]) { let ty_str_ctxt = @tyencode::ctxt { diag: ecx.diag, @@ -182,7 +187,7 @@ fn encode_ty_type_param_bounds(ebml_w: writer::Encoder, ecx: @encode_ctxt, } } -fn encode_type_param_bounds(ebml_w: writer::Encoder, ecx: @encode_ctxt, +fn encode_type_param_bounds(ebml_w: writer::Encoder, ecx: @EncodeContext, params: &[ty_param]) { let ty_param_bounds = @params.map(|param| ecx.tcx.ty_param_bounds.get(¶m.id)); @@ -196,7 +201,7 @@ fn encode_variant_id(ebml_w: writer::Encoder, vid: def_id) { ebml_w.end_tag(); } -pub fn write_type(ecx: @encode_ctxt, ebml_w: writer::Encoder, typ: ty::t) { +pub fn write_type(ecx: @EncodeContext, ebml_w: writer::Encoder, typ: ty::t) { let ty_str_ctxt = @tyencode::ctxt { diag: ecx.diag, ds: def_to_str, @@ -206,7 +211,7 @@ pub fn write_type(ecx: @encode_ctxt, ebml_w: writer::Encoder, typ: ty::t) { tyencode::enc_ty(ebml_w.writer, ty_str_ctxt, typ); } -pub fn write_vstore(ecx: @encode_ctxt, ebml_w: writer::Encoder, +pub fn write_vstore(ecx: @EncodeContext, ebml_w: writer::Encoder, vstore: ty::vstore) { let ty_str_ctxt = @tyencode::ctxt { diag: ecx.diag, @@ -217,13 +222,13 @@ pub fn write_vstore(ecx: @encode_ctxt, ebml_w: writer::Encoder, tyencode::enc_vstore(ebml_w.writer, ty_str_ctxt, vstore); } -fn encode_type(ecx: @encode_ctxt, ebml_w: writer::Encoder, typ: ty::t) { +fn encode_type(ecx: @EncodeContext, ebml_w: writer::Encoder, typ: ty::t) { ebml_w.start_tag(tag_items_data_item_type); write_type(ecx, ebml_w, typ); ebml_w.end_tag(); } -fn encode_symbol(ecx: @encode_ctxt, ebml_w: writer::Encoder, id: node_id) { +fn encode_symbol(ecx: @EncodeContext, ebml_w: writer::Encoder, id: node_id) { ebml_w.start_tag(tag_items_data_item_symbol); let sym = match ecx.item_symbols.find(&id) { Some(ref x) => (/*bad*/copy *x), @@ -236,14 +241,14 @@ fn encode_symbol(ecx: @encode_ctxt, ebml_w: writer::Encoder, id: node_id) { ebml_w.end_tag(); } -fn encode_discriminant(ecx: @encode_ctxt, ebml_w: writer::Encoder, +fn encode_discriminant(ecx: @EncodeContext, ebml_w: writer::Encoder, id: node_id) { ebml_w.start_tag(tag_items_data_item_symbol); ebml_w.writer.write(str::to_bytes(ecx.discrim_symbols.get(&id))); ebml_w.end_tag(); } -fn encode_disr_val(_ecx: @encode_ctxt, ebml_w: writer::Encoder, +fn encode_disr_val(_ecx: @EncodeContext, ebml_w: writer::Encoder, disr_val: int) { ebml_w.start_tag(tag_disr_val); ebml_w.writer.write(str::to_bytes(int::to_str(disr_val))); @@ -256,7 +261,7 @@ fn encode_parent_item(ebml_w: writer::Encoder, id: def_id) { ebml_w.end_tag(); } -fn encode_enum_variant_info(ecx: @encode_ctxt, ebml_w: writer::Encoder, +fn encode_enum_variant_info(ecx: @EncodeContext, ebml_w: writer::Encoder, id: node_id, variants: &[variant], path: &[ast_map::path_elt], index: @mut ~[entry], @@ -266,7 +271,7 @@ fn encode_enum_variant_info(ecx: @encode_ctxt, ebml_w: writer::Encoder, let vi = ty::enum_variants(ecx.tcx, ast::def_id { crate: local_crate, node: id }); for variants.each |variant| { - index.push({val: variant.node.id, pos: ebml_w.writer.tell()}); + index.push(entry {val: variant.node.id, pos: ebml_w.writer.tell()}); ebml_w.start_tag(tag_items_data_item); encode_def_id(ebml_w, local_def(variant.node.id)); encode_family(ebml_w, 'v'); @@ -296,16 +301,16 @@ fn encode_enum_variant_info(ecx: @encode_ctxt, ebml_w: writer::Encoder, } } -fn encode_path(ecx: @encode_ctxt, ebml_w: writer::Encoder, +fn encode_path(ecx: @EncodeContext, ebml_w: writer::Encoder, path: &[ast_map::path_elt], name: ast_map::path_elt) { - fn encode_path_elt(ecx: @encode_ctxt, ebml_w: writer::Encoder, + fn encode_path_elt(ecx: @EncodeContext, ebml_w: writer::Encoder, elt: ast_map::path_elt) { let (tag, name) = match elt { ast_map::path_mod(name) => (tag_path_elt_mod, name), ast_map::path_name(name) => (tag_path_elt_name, name) }; - ebml_w.wr_tagged_str(tag, ecx.tcx.sess.str_of(name)); + ebml_w.wr_tagged_str(tag, *ecx.tcx.sess.str_of(name)); } do ebml_w.wr_tag(tag_path) { @@ -317,7 +322,7 @@ fn encode_path(ecx: @encode_ctxt, ebml_w: writer::Encoder, } } -fn encode_info_for_mod(ecx: @encode_ctxt, ebml_w: writer::Encoder, +fn encode_info_for_mod(ecx: @EncodeContext, ebml_w: writer::Encoder, md: _mod, id: node_id, path: &[ast_map::path_elt], name: ident) { ebml_w.start_tag(tag_items_data_item); @@ -333,7 +338,7 @@ fn encode_info_for_mod(ecx: @encode_ctxt, ebml_w: writer::Encoder, let (ident, did) = (item.ident, item.id); debug!("(encoding info for module) ... encoding impl %s \ (%?/%?)", - ecx.tcx.sess.str_of(ident), + *ecx.tcx.sess.str_of(ident), did, ast_map::node_id_to_str(ecx.tcx.items, did, ecx.tcx .sess.parse_sess.interner)); @@ -353,15 +358,15 @@ fn encode_info_for_mod(ecx: @encode_ctxt, ebml_w: writer::Encoder, match ecx.reexports2.find(&id) { Some(ref exports) => { debug!("(encoding info for module) found reexports for %d", id); - for (*exports).each |exp| { + for exports.each |exp| { debug!("(encoding info for module) reexport '%s' for %d", - exp.name, id); + *exp.name, id); ebml_w.start_tag(tag_items_data_item_reexport); ebml_w.start_tag(tag_items_data_item_reexport_def_id); ebml_w.wr_str(def_to_str(exp.def_id)); ebml_w.end_tag(); ebml_w.start_tag(tag_items_data_item_reexport_name); - ebml_w.wr_str(exp.name); + ebml_w.wr_str(*exp.name); ebml_w.end_tag(); ebml_w.end_tag(); } @@ -422,7 +427,7 @@ fn encode_method_sort(ebml_w: writer::Encoder, sort: char) { } /* Returns an index of items in this class */ -fn encode_info_for_struct(ecx: @encode_ctxt, ebml_w: writer::Encoder, +fn encode_info_for_struct(ecx: @EncodeContext, ebml_w: writer::Encoder, path: &[ast_map::path_elt], fields: &[@struct_field], global_index: @mut~[entry]) -> ~[entry] { @@ -443,11 +448,11 @@ fn encode_info_for_struct(ecx: @encode_ctxt, ebml_w: writer::Encoder, }; let id = field.node.id; - index.push({val: id, pos: ebml_w.writer.tell()}); - global_index.push({val: id, pos: ebml_w.writer.tell()}); + index.push(entry {val: id, pos: ebml_w.writer.tell()}); + global_index.push(entry {val: id, pos: ebml_w.writer.tell()}); ebml_w.start_tag(tag_items_data_item); debug!("encode_info_for_struct: doing %s %d", - tcx.sess.str_of(nm), id); + *tcx.sess.str_of(nm), id); encode_visibility(ebml_w, vis); encode_name(ecx, ebml_w, nm); encode_path(ecx, ebml_w, path, ast_map::path_name(nm)); @@ -460,7 +465,7 @@ fn encode_info_for_struct(ecx: @encode_ctxt, ebml_w: writer::Encoder, } // This is for encoding info for ctors and dtors -fn encode_info_for_ctor(ecx: @encode_ctxt, ebml_w: writer::Encoder, +fn encode_info_for_ctor(ecx: @EncodeContext, ebml_w: writer::Encoder, id: node_id, ident: ident, path: &[ast_map::path_elt], item: Option, tps: &[ty_param]) { ebml_w.start_tag(tag_items_data_item); @@ -470,7 +475,7 @@ fn encode_info_for_ctor(ecx: @encode_ctxt, ebml_w: writer::Encoder, encode_type_param_bounds(ebml_w, ecx, tps); let its_ty = node_id_to_type(ecx.tcx, id); debug!("fn name = %s ty = %s its node id = %d", - ecx.tcx.sess.str_of(ident), + *ecx.tcx.sess.str_of(ident), ty_to_str(ecx.tcx, its_ty), id); encode_type(ecx, ebml_w, its_ty); encode_path(ecx, ebml_w, path, ast_map::path_name(ident)); @@ -485,13 +490,13 @@ fn encode_info_for_ctor(ecx: @encode_ctxt, ebml_w: writer::Encoder, ebml_w.end_tag(); } -fn encode_info_for_struct_ctor(ecx: @encode_ctxt, +fn encode_info_for_struct_ctor(ecx: @EncodeContext, ebml_w: writer::Encoder, path: &[ast_map::path_elt], name: ast::ident, ctor_id: node_id, index: @mut ~[entry]) { - index.push({ val: ctor_id, pos: ebml_w.writer.tell() }); + index.push(entry { val: ctor_id, pos: ebml_w.writer.tell() }); ebml_w.start_tag(tag_items_data_item); encode_def_id(ebml_w, local_def(ctor_id)); @@ -507,7 +512,7 @@ fn encode_info_for_struct_ctor(ecx: @encode_ctxt, ebml_w.end_tag(); } -fn encode_info_for_method(ecx: @encode_ctxt, +fn encode_info_for_method(ecx: @EncodeContext, ebml_w: writer::Encoder, impl_path: &[ast_map::path_elt], should_inline: bool, @@ -515,7 +520,7 @@ fn encode_info_for_method(ecx: @encode_ctxt, m: @method, +all_tps: ~[ty_param]) { debug!("encode_info_for_method: %d %s %u", m.id, - ecx.tcx.sess.str_of(m.ident), all_tps.len()); + *ecx.tcx.sess.str_of(m.ident), all_tps.len()); ebml_w.start_tag(tag_items_data_item); encode_def_id(ebml_w, local_def(m.id)); match m.self_ty.node { @@ -566,7 +571,7 @@ fn should_inline(attrs: &[attribute]) -> bool { } -fn encode_info_for_item(ecx: @encode_ctxt, ebml_w: writer::Encoder, +fn encode_info_for_item(ecx: @EncodeContext, ebml_w: writer::Encoder, item: @item, index: @mut ~[entry], path: &[ast_map::path_elt]) { @@ -581,7 +586,7 @@ fn encode_info_for_item(ecx: @encode_ctxt, ebml_w: writer::Encoder, fn add_to_index_(item: @item, ebml_w: writer::Encoder, index: @mut ~[entry]) { - index.push({val: item.id, pos: ebml_w.writer.tell()}); + index.push(entry { val: item.id, pos: ebml_w.writer.tell() }); } let add_to_index: &fn() = || add_to_index_(item, ebml_w, index); @@ -673,12 +678,12 @@ fn encode_info_for_item(ecx: @encode_ctxt, ebml_w: writer::Encoder, struct_def.fields, index); /* Encode the dtor */ do struct_def.dtor.iter |dtor| { - index.push({val: dtor.node.id, pos: ebml_w.writer.tell()}); + index.push(entry {val: dtor.node.id, pos: ebml_w.writer.tell()}); encode_info_for_ctor(ecx, ebml_w, dtor.node.id, ecx.tcx.sess.ident_of( - ecx.tcx.sess.str_of(item.ident) + + *ecx.tcx.sess.str_of(item.ident) + ~"_dtor"), path, if tps.len() > 0u { @@ -788,7 +793,7 @@ fn encode_info_for_item(ecx: @encode_ctxt, ebml_w: writer::Encoder, impl_path += ~[ast_map::path_name(item.ident)]; for methods.each |m| { - index.push({val: m.id, pos: ebml_w.writer.tell()}); + index.push(entry {val: m.id, pos: ebml_w.writer.tell()}); encode_info_for_method(ecx, ebml_w, impl_path, should_inline(m.attrs), item.id, *m, @@ -855,7 +860,7 @@ fn encode_info_for_item(ecx: @encode_ctxt, ebml_w: writer::Encoder, let ty_m = ast_util::trait_method_to_ty_method(*m); if ty_m.self_ty.node != ast::sty_static { loop; } - index.push({val: ty_m.id, pos: ebml_w.writer.tell()}); + index.push(entry { val: ty_m.id, pos: ebml_w.writer.tell() }); ebml_w.start_tag(tag_items_data_item); encode_def_id(ebml_w, local_def(ty_m.id)); @@ -874,7 +879,7 @@ fn encode_info_for_item(ecx: @encode_ctxt, ebml_w: writer::Encoder, // Finally, output all the provided methods as items. for provided_methods.each |m| { - index.push({val: m.id, pos: ebml_w.writer.tell()}); + index.push(entry { val: m.id, pos: ebml_w.writer.tell() }); encode_info_for_method(ecx, ebml_w, /*bad*/copy path, true, item.id, *m, /*bad*/copy m.tps); } @@ -883,14 +888,14 @@ fn encode_info_for_item(ecx: @encode_ctxt, ebml_w: writer::Encoder, } } -fn encode_info_for_foreign_item(ecx: @encode_ctxt, +fn encode_info_for_foreign_item(ecx: @EncodeContext, ebml_w: writer::Encoder, nitem: @foreign_item, index: @mut ~[entry], +path: ast_map::path, abi: foreign_abi) { if !reachable(ecx, nitem.id) { return; } - index.push({val: nitem.id, pos: ebml_w.writer.tell()}); + index.push(entry { val: nitem.id, pos: ebml_w.writer.tell() }); ebml_w.start_tag(tag_items_data_item); match /*bad*/copy nitem.node { @@ -917,11 +922,11 @@ fn encode_info_for_foreign_item(ecx: @encode_ctxt, ebml_w.end_tag(); } -fn encode_info_for_items(ecx: @encode_ctxt, ebml_w: writer::Encoder, +fn encode_info_for_items(ecx: @EncodeContext, ebml_w: writer::Encoder, crate: &crate) -> ~[entry] { let index = @mut ~[]; ebml_w.start_tag(tag_items_data); - index.push({val: crate_node_id, pos: ebml_w.writer.tell()}); + index.push(entry { val: crate_node_id, pos: ebml_w.writer.tell() }); encode_info_for_mod(ecx, ebml_w, crate.node.module, crate_node_id, ~[], syntax::parse::token::special_idents::invalid); @@ -964,7 +969,7 @@ fn encode_info_for_items(ecx: @encode_ctxt, ebml_w: writer::Encoder, // Path and definition ID indexing -fn create_index(index: ~[entry]) -> +fn create_index(index: ~[entry]) -> ~[@~[entry]] { let mut buckets: ~[@mut ~[entry]] = ~[]; for uint::range(0u, 256u) |_i| { buckets.push(@mut ~[]); }; @@ -1017,19 +1022,19 @@ fn write_int(writer: io::Writer, &&n: int) { fn encode_meta_item(ebml_w: writer::Encoder, mi: meta_item) { match mi.node { - meta_word(ref name) => { + meta_word(name) => { ebml_w.start_tag(tag_meta_item_word); ebml_w.start_tag(tag_meta_item_name); - ebml_w.writer.write(str::to_bytes((*name))); + ebml_w.writer.write(str::to_bytes(*name)); ebml_w.end_tag(); ebml_w.end_tag(); } - meta_name_value(ref name, value) => { + meta_name_value(name, value) => { match value.node { lit_str(value) => { ebml_w.start_tag(tag_meta_item_name_value); ebml_w.start_tag(tag_meta_item_name); - ebml_w.writer.write(str::to_bytes((*name))); + ebml_w.writer.write(str::to_bytes(*name)); ebml_w.end_tag(); ebml_w.start_tag(tag_meta_item_value); ebml_w.writer.write(str::to_bytes(*value)); @@ -1039,10 +1044,10 @@ fn encode_meta_item(ebml_w: writer::Encoder, mi: meta_item) { _ => {/* FIXME (#623): encode other variants */ } } } - meta_list(ref name, ref items) => { + meta_list(name, ref items) => { ebml_w.start_tag(tag_meta_item_list); ebml_w.start_tag(tag_meta_item_name); - ebml_w.writer.write(str::to_bytes((*name))); + ebml_w.writer.write(str::to_bytes(*name)); ebml_w.end_tag(); for items.each |inner_item| { encode_meta_item(ebml_w, **inner_item); @@ -1066,20 +1071,21 @@ fn encode_attributes(ebml_w: writer::Encoder, attrs: &[attribute]) { // metadata that Rust cares about for linking crates. This attribute requires // 'name' and 'vers' items, so if the user didn't provide them we will throw // them in anyway with default values. -fn synthesize_crate_attrs(ecx: @encode_ctxt, crate: &crate) -> ~[attribute] { +fn synthesize_crate_attrs(ecx: @EncodeContext, + crate: &crate) -> ~[attribute] { - fn synthesize_link_attr(ecx: @encode_ctxt, +items: ~[@meta_item]) -> + fn synthesize_link_attr(ecx: @EncodeContext, +items: ~[@meta_item]) -> attribute { assert !ecx.link_meta.name.is_empty(); assert !ecx.link_meta.vers.is_empty(); let name_item = - attr::mk_name_value_item_str(~"name", - ecx.link_meta.name.to_owned()); + attr::mk_name_value_item_str(@~"name", + @ecx.link_meta.name.to_owned()); let vers_item = - attr::mk_name_value_item_str(~"vers", - ecx.link_meta.vers.to_owned()); + attr::mk_name_value_item_str(@~"vers", + @ecx.link_meta.vers.to_owned()); let other_items = { @@ -1088,7 +1094,7 @@ fn synthesize_crate_attrs(ecx: @encode_ctxt, crate: &crate) -> ~[attribute] { }; let meta_items = vec::append(~[name_item, vers_item], other_items); - let link_item = attr::mk_list_item(~"link", meta_items); + let link_item = attr::mk_list_item(@~"link", meta_items); return attr::mk_attr(link_item); } @@ -1097,7 +1103,7 @@ fn synthesize_crate_attrs(ecx: @encode_ctxt, crate: &crate) -> ~[attribute] { let mut found_link_attr = false; for crate.node.attrs.each |attr| { attrs.push( - if attr::get_attr_name(*attr) != ~"link" { + if *attr::get_attr_name(attr) != ~"link" { /*bad*/copy *attr } else { match /*bad*/copy attr.node.value.node { @@ -1115,29 +1121,25 @@ fn synthesize_crate_attrs(ecx: @encode_ctxt, crate: &crate) -> ~[attribute] { return attrs; } -fn encode_crate_deps(ecx: @encode_ctxt, +fn encode_crate_deps(ecx: @EncodeContext, ebml_w: writer::Encoder, cstore: @mut cstore::CStore) { - fn get_ordered_deps(ecx: @encode_ctxt, cstore: @mut cstore::CStore) + fn get_ordered_deps(ecx: @EncodeContext, cstore: @mut cstore::CStore) -> ~[decoder::crate_dep] { - type hashkv = @{key: crate_num, val: cstore::crate_metadata}; type numdep = decoder::crate_dep; // Pull the cnums and name,vers,hash out of cstore - let mut deps: ~[numdep] = ~[]; + let mut deps = ~[]; do cstore::iter_crate_data(cstore) |key, val| { - let dep = {cnum: key, - name: ecx.tcx.sess.ident_of(/*bad*/copy val.name), + let dep = decoder::crate_dep {cnum: key, + name: ecx.tcx.sess.ident_of(/*bad*/ copy *val.name), vers: decoder::get_crate_vers(val.data), hash: decoder::get_crate_hash(val.data)}; deps.push(dep); }; // Sort by cnum - pure fn lteq(kv1: &numdep, kv2: &numdep) -> bool { - kv1.cnum <= kv2.cnum - } - std::sort::quick_sort(deps, lteq); + std::sort::quick_sort(deps, |kv1, kv2| kv1.cnum <= kv2.cnum); // Sanity-check the crate numbers let mut expected_cnum = 1; @@ -1147,7 +1149,7 @@ fn encode_crate_deps(ecx: @encode_ctxt, } // mut -> immutable hack for vec::map - return vec::slice(deps, 0u, vec::len(deps)); + deps.slice(0, deps.len()) } // We're just going to write a list of crate 'name-hash-version's, with @@ -1161,7 +1163,7 @@ fn encode_crate_deps(ecx: @encode_ctxt, ebml_w.end_tag(); } -fn encode_lang_items(ecx: @encode_ctxt, ebml_w: writer::Encoder) { +fn encode_lang_items(ecx: @EncodeContext, ebml_w: writer::Encoder) { ebml_w.start_tag(tag_lang_items); for ecx.tcx.lang_items.each_item |def_id, i| { @@ -1185,17 +1187,17 @@ fn encode_lang_items(ecx: @encode_ctxt, ebml_w: writer::Encoder) { ebml_w.end_tag(); // tag_lang_items } -fn encode_crate_dep(ecx: @encode_ctxt, ebml_w: writer::Encoder, +fn encode_crate_dep(ecx: @EncodeContext, ebml_w: writer::Encoder, dep: decoder::crate_dep) { ebml_w.start_tag(tag_crate_dep); ebml_w.start_tag(tag_crate_dep_name); - ebml_w.writer.write(str::to_bytes(ecx.tcx.sess.str_of(dep.name))); + ebml_w.writer.write(str::to_bytes(*ecx.tcx.sess.str_of(dep.name))); ebml_w.end_tag(); ebml_w.start_tag(tag_crate_dep_vers); - ebml_w.writer.write(str::to_bytes(dep.vers)); + ebml_w.writer.write(str::to_bytes(*dep.vers)); ebml_w.end_tag(); ebml_w.start_tag(tag_crate_dep_hash); - ebml_w.writer.write(str::to_bytes(dep.hash)); + ebml_w.writer.write(str::to_bytes(*dep.hash)); ebml_w.end_tag(); ebml_w.end_tag(); } @@ -1213,7 +1215,7 @@ pub const metadata_encoding_version : &[u8] = &[0x72, //'r' as u8, 0x74, //'t' as u8, 0, 0, 0, 1 ]; -pub fn encode_metadata(parms: encode_parms, crate: &crate) -> ~[u8] { +pub fn encode_metadata(parms: EncodeParams, crate: &crate) -> ~[u8] { let wr = @io::BytesWriter(); let mut stats = Stats { inline_bytes: 0, @@ -1226,10 +1228,10 @@ pub fn encode_metadata(parms: encode_parms, crate: &crate) -> ~[u8] { total_bytes: 0, n_inlines: 0 }; - let ecx: @encode_ctxt = @encode_ctxt({ + let ecx = @EncodeContext { diag: parms.diag, tcx: parms.tcx, - stats: @mut move stats, + stats: @mut stats, reachable: parms.reachable, reexports2: parms.reexports2, item_symbols: parms.item_symbols, @@ -1238,7 +1240,7 @@ pub fn encode_metadata(parms: encode_parms, crate: &crate) -> ~[u8] { cstore: parms.cstore, encode_inlined_item: parms.encode_inlined_item, type_abbrevs: ty::new_ty_hash() - }); + }; let ebml_w = writer::Encoder(wr as io::Writer); @@ -1307,7 +1309,7 @@ pub fn encode_metadata(parms: encode_parms, crate: &crate) -> ~[u8] { // vec::from_slice(metadata_encoding_version) + (do str::as_bytes(&~"rust\x00\x00\x00\x01") |bytes| { - vec::slice(*bytes, 0, 8) + vec::slice(*bytes, 0, 8).to_vec() }) + flate::deflate_bytes(wr.bytes.check_out(|buf| buf)) } diff --git a/src/librustc/metadata/filesearch.rs b/src/librustc/metadata/filesearch.rs index ed4ea665aafcd..82ea0b6d6f186 100644 --- a/src/librustc/metadata/filesearch.rs +++ b/src/librustc/metadata/filesearch.rs @@ -29,52 +29,56 @@ pub fn pick_file(file: Path, path: &Path) -> Option { } pub trait FileSearch { - fn sysroot() -> Path; - fn lib_search_paths() -> ~[Path]; - fn get_target_lib_path() -> Path; - fn get_target_lib_file_path(file: &Path) -> Path; + fn sysroot(&self) -> Path; + fn lib_search_paths(&self) -> ~[Path]; + fn get_target_lib_path(&self) -> Path; + fn get_target_lib_file_path(&self, file: &Path) -> Path; } pub fn mk_filesearch(maybe_sysroot: Option, target_triple: &str, +addl_lib_search_paths: ~[Path]) -> FileSearch { - type filesearch_impl = {sysroot: Path, - addl_lib_search_paths: ~[Path], - target_triple: ~str}; - impl FileSearch for filesearch_impl { - fn sysroot() -> Path { /*bad*/copy self.sysroot } - fn lib_search_paths() -> ~[Path] { + struct FileSearchImpl { + sysroot: Path, + addl_lib_search_paths: ~[Path], + target_triple: ~str + } + impl FileSearch for FileSearchImpl { + fn sysroot(&self) -> Path { /*bad*/copy self.sysroot } + fn lib_search_paths(&self) -> ~[Path] { let mut paths = /*bad*/copy self.addl_lib_search_paths; paths.push( make_target_lib_path(&self.sysroot, self.target_triple)); - match get_cargo_lib_path_nearest() { + match get_rustpkg_lib_path_nearest() { result::Ok(ref p) => paths.push((/*bad*/copy *p)), result::Err(_) => () } - match get_cargo_lib_path() { + match get_rustpkg_lib_path() { result::Ok(ref p) => paths.push((/*bad*/copy *p)), result::Err(_) => () } paths } - fn get_target_lib_path() -> Path { + fn get_target_lib_path(&self) -> Path { make_target_lib_path(&self.sysroot, self.target_triple) } - fn get_target_lib_file_path(file: &Path) -> Path { + fn get_target_lib_file_path(&self, file: &Path) -> Path { self.get_target_lib_path().push_rel(file) } } let sysroot = get_sysroot(maybe_sysroot); debug!("using sysroot = %s", sysroot.to_str()); - {sysroot: sysroot, - addl_lib_search_paths: addl_lib_search_paths, - target_triple: str::from_slice(target_triple)} as FileSearch + FileSearchImpl { + sysroot: sysroot, + addl_lib_search_paths: addl_lib_search_paths, + target_triple: str::from_slice(target_triple) + } as FileSearch } -pub fn search(filesearch: FileSearch, pick: pick) -> Option { +pub fn search(filesearch: FileSearch, pick: pick) -> Option { let mut rslt = None; for filesearch.lib_search_paths().each |lib_search_path| { debug!("searching %s", lib_search_path.to_str()); @@ -119,54 +123,54 @@ fn get_sysroot(maybe_sysroot: Option) -> Path { } } -pub fn get_cargo_sysroot() -> Result { - result::Ok(get_or_default_sysroot().push_many([libdir(), ~"cargo"])) +pub fn get_rustpkg_sysroot() -> Result { + result::Ok(get_or_default_sysroot().push_many([libdir(), ~"rustpkg"])) } -pub fn get_cargo_root() -> Result { - match os::getenv(~"CARGO_ROOT") { +pub fn get_rustpkg_root() -> Result { + match os::getenv(~"RUSTPKG_ROOT") { Some(ref _p) => result::Ok(Path((*_p))), None => match os::homedir() { - Some(ref _q) => result::Ok((*_q).push(".cargo")), - None => result::Err(~"no CARGO_ROOT or home directory") + Some(ref _q) => result::Ok((*_q).push(".rustpkg")), + None => result::Err(~"no RUSTPKG_ROOT or home directory") } } } -pub fn get_cargo_root_nearest() -> Result { - do result::chain(get_cargo_root()) |p| { +pub fn get_rustpkg_root_nearest() -> Result { + do result::chain(get_rustpkg_root()) |p| { let cwd = os::getcwd(); - let cwd_cargo = cwd.push(".cargo"); - let cargo_is_non_root_file = - !os::path_is_dir(&cwd_cargo) && cwd_cargo != p; - let mut par_cargo = cwd.pop().push(".cargo"); - let mut rslt = result::Ok(cwd_cargo); - - if cargo_is_non_root_file { - while par_cargo != p { - if os::path_is_dir(&par_cargo) { - rslt = result::Ok(par_cargo); + let cwd_rustpkg = cwd.push(".rustpkg"); + let rustpkg_is_non_root_file = + !os::path_is_dir(&cwd_rustpkg) && cwd_rustpkg != p; + let mut par_rustpkg = cwd.pop().push(".rustpkg"); + let mut rslt = result::Ok(cwd_rustpkg); + + if rustpkg_is_non_root_file { + while par_rustpkg != p { + if os::path_is_dir(&par_rustpkg) { + rslt = result::Ok(par_rustpkg); break; } - if par_cargo.components.len() == 1 { - // We just checked /.cargo, stop now. + if par_rustpkg.components.len() == 1 { + // We just checked /.rustpkg, stop now. break; } - par_cargo = par_cargo.pop().pop().push(".cargo"); + par_rustpkg = par_rustpkg.pop().pop().push(".rustpkg"); } } rslt } } -fn get_cargo_lib_path() -> Result { - do result::chain(get_cargo_root()) |p| { +fn get_rustpkg_lib_path() -> Result { + do result::chain(get_rustpkg_root()) |p| { result::Ok(p.push(libdir())) } } -fn get_cargo_lib_path_nearest() -> Result { - do result::chain(get_cargo_root_nearest()) |p| { +fn get_rustpkg_lib_path_nearest() -> Result { + do result::chain(get_rustpkg_root_nearest()) |p| { result::Ok(p.push(libdir())) } } diff --git a/src/librustc/metadata/loader.rs b/src/librustc/metadata/loader.rs index 9e5b1db879f0c..da7f3635c0e24 100644 --- a/src/librustc/metadata/loader.rs +++ b/src/librustc/metadata/loader.rs @@ -43,19 +43,19 @@ pub enum os { os_freebsd } -pub type ctxt = { +pub struct Context { diag: span_handler, filesearch: FileSearch, span: span, ident: ast::ident, metas: ~[@ast::meta_item], - hash: ~str, + hash: @~str, os: os, - static: bool, + is_static: bool, intr: @ident_interner -}; +} -pub fn load_library_crate(cx: ctxt) -> {ident: ~str, data: @~[u8]} { +pub fn load_library_crate(cx: Context) -> (~str, @~[u8]) { match find_library_crate(cx) { Some(ref t) => return (/*bad*/copy *t), None => { @@ -66,13 +66,13 @@ pub fn load_library_crate(cx: ctxt) -> {ident: ~str, data: @~[u8]} { } } -fn find_library_crate(cx: ctxt) -> Option<{ident: ~str, data: @~[u8]}> { +fn find_library_crate(cx: Context) -> Option<(~str, @~[u8])> { attr::require_unique_names(cx.diag, cx.metas); find_library_crate_aux(cx, libname(cx), cx.filesearch) } -fn libname(cx: ctxt) -> {prefix: ~str, suffix: ~str} { - if cx.static { return {prefix: ~"lib", suffix: ~".rlib"}; } +fn libname(cx: Context) -> (~str, ~str) { + if cx.is_static { return (~"lib", ~".rlib"); } let (dll_prefix, dll_suffix) = match cx.os { os_win32 => (win32::DLL_PREFIX, win32::DLL_SUFFIX), os_macos => (macos::DLL_PREFIX, macos::DLL_SUFFIX), @@ -80,19 +80,17 @@ fn libname(cx: ctxt) -> {prefix: ~str, suffix: ~str} { os_android => (android::DLL_PREFIX, android::DLL_SUFFIX), os_freebsd => (freebsd::DLL_PREFIX, freebsd::DLL_SUFFIX), }; - return { - prefix: str::from_slice(dll_prefix), - suffix: str::from_slice(dll_suffix) - } + + (str::from_slice(dll_prefix), str::from_slice(dll_suffix)) } -fn find_library_crate_aux(cx: ctxt, - nn: {prefix: ~str, suffix: ~str}, +fn find_library_crate_aux(cx: Context, + (prefix, suffix): (~str, ~str), filesearch: filesearch::FileSearch) -> - Option<{ident: ~str, data: @~[u8]}> { + Option<(~str, @~[u8])> { let crate_name = crate_name_from_metas(/*bad*/copy cx.metas); - let prefix: ~str = nn.prefix + crate_name + ~"-"; - let suffix: ~str = /*bad*/copy nn.suffix; + let prefix: ~str = prefix + *crate_name + ~"-"; + let suffix: ~str = /*bad*/copy suffix; let mut matches = ~[]; filesearch::search(filesearch, |path| { @@ -112,7 +110,7 @@ fn find_library_crate_aux(cx: ctxt, option::None::<()> } else { debug!("found %s with matching metadata", path.to_str()); - matches.push({ident: path.to_str(), data: cvec}); + matches.push((path.to_str(), cvec)); option::None::<()> } } @@ -130,11 +128,11 @@ fn find_library_crate_aux(cx: ctxt, Some(/*bad*/copy matches[0]) } else { cx.diag.span_err( - cx.span, fmt!("multiple matching crates for `%s`", crate_name)); + cx.span, fmt!("multiple matching crates for `%s`", *crate_name)); cx.diag.handler().note(~"candidates:"); - for matches.each |match_| { - cx.diag.handler().note(fmt!("path: %s", match_.ident)); - let attrs = decoder::get_crate_attributes(match_.data); + for matches.each |&(ident, data)| { + cx.diag.handler().note(fmt!("path: %s", ident)); + let attrs = decoder::get_crate_attributes(data); note_linkage_attrs(cx.intr, cx.diag, attrs); } cx.diag.handler().abort_if_errors(); @@ -142,18 +140,18 @@ fn find_library_crate_aux(cx: ctxt, } } -pub fn crate_name_from_metas(+metas: ~[@ast::meta_item]) -> ~str { +pub fn crate_name_from_metas(+metas: &[@ast::meta_item]) -> @~str { let name_items = attr::find_meta_items_by_name(metas, ~"name"); match vec::last_opt(name_items) { - Some(i) => { - match attr::get_meta_item_value_str(i) { - Some(ref n) => (/*bad*/copy *n), - // FIXME (#2406): Probably want a warning here since the user - // is using the wrong type of meta item. - _ => fail!() + Some(i) => { + match attr::get_meta_item_value_str(i) { + Some(n) => n, + // FIXME (#2406): Probably want a warning here since the user + // is using the wrong type of meta item. + _ => fail!() + } } - } - None => fail!(~"expected to find the crate name") + None => fail!(~"expected to find the crate name") } } @@ -167,7 +165,7 @@ pub fn note_linkage_attrs(intr: @ident_interner, diag: span_handler, fn crate_matches(crate_data: @~[u8], metas: &[@ast::meta_item], - hash: ~str) -> bool { + hash: @~str) -> bool { let attrs = decoder::get_crate_attributes(crate_data); let linkage_metas = attr::find_linkage_metas(attrs); if !hash.is_empty() { @@ -228,7 +226,7 @@ fn get_metadata_section(os: os, csz - vlen); do vec::raw::buf_as_slice(cvbuf1, csz-vlen) |bytes| { let inflated = flate::inflate_bytes(bytes); - found = move Some(@(move inflated)); + found = Some(@(inflated)); } if found != None { return found; diff --git a/src/librustc/metadata/tydecode.rs b/src/librustc/metadata/tydecode.rs index 2599ceb2ef16e..8da6ddda4b319 100644 --- a/src/librustc/metadata/tydecode.rs +++ b/src/librustc/metadata/tydecode.rs @@ -493,8 +493,8 @@ pub fn parse_def_id(buf: &[u8]) -> ast::def_id { fail!(); } - let crate_part = vec::view(buf, 0u, colon_idx); - let def_part = vec::view(buf, colon_idx + 1u, len); + let crate_part = vec::slice(buf, 0u, colon_idx); + let def_part = vec::slice(buf, colon_idx + 1u, len); let crate_num = match uint::parse_bytes(crate_part, 10u) { Some(cn) => cn as int, diff --git a/src/librustc/metadata/tyencode.rs b/src/librustc/metadata/tyencode.rs index 252de54cb9bbd..12d998ee9448f 100644 --- a/src/librustc/metadata/tyencode.rs +++ b/src/librustc/metadata/tyencode.rs @@ -39,7 +39,11 @@ pub struct ctxt { // Compact string representation for ty.t values. API ty_str & parse_from_str. // Extra parameters are for converting to/from def_ids in the string rep. // Whatever format you choose should not contain pipe characters. -pub type ty_abbrev = {pos: uint, len: uint, s: @~str}; +pub struct ty_abbrev { + pos: uint, + len: uint, + s: @~str +} pub enum abbrev_ctxt { ac_no_abbrevs, @@ -100,7 +104,7 @@ pub fn enc_ty(w: io::Writer, cx: @ctxt, t: ty::t) { // I.e. it's actually an abbreviation. let s = ~"#" + uint::to_str_radix(pos, 16u) + ~":" + uint::to_str_radix(len, 16u) + ~"#"; - let a = {pos: pos, len: len, s: @s}; + let a = ty_abbrev { pos: pos, len: len, s: @s }; abbrevs.insert(t, a); } return; @@ -175,7 +179,7 @@ fn enc_bound_region(w: io::Writer, cx: @ctxt, br: ty::bound_region) { } ty::br_named(s) => { w.write_char('['); - w.write_str(cx.tcx.sess.str_of(s)); + w.write_str(*cx.tcx.sess.str_of(s)); w.write_char(']') } ty::br_cap_avoid(id, br) => { @@ -282,7 +286,7 @@ fn enc_sty(w: io::Writer, cx: @ctxt, +st: ty::sty) { ty::ty_rec(fields) => { w.write_str(&"R["); for fields.each |field| { - w.write_str(cx.tcx.sess.str_of(field.ident)); + w.write_str(*cx.tcx.sess.str_of(field.ident)); w.write_char('='); enc_mt(w, cx, field.mt); } diff --git a/src/librustc/middle/astencode.rs b/src/librustc/middle/astencode.rs index 3b84216b2e6db..0b1abd683b122 100644 --- a/src/librustc/middle/astencode.rs +++ b/src/librustc/middle/astencode.rs @@ -62,41 +62,37 @@ pub struct Maps { capture_map: middle::moves::CaptureMap, } -type decode_ctxt = @{ - cdata: cstore::crate_metadata, +struct DecodeContext { + cdata: @cstore::crate_metadata, tcx: ty::ctxt, maps: Maps -}; +} -type extended_decode_ctxt_ = { - dcx: decode_ctxt, +struct ExtendedDecodeContext { + dcx: @DecodeContext, from_id_range: ast_util::id_range, to_id_range: ast_util::id_range -}; - -enum extended_decode_ctxt { - extended_decode_ctxt_(@extended_decode_ctxt_) } trait tr { - fn tr(xcx: extended_decode_ctxt) -> Self; + fn tr(&self, xcx: @ExtendedDecodeContext) -> Self; } trait tr_intern { - fn tr_intern(xcx: extended_decode_ctxt) -> ast::def_id; + fn tr_intern(&self, xcx: @ExtendedDecodeContext) -> ast::def_id; } // ______________________________________________________________________ // Top-level methods. -pub fn encode_inlined_item(ecx: @e::encode_ctxt, +pub fn encode_inlined_item(ecx: @e::EncodeContext, ebml_w: writer::Encoder, path: &[ast_map::path_elt], ii: ast::inlined_item, maps: Maps) { debug!("> Encoding inlined item: %s::%s (%u)", ast_map::path_to_str(path, ecx.tcx.sess.parse_sess.interner), - ecx.tcx.sess.str_of(ii.ident()), + *ecx.tcx.sess.str_of(ii.ident()), ebml_w.writer.tell()); let id_range = ast_util::compute_id_range_for_inlined_item(ii); @@ -108,17 +104,21 @@ pub fn encode_inlined_item(ecx: @e::encode_ctxt, debug!("< Encoded inlined fn: %s::%s (%u)", ast_map::path_to_str(path, ecx.tcx.sess.parse_sess.interner), - ecx.tcx.sess.str_of(ii.ident()), + *ecx.tcx.sess.str_of(ii.ident()), ebml_w.writer.tell()); } -pub fn decode_inlined_item(cdata: cstore::crate_metadata, +pub fn decode_inlined_item(cdata: @cstore::crate_metadata, tcx: ty::ctxt, maps: Maps, +path: ast_map::path, par_doc: ebml::Doc) -> Option { - let dcx = @{cdata: cdata, tcx: tcx, maps: maps}; + let dcx = @DecodeContext { + cdata: cdata, + tcx: tcx, + maps: maps + }; match par_doc.opt_child(c::tag_ast) { None => None, Some(ast_doc) => { @@ -127,15 +127,17 @@ pub fn decode_inlined_item(cdata: cstore::crate_metadata, let ast_dsr = &reader::Decoder(ast_doc); let from_id_range = Decodable::decode(ast_dsr); let to_id_range = reserve_id_range(dcx.tcx.sess, from_id_range); - let xcx = extended_decode_ctxt_(@{dcx: dcx, - from_id_range: from_id_range, - to_id_range: to_id_range}); + let xcx = @ExtendedDecodeContext { + dcx: dcx, + from_id_range: from_id_range, + to_id_range: to_id_range + }; let raw_ii = decode_ast(ast_doc); let ii = renumber_ast(xcx, raw_ii); - debug!("Fn named: %s", tcx.sess.str_of(ii.ident())); + debug!("Fn named: %s", *tcx.sess.str_of(ii.ident())); debug!("< Decoded inlined fn: %s::%s", ast_map::path_to_str(path, tcx.sess.parse_sess.interner), - tcx.sess.str_of(ii.ident())); + *tcx.sess.str_of(ii.ident())); ast_map::map_decoded_item(tcx.sess.diagnostic(), dcx.tcx.items, path, ii); decode_side_tables(xcx, ast_doc); @@ -165,8 +167,8 @@ fn reserve_id_range(sess: Session, ast_util::id_range { min: to_id_min, max: to_id_min } } -impl extended_decode_ctxt { - fn tr_id(id: ast::node_id) -> ast::node_id { +impl ExtendedDecodeContext { + fn tr_id(&self, id: ast::node_id) -> ast::node_id { /*! * * Translates an internal id, meaning a node id that is known @@ -182,7 +184,7 @@ impl extended_decode_ctxt { assert !ast_util::empty(self.from_id_range); (id - self.from_id_range.min + self.to_id_range.min) } - fn tr_def_id(did: ast::def_id) -> ast::def_id { + fn tr_def_id(&self, did: ast::def_id) -> ast::def_id { /*! * * Translates an EXTERNAL def-id, converting the crate number @@ -207,7 +209,7 @@ impl extended_decode_ctxt { decoder::translate_def_id(self.dcx.cdata, did) } - fn tr_intern_def_id(did: ast::def_id) -> ast::def_id { + fn tr_intern_def_id(&self, did: ast::def_id) -> ast::def_id { /*! * * Translates an INTERNAL def-id, meaning a def-id that is @@ -219,47 +221,47 @@ impl extended_decode_ctxt { assert did.crate == ast::local_crate; ast::def_id { crate: ast::local_crate, node: self.tr_id(did.node) } } - fn tr_span(_span: span) -> span { + fn tr_span(&self, _span: span) -> span { codemap::dummy_sp() // FIXME (#1972): handle span properly } } impl tr_intern for ast::def_id { - fn tr_intern(xcx: extended_decode_ctxt) -> ast::def_id { - xcx.tr_intern_def_id(self) + fn tr_intern(&self, xcx: @ExtendedDecodeContext) -> ast::def_id { + xcx.tr_intern_def_id(*self) } } impl tr for ast::def_id { - fn tr(xcx: extended_decode_ctxt) -> ast::def_id { - xcx.tr_def_id(self) + fn tr(&self, xcx: @ExtendedDecodeContext) -> ast::def_id { + xcx.tr_def_id(*self) } } impl tr for span { - fn tr(xcx: extended_decode_ctxt) -> span { - xcx.tr_span(self) + fn tr(&self, xcx: @ExtendedDecodeContext) -> span { + xcx.tr_span(*self) } } trait def_id_encoder_helpers { - fn emit_def_id(did: ast::def_id); + fn emit_def_id(&self, did: ast::def_id); } -impl def_id_encoder_helpers for S { - fn emit_def_id(did: ast::def_id) { - did.encode(&self) +impl def_id_encoder_helpers for S { + fn emit_def_id(&self, did: ast::def_id) { + did.encode(self) } } trait def_id_decoder_helpers { - fn read_def_id(xcx: extended_decode_ctxt) -> ast::def_id; + fn read_def_id(&self, xcx: @ExtendedDecodeContext) -> ast::def_id; } -impl def_id_decoder_helpers for D { +impl def_id_decoder_helpers for D { - fn read_def_id(xcx: extended_decode_ctxt) -> ast::def_id { - let did: ast::def_id = Decodable::decode(&self); + fn read_def_id(&self, xcx: @ExtendedDecodeContext) -> ast::def_id { + let did: ast::def_id = Decodable::decode(self); did.tr(xcx) } } @@ -351,7 +353,7 @@ fn decode_ast(par_doc: ebml::Doc) -> ast::inlined_item { Decodable::decode(d) } -fn renumber_ast(xcx: extended_decode_ctxt, ii: ast::inlined_item) +fn renumber_ast(xcx: @ExtendedDecodeContext, ii: ast::inlined_item) -> ast::inlined_item { let fld = fold::make_fold(@fold::AstFoldFns{ new_id: |a| xcx.tr_id(a), @@ -396,15 +398,15 @@ fn encode_def(ebml_w: writer::Encoder, def: ast::def) { def.encode(&ebml_w) } -fn decode_def(xcx: extended_decode_ctxt, doc: ebml::Doc) -> ast::def { +fn decode_def(xcx: @ExtendedDecodeContext, doc: ebml::Doc) -> ast::def { let dsr = &reader::Decoder(doc); let def: ast::def = Decodable::decode(dsr); def.tr(xcx) } impl tr for ast::def { - fn tr(xcx: extended_decode_ctxt) -> ast::def { - match self { + fn tr(&self, xcx: @ExtendedDecodeContext) -> ast::def { + match *self { ast::def_fn(did, p) => { ast::def_fn(did.tr(xcx), p) } ast::def_static_method(did, did2_opt, p) => { ast::def_static_method(did.tr(xcx), @@ -448,7 +450,7 @@ impl tr for ast::def { // Encoding and decoding of adjustment information impl tr for ty::AutoAdjustment { - fn tr(xcx: extended_decode_ctxt) -> ty::AutoAdjustment { + fn tr(&self, xcx: @ExtendedDecodeContext) -> ty::AutoAdjustment { ty::AutoAdjustment { autoderefs: self.autoderefs, autoref: self.autoref.map(|ar| ar.tr(xcx)), @@ -457,7 +459,7 @@ impl tr for ty::AutoAdjustment { } impl tr for ty::AutoRef { - fn tr(xcx: extended_decode_ctxt) -> ty::AutoRef { + fn tr(&self, xcx: @ExtendedDecodeContext) -> ty::AutoRef { ty::AutoRef { kind: self.kind, region: self.region.tr(xcx), @@ -467,21 +469,21 @@ impl tr for ty::AutoRef { } impl tr for ty::Region { - fn tr(xcx: extended_decode_ctxt) -> ty::Region { - match self { + fn tr(&self, xcx: @ExtendedDecodeContext) -> ty::Region { + match *self { ty::re_bound(br) => ty::re_bound(br.tr(xcx)), ty::re_free(id, br) => ty::re_free(xcx.tr_id(id), br.tr(xcx)), ty::re_scope(id) => ty::re_scope(xcx.tr_id(id)), - ty::re_static | ty::re_infer(*) => self, + ty::re_static | ty::re_infer(*) => *self, } } } impl tr for ty::bound_region { - fn tr(xcx: extended_decode_ctxt) -> ty::bound_region { - match self { + fn tr(&self, xcx: @ExtendedDecodeContext) -> ty::bound_region { + match *self { ty::br_anon(_) | ty::br_named(_) | ty::br_self | - ty::br_fresh(_) => self, + ty::br_fresh(_) => *self, ty::br_cap_avoid(id, br) => ty::br_cap_avoid(xcx.tr_id(id), @br.tr(xcx)) } @@ -496,18 +498,20 @@ fn encode_freevar_entry(ebml_w: writer::Encoder, fv: @freevar_entry) { } trait ebml_decoder_helper { - fn read_freevar_entry(xcx: extended_decode_ctxt) -> freevar_entry; + fn read_freevar_entry(&self, xcx: @ExtendedDecodeContext) + -> freevar_entry; } impl ebml_decoder_helper for reader::Decoder { - fn read_freevar_entry(xcx: extended_decode_ctxt) -> freevar_entry { - let fv: freevar_entry = Decodable::decode(&self); + fn read_freevar_entry(&self, xcx: @ExtendedDecodeContext) + -> freevar_entry { + let fv: freevar_entry = Decodable::decode(self); fv.tr(xcx) } } impl tr for freevar_entry { - fn tr(xcx: extended_decode_ctxt) -> freevar_entry { + fn tr(&self, xcx: @ExtendedDecodeContext) -> freevar_entry { freevar_entry { def: self.def.tr(xcx), span: self.span.tr(xcx), @@ -519,18 +523,20 @@ impl tr for freevar_entry { // Encoding and decoding of CaptureVar information trait capture_var_helper { - fn read_capture_var(xcx: extended_decode_ctxt) -> moves::CaptureVar; + fn read_capture_var(&self, xcx: @ExtendedDecodeContext) + -> moves::CaptureVar; } impl capture_var_helper for reader::Decoder { - fn read_capture_var(xcx: extended_decode_ctxt) -> moves::CaptureVar { - let cvar: moves::CaptureVar = Decodable::decode(&self); + fn read_capture_var(&self, xcx: @ExtendedDecodeContext) + -> moves::CaptureVar { + let cvar: moves::CaptureVar = Decodable::decode(self); cvar.tr(xcx) } } impl tr for moves::CaptureVar { - fn tr(xcx: extended_decode_ctxt) -> moves::CaptureVar { + fn tr(&self, xcx: @ExtendedDecodeContext) -> moves::CaptureVar { moves::CaptureVar { def: self.def.tr(xcx), span: self.span.tr(xcx), @@ -543,10 +549,11 @@ impl tr for moves::CaptureVar { // Encoding and decoding of method_map_entry trait read_method_map_entry_helper { - fn read_method_map_entry(xcx: extended_decode_ctxt) -> method_map_entry; + fn read_method_map_entry(&self, xcx: @ExtendedDecodeContext) + -> method_map_entry; } -fn encode_method_map_entry(ecx: @e::encode_ctxt, +fn encode_method_map_entry(ecx: @e::EncodeContext, ebml_w: writer::Encoder, mme: method_map_entry) { do ebml_w.emit_rec { @@ -563,19 +570,20 @@ fn encode_method_map_entry(ecx: @e::encode_ctxt, } impl read_method_map_entry_helper for reader::Decoder { - fn read_method_map_entry(xcx: extended_decode_ctxt) -> method_map_entry { + fn read_method_map_entry(&self, xcx: @ExtendedDecodeContext) + -> method_map_entry { do self.read_rec { method_map_entry { self_arg: self.read_field(~"self_arg", 0u, || { self.read_arg(xcx) }), explicit_self: self.read_field(~"explicit_self", 2u, || { - let self_type: ast::self_ty_ = Decodable::decode(&self); + let self_type: ast::self_ty_ = Decodable::decode(self); self_type }), origin: self.read_field(~"origin", 1u, || { let method_origin: method_origin = - Decodable::decode(&self); + Decodable::decode(self); method_origin.tr(xcx) }), } @@ -584,8 +592,8 @@ impl read_method_map_entry_helper for reader::Decoder { } impl tr for method_origin { - fn tr(xcx: extended_decode_ctxt) -> method_origin { - match self { + fn tr(&self, xcx: @ExtendedDecodeContext) -> method_origin { + match *self { typeck::method_static(did) => { typeck::method_static(did.tr(xcx)) } @@ -613,7 +621,7 @@ impl tr for method_origin { // ______________________________________________________________________ // Encoding and decoding vtable_res -fn encode_vtable_res(ecx: @e::encode_ctxt, +fn encode_vtable_res(ecx: @e::EncodeContext, ebml_w: writer::Encoder, dr: typeck::vtable_res) { // can't autogenerate this code because automatic code of @@ -625,7 +633,7 @@ fn encode_vtable_res(ecx: @e::encode_ctxt, } } -fn encode_vtable_origin(ecx: @e::encode_ctxt, +fn encode_vtable_origin(ecx: @e::EncodeContext, ebml_w: writer::Encoder, vtable_origin: typeck::vtable_origin) { do ebml_w.emit_enum(~"vtable_origin") { @@ -669,16 +677,19 @@ fn encode_vtable_origin(ecx: @e::encode_ctxt, } trait vtable_decoder_helpers { - fn read_vtable_res(xcx: extended_decode_ctxt) -> typeck::vtable_res; - fn read_vtable_origin(xcx: extended_decode_ctxt) -> typeck::vtable_origin; + fn read_vtable_res(&self, xcx: @ExtendedDecodeContext) + -> typeck::vtable_res; + fn read_vtable_origin(&self, xcx: @ExtendedDecodeContext) + -> typeck::vtable_origin; } impl vtable_decoder_helpers for reader::Decoder { - fn read_vtable_res(xcx: extended_decode_ctxt) -> typeck::vtable_res { + fn read_vtable_res(&self, xcx: @ExtendedDecodeContext) + -> typeck::vtable_res { @self.read_to_vec(|| self.read_vtable_origin(xcx) ) } - fn read_vtable_origin(xcx: extended_decode_ctxt) + fn read_vtable_origin(&self, xcx: @ExtendedDecodeContext) -> typeck::vtable_origin { do self.read_enum(~"vtable_origin") { do self.read_enum_variant |i| { @@ -731,7 +742,8 @@ trait get_ty_str_ctxt { fn ty_str_ctxt() -> @tyencode::ctxt; } -impl get_ty_str_ctxt for @e::encode_ctxt { +impl get_ty_str_ctxt for @e::EncodeContext { + // IMPLICIT SELF WARNING: fix this! fn ty_str_ctxt() -> @tyencode::ctxt { @tyencode::ctxt {diag: self.tcx.sess.diagnostic(), ds: e::def_to_str, @@ -742,46 +754,48 @@ impl get_ty_str_ctxt for @e::encode_ctxt { } trait ebml_writer_helpers { - fn emit_arg(ecx: @e::encode_ctxt, arg: ty::arg); - fn emit_ty(ecx: @e::encode_ctxt, ty: ty::t); - fn emit_vstore(ecx: @e::encode_ctxt, vstore: ty::vstore); - fn emit_tys(ecx: @e::encode_ctxt, tys: ~[ty::t]); - fn emit_bounds(ecx: @e::encode_ctxt, bs: ty::param_bounds); - fn emit_tpbt(ecx: @e::encode_ctxt, tpbt: ty::ty_param_bounds_and_ty); + fn emit_arg(&self, ecx: @e::EncodeContext, arg: ty::arg); + fn emit_ty(&self, ecx: @e::EncodeContext, ty: ty::t); + fn emit_vstore(&self, ecx: @e::EncodeContext, vstore: ty::vstore); + fn emit_tys(&self, ecx: @e::EncodeContext, tys: ~[ty::t]); + fn emit_bounds(&self, ecx: @e::EncodeContext, bs: ty::param_bounds); + fn emit_tpbt(&self, ecx: @e::EncodeContext, + tpbt: ty::ty_param_bounds_and_ty); } impl ebml_writer_helpers for writer::Encoder { - fn emit_ty(ecx: @e::encode_ctxt, ty: ty::t) { + fn emit_ty(&self, ecx: @e::EncodeContext, ty: ty::t) { do self.emit_opaque { - e::write_type(ecx, self, ty) + e::write_type(ecx, *self, ty) } } - fn emit_vstore(ecx: @e::encode_ctxt, vstore: ty::vstore) { + fn emit_vstore(&self, ecx: @e::EncodeContext, vstore: ty::vstore) { do self.emit_opaque { - e::write_vstore(ecx, self, vstore) + e::write_vstore(ecx, *self, vstore) } } - fn emit_arg(ecx: @e::encode_ctxt, arg: ty::arg) { + fn emit_arg(&self, ecx: @e::EncodeContext, arg: ty::arg) { do self.emit_opaque { tyencode::enc_arg(self.writer, ecx.ty_str_ctxt(), arg); } } - fn emit_tys(ecx: @e::encode_ctxt, tys: ~[ty::t]) { + fn emit_tys(&self, ecx: @e::EncodeContext, tys: ~[ty::t]) { do self.emit_from_vec(tys) |ty| { self.emit_ty(ecx, *ty) } } - fn emit_bounds(ecx: @e::encode_ctxt, bs: ty::param_bounds) { + fn emit_bounds(&self, ecx: @e::EncodeContext, bs: ty::param_bounds) { do self.emit_opaque { tyencode::enc_bounds(self.writer, ecx.ty_str_ctxt(), bs) } } - fn emit_tpbt(ecx: @e::encode_ctxt, tpbt: ty::ty_param_bounds_and_ty) { + fn emit_tpbt(&self, ecx: @e::EncodeContext, + tpbt: ty::ty_param_bounds_and_ty) { do self.emit_rec { do self.emit_field(~"bounds", 0) { do self.emit_from_vec(*tpbt.bounds) |bs| { @@ -789,7 +803,7 @@ impl ebml_writer_helpers for writer::Encoder { } } do self.emit_field(~"region_param", 1u) { - tpbt.region_param.encode(&self); + tpbt.region_param.encode(self); } do self.emit_field(~"ty", 2u) { self.emit_ty(ecx, tpbt.ty); @@ -799,21 +813,21 @@ impl ebml_writer_helpers for writer::Encoder { } trait write_tag_and_id { - fn tag(tag_id: c::astencode_tag, f: fn()); - fn id(id: ast::node_id); + fn tag(&self, tag_id: c::astencode_tag, f: fn()); + fn id(&self, id: ast::node_id); } impl write_tag_and_id for writer::Encoder { - fn tag(tag_id: c::astencode_tag, f: fn()) { + fn tag(&self, tag_id: c::astencode_tag, f: fn()) { do self.wr_tag(tag_id as uint) { f() } } - fn id(id: ast::node_id) { + fn id(&self, id: ast::node_id) { self.wr_tagged_u64(c::tag_table_id as uint, id as u64) } } -fn encode_side_tables_for_ii(ecx: @e::encode_ctxt, +fn encode_side_tables_for_ii(ecx: @e::EncodeContext, maps: Maps, ebml_w: writer::Encoder, ii: ast::inlined_item) { @@ -821,7 +835,7 @@ fn encode_side_tables_for_ii(ecx: @e::encode_ctxt, let ebml_w = copy ebml_w; ast_util::visit_ids_for_inlined_item( ii, - fn@(id: ast::node_id, copy ebml_w) { + fn@(id: ast::node_id) { // Note: this will cause a copy of ebml_w, which is bad as // it has mut fields. But I believe it's harmless since // we generate balanced EBML. @@ -830,7 +844,7 @@ fn encode_side_tables_for_ii(ecx: @e::encode_ctxt, } } -fn encode_side_tables_for_id(ecx: @e::encode_ctxt, +fn encode_side_tables_for_id(ecx: @e::EncodeContext, maps: Maps, ebml_w: writer::Encoder, id: ast::node_id) { @@ -977,31 +991,31 @@ fn encode_side_tables_for_id(ecx: @e::encode_ctxt, } trait doc_decoder_helpers { - fn as_int() -> int; - fn opt_child(tag: c::astencode_tag) -> Option; + fn as_int(&self) -> int; + fn opt_child(&self, tag: c::astencode_tag) -> Option; } impl doc_decoder_helpers for ebml::Doc { - fn as_int() -> int { reader::doc_as_u64(self) as int } - fn opt_child(tag: c::astencode_tag) -> Option { - reader::maybe_get_doc(self, tag as uint) + fn as_int(&self) -> int { reader::doc_as_u64(*self) as int } + fn opt_child(&self, tag: c::astencode_tag) -> Option { + reader::maybe_get_doc(*self, tag as uint) } } trait ebml_decoder_decoder_helpers { - fn read_arg(xcx: extended_decode_ctxt) -> ty::arg; - fn read_ty(xcx: extended_decode_ctxt) -> ty::t; - fn read_tys(xcx: extended_decode_ctxt) -> ~[ty::t]; - fn read_bounds(xcx: extended_decode_ctxt) -> @~[ty::param_bound]; - fn read_ty_param_bounds_and_ty(xcx: extended_decode_ctxt) + fn read_arg(&self, xcx: @ExtendedDecodeContext) -> ty::arg; + fn read_ty(&self, xcx: @ExtendedDecodeContext) -> ty::t; + fn read_tys(&self, xcx: @ExtendedDecodeContext) -> ~[ty::t]; + fn read_bounds(&self, xcx: @ExtendedDecodeContext) -> @~[ty::param_bound]; + fn read_ty_param_bounds_and_ty(&self, xcx: @ExtendedDecodeContext) -> ty::ty_param_bounds_and_ty; - fn convert_def_id(xcx: extended_decode_ctxt, + fn convert_def_id(&self, xcx: @ExtendedDecodeContext, source: DefIdSource, did: ast::def_id) -> ast::def_id; } impl ebml_decoder_decoder_helpers for reader::Decoder { - fn read_arg(xcx: extended_decode_ctxt) -> ty::arg { + fn read_arg(&self, xcx: @ExtendedDecodeContext) -> ty::arg { do self.read_opaque |doc| { tydecode::parse_arg_data( doc.data, xcx.dcx.cdata.cnum, doc.start, xcx.dcx.tcx, @@ -1009,7 +1023,7 @@ impl ebml_decoder_decoder_helpers for reader::Decoder { } } - fn read_ty(xcx: extended_decode_ctxt) -> ty::t { + fn read_ty(&self, xcx: @ExtendedDecodeContext) -> ty::t { // Note: regions types embed local node ids. In principle, we // should translate these node ids into the new decode // context. However, we do not bother, because region types @@ -1036,11 +1050,12 @@ impl ebml_decoder_decoder_helpers for reader::Decoder { } } - fn read_tys(xcx: extended_decode_ctxt) -> ~[ty::t] { + fn read_tys(&self, xcx: @ExtendedDecodeContext) -> ~[ty::t] { self.read_to_vec(|| self.read_ty(xcx) ) } - fn read_bounds(xcx: extended_decode_ctxt) -> @~[ty::param_bound] { + fn read_bounds(&self, xcx: @ExtendedDecodeContext) + -> @~[ty::param_bound] { do self.read_opaque |doc| { tydecode::parse_bounds_data( doc.data, doc.start, xcx.dcx.cdata.cnum, xcx.dcx.tcx, @@ -1048,16 +1063,16 @@ impl ebml_decoder_decoder_helpers for reader::Decoder { } } - fn read_ty_param_bounds_and_ty(xcx: extended_decode_ctxt) + fn read_ty_param_bounds_and_ty(&self, xcx: @ExtendedDecodeContext) -> ty::ty_param_bounds_and_ty { do self.read_rec { - { + ty::ty_param_bounds_and_ty { bounds: self.read_field(~"bounds", 0u, || { @self.read_to_vec(|| self.read_bounds(xcx) ) }), region_param: self.read_field(~"region_param", 1u, || { - Decodable::decode(&self) + Decodable::decode(self) }), ty: self.read_field(~"ty", 2u, || { self.read_ty(xcx) @@ -1066,7 +1081,7 @@ impl ebml_decoder_decoder_helpers for reader::Decoder { } } - fn convert_def_id(xcx: extended_decode_ctxt, + fn convert_def_id(&self, xcx: @ExtendedDecodeContext, source: tydecode::DefIdSource, did: ast::def_id) -> ast::def_id { /*! @@ -1092,7 +1107,7 @@ impl ebml_decoder_decoder_helpers for reader::Decoder { } } -fn decode_side_tables(xcx: extended_decode_ctxt, +fn decode_side_tables(xcx: @ExtendedDecodeContext, ast_doc: ebml::Doc) { let dcx = xcx.dcx; let tbl_doc = ast_doc[c::tag_table as uint]; @@ -1140,7 +1155,7 @@ fn decode_side_tables(xcx: extended_decode_ctxt, let ids = val_dsr.read_to_vec(|| { xcx.tr_id(val_dsr.read_int()) }); - let dvec = @dvec::from_vec(move ids); + let dvec = @dvec::from_vec(ids); dcx.maps.last_use_map.insert(id, dvec); } else if tag == (c::tag_table_method_map as uint) { dcx.maps.method_map.insert( @@ -1188,27 +1203,27 @@ fn decode_item_ast(par_doc: ebml::Doc) -> @ast::item { #[cfg(test)] trait fake_ext_ctxt { - fn cfg() -> ast::crate_cfg; - fn parse_sess() -> parse::parse_sess; - fn call_site() -> span; - fn ident_of(+st: ~str) -> ast::ident; + fn cfg(&self) -> ast::crate_cfg; + fn parse_sess(&self) -> @mut parse::ParseSess; + fn call_site(&self) -> span; + fn ident_of(&self, +st: ~str) -> ast::ident; } #[cfg(test)] -type fake_session = parse::parse_sess; +type fake_session = @mut parse::ParseSess; #[cfg(test)] impl fake_ext_ctxt for fake_session { - fn cfg() -> ast::crate_cfg { ~[] } - fn parse_sess() -> parse::parse_sess { self } - fn call_site() -> span { + fn cfg(&self) -> ast::crate_cfg { ~[] } + fn parse_sess(&self) -> @mut parse::ParseSess { *self } + fn call_site(&self) -> span { codemap::span { lo: codemap::BytePos(0), hi: codemap::BytePos(0), expn_info: None } } - fn ident_of(+st: ~str) -> ast::ident { + fn ident_of(&self, +st: ~str) -> ast::ident { self.interner.intern(@st) } } @@ -1272,15 +1287,15 @@ fn test_more() { fn test_simplification() { let ext_cx = mk_ctxt(); let item_in = ast::ii_item(quote_item!( - fn new_int_alist() -> alist { + fn new_int_alist() -> alist { fn eq_int(&&a: int, &&b: int) -> bool { a == b } - return {eq_fn: eq_int, data: ~[]}; + return alist {eq_fn: eq_int, data: ~[]}; } ).get()); let item_out = simplify_ast(item_in); let item_exp = ast::ii_item(quote_item!( - fn new_int_alist() -> alist { - return {eq_fn: eq_int, data: ~[]}; + fn new_int_alist() -> alist { + return alist {eq_fn: eq_int, data: ~[]}; } ).get()); match (item_out, item_exp) { diff --git a/src/librustc/middle/borrowck/check_loans.rs b/src/librustc/middle/borrowck/check_loans.rs index b6b94faa3db7e..afefec00c5040 100644 --- a/src/librustc/middle/borrowck/check_loans.rs +++ b/src/librustc/middle/borrowck/check_loans.rs @@ -21,7 +21,7 @@ use core::prelude::*; use middle::moves; use middle::borrowck::{Loan, bckerr, BorrowckCtxt, inherent_mutability}; -use middle::borrowck::{req_maps, root_map_key, save_and_restore_managed}; +use middle::borrowck::{ReqMaps, root_map_key, save_and_restore_managed}; use middle::borrowck::{MoveError, MoveOk, MoveFromIllegalCmt}; use middle::borrowck::{MoveWhileBorrowed}; use middle::mem_categorization::{cat_arg, cat_binding, cat_comp, cat_deref}; @@ -45,7 +45,7 @@ use syntax::visit; struct CheckLoanCtxt { bccx: @BorrowckCtxt, - req_maps: req_maps, + req_maps: ReqMaps, reported: HashMap, @@ -66,7 +66,7 @@ enum purity_cause { } pub fn check_loans(bccx: @BorrowckCtxt, - req_maps: req_maps, + req_maps: ReqMaps, crate: @ast::crate) { let clcx = @mut CheckLoanCtxt { bccx: bccx, @@ -90,16 +90,16 @@ enum assignment_type { } impl assignment_type { - fn checked_by_liveness() -> bool { + fn checked_by_liveness(&self) -> bool { // the liveness pass guarantees that immutable local variables // are only assigned once; but it doesn't consider &mut - match self { + match *self { at_straight_up => true, at_swap => true } } - fn ing_form(desc: ~str) -> ~str { - match self { + fn ing_form(&self, desc: ~str) -> ~str { + match *self { at_straight_up => ~"assigning to " + desc, at_swap => ~"swapping to and from " + desc } @@ -632,7 +632,7 @@ fn check_loans_in_fn(fk: visit::fn_kind, _ => {} // Ignore this argument. } } - *self.fn_args = @move fn_args; + *self.fn_args = @fn_args; } } diff --git a/src/librustc/middle/borrowck/gather_loans.rs b/src/librustc/middle/borrowck/gather_loans.rs index 65518398eb752..546e9359a32d9 100644 --- a/src/librustc/middle/borrowck/gather_loans.rs +++ b/src/librustc/middle/borrowck/gather_loans.rs @@ -22,7 +22,7 @@ use middle::borrowck::preserve::{PreserveCondition, PcOk, PcIfPure}; use middle::borrowck::{Loan, bckerr, bckres, BorrowckCtxt, err_mutbl}; use middle::borrowck::{LoanKind, TotalFreeze, PartialFreeze, TotalTake, PartialTake, Immobile}; -use middle::borrowck::{req_maps}; +use middle::borrowck::ReqMaps; use middle::borrowck::loan; use middle::mem_categorization::{cat_binding, cat_discr, cmt, comp_variant}; use middle::mem_categorization::{mem_categorization_ctxt}; @@ -47,7 +47,7 @@ use syntax::visit; /// /// - `bccx`: the the borrow check context /// - `req_maps`: the maps computed by `gather_loans()`, see def'n of the -/// type `req_maps` for more info +/// struct `ReqMaps` for more info /// - `item_ub`: the id of the block for the enclosing fn/method item /// - `root_ub`: the id of the outermost block for which we can root /// an `@T`. This is the id of the innermost enclosing @@ -73,16 +73,16 @@ use syntax::visit; /// because it would have to be rooted for a region greater than `root_ub`. struct GatherLoanCtxt { bccx: @BorrowckCtxt, - req_maps: req_maps, + req_maps: ReqMaps, item_ub: ast::node_id, root_ub: ast::node_id, ignore_adjustments: LinearSet } -pub fn gather_loans(bccx: @BorrowckCtxt, crate: @ast::crate) -> req_maps { +pub fn gather_loans(bccx: @BorrowckCtxt, crate: @ast::crate) -> ReqMaps { let glcx = @mut GatherLoanCtxt { bccx: bccx, - req_maps: {req_loan_map: HashMap(), pure_map: HashMap()}, + req_maps: ReqMaps { req_loan_map: HashMap(), pure_map: HashMap() }, item_ub: 0, root_ub: 0, ignore_adjustments: LinearSet::new() @@ -376,8 +376,8 @@ impl GatherLoanCtxt { Some(_) => { match loan::loan(self.bccx, cmt, scope_r, loan_kind) { Err(ref e) => { self.bccx.report((*e)); } - Ok(move loans) => { - self.add_loans(cmt, loan_kind, scope_r, move loans); + Ok(loans) => { + self.add_loans(cmt, loan_kind, scope_r, loans); } } } @@ -540,7 +540,7 @@ impl GatherLoanCtxt { } }; - self.add_loans_to_scope_id(scope_id, move loans); + self.add_loans_to_scope_id(scope_id, loans); if loan_kind.is_freeze() && !cmt.mutbl.is_immutable() { self.bccx.stats.loaned_paths_imm += 1; @@ -566,7 +566,7 @@ impl GatherLoanCtxt { req_loans.push_all(loans); } None => { - let dvec = @dvec::from_vec(move loans); + let dvec = @dvec::from_vec(loans); let req_loan_map = self.req_maps.req_loan_map; req_loan_map.insert(scope_id, dvec); } diff --git a/src/librustc/middle/borrowck/loan.rs b/src/librustc/middle/borrowck/loan.rs index 3b6d735ae781f..c39f2455c2f8f 100644 --- a/src/librustc/middle/borrowck/loan.rs +++ b/src/librustc/middle/borrowck/loan.rs @@ -73,7 +73,7 @@ pub fn loan(bccx: @BorrowckCtxt, Err(ref e) => return Err((*e)), Ok(()) => {} } - // XXX: Workaround for borrow check bug. + // FIXME #4945: Workaround for borrow check bug. Ok(copy lc.loans) } diff --git a/src/librustc/middle/borrowck/mod.rs b/src/librustc/middle/borrowck/mod.rs index dd8f889a05732..568bc5b5e70f6 100644 --- a/src/librustc/middle/borrowck/mod.rs +++ b/src/librustc/middle/borrowck/mod.rs @@ -400,9 +400,11 @@ pub enum LoanKind { } /// a complete record of a loan that was granted -pub struct Loan {lp: @loan_path, - cmt: cmt, - kind: LoanKind} +pub struct Loan { + lp: @loan_path, + cmt: cmt, + kind: LoanKind +} /// maps computed by `gather_loans` that are then used by `check_loans` /// @@ -410,17 +412,17 @@ pub struct Loan {lp: @loan_path, /// for the duration of that block/expr /// - `pure_map`: map from block/expr that must be pure to the error message /// that should be reported if they are not pure -pub type req_maps = { +pub struct ReqMaps { req_loan_map: HashMap>, pure_map: HashMap -}; +} pub fn save_and_restore(save_and_restore_t: &mut T, f: &fn() -> U) -> U { let old_save_and_restore_t = *save_and_restore_t; let u = f(); *save_and_restore_t = old_save_and_restore_t; - move u + u } pub fn save_and_restore_managed(save_and_restore_t: @mut T, @@ -428,7 +430,7 @@ pub fn save_and_restore_managed(save_and_restore_t: @mut T, let old_save_and_restore_t = *save_and_restore_t; let u = f(); *save_and_restore_t = old_save_and_restore_t; - move u + u } impl LoanKind { @@ -449,7 +451,7 @@ impl LoanKind { /// Creates and returns a new root_map -pub impl root_map_key : to_bytes::IterBytes { +pub impl to_bytes::IterBytes for root_map_key { pure fn iter_bytes(&self, +lsb0: bool, f: to_bytes::Cb) { to_bytes::iter_bytes_2(&self.id, &self.derefs, lsb0, f); } @@ -489,7 +491,7 @@ pub impl BorrowckCtxt { cat_def(self.tcx, self.method_map, id, span, ty, def) } - fn cat_variant(&self, + fn cat_variant(&self, arg: N, enum_did: ast::def_id, cmt: cmt) -> cmt { diff --git a/src/librustc/middle/check_const.rs b/src/librustc/middle/check_const.rs index 6d4de6aeb9351..c86f7ea5a922f 100644 --- a/src/librustc/middle/check_const.rs +++ b/src/librustc/middle/check_const.rs @@ -16,7 +16,6 @@ use middle::ty; use middle::typeck; use util::ppaux; -use core::dvec::DVec; use core::option; use std::oldmap::HashMap; use syntax::ast::*; @@ -212,20 +211,20 @@ pub fn check_item_recursion(sess: Session, ast_map: ast_map::map, def_map: resolve::DefMap, it: @item) { - type env = { + struct env { root_it: @item, sess: Session, ast_map: ast_map::map, def_map: resolve::DefMap, - idstack: @DVec, - }; + idstack: @mut ~[node_id] + } - let env = { + let env = env { root_it: it, sess: sess, ast_map: ast_map, def_map: def_map, - idstack: @DVec() + idstack: @mut ~[] }; let visitor = visit::mk_vt(@visit::Visitor { @@ -236,12 +235,12 @@ pub fn check_item_recursion(sess: Session, (visitor.visit_item)(it, env, visitor); fn visit_item(it: @item, &&env: env, v: visit::vt) { - if (*env.idstack).contains(&(it.id)) { + if env.idstack.contains(&(it.id)) { env.sess.span_fatal(env.root_it.span, ~"recursive constant"); } - (*env.idstack).push(it.id); + env.idstack.push(it.id); visit::visit_item(it, env, v); - (*env.idstack).pop(); + env.idstack.pop(); } fn visit_expr(e: @expr, &&env: env, v: visit::vt) { diff --git a/src/librustc/middle/check_loop.rs b/src/librustc/middle/check_loop.rs index 38450de6b540c..34665fe7b7d27 100644 --- a/src/librustc/middle/check_loop.rs +++ b/src/librustc/middle/check_loop.rs @@ -14,34 +14,49 @@ use middle::ty; use syntax::ast::*; use syntax::visit; -pub type ctx = {in_loop: bool, can_ret: bool}; +pub struct Context { + in_loop: bool, + can_ret: bool +} pub fn check_crate(tcx: ty::ctxt, crate: @crate) { visit::visit_crate(*crate, - {in_loop: false, can_ret: true}, + Context { in_loop: false, can_ret: true }, visit::mk_vt(@visit::Visitor { visit_item: |i, _cx, v| { - visit::visit_item(i, {in_loop: false, can_ret: true}, v); + visit::visit_item(i, Context { + in_loop: false, + can_ret: true + }, v); }, - visit_expr: |e: @expr, cx: ctx, v: visit::vt| { + visit_expr: |e: @expr, cx: Context, v: visit::vt| { match e.node { expr_while(e, ref b) => { (v.visit_expr)(e, cx, v); - (v.visit_block)((*b), {in_loop: true,.. cx}, v); + (v.visit_block)((*b), Context { in_loop: true,.. cx }, v); } expr_loop(ref b, _) => { - (v.visit_block)((*b), {in_loop: true,.. cx}, v); + (v.visit_block)((*b), Context { in_loop: true,.. cx }, v); } expr_fn(*) => { - visit::visit_expr(e, {in_loop: false, can_ret: true}, v); + visit::visit_expr(e, Context { + in_loop: false, + can_ret: true + }, v); } expr_fn_block(_, ref b) => { - (v.visit_block)((*b), {in_loop: false, can_ret: false}, v); + (v.visit_block)((*b), Context { + in_loop: false, + can_ret: false + }, v); } expr_loop_body(@expr {node: expr_fn_block(_, ref b), _}) => { let sigil = ty::ty_closure_sigil(ty::expr_ty(tcx, e)); let blk = (sigil == BorrowedSigil); - (v.visit_block)((*b), {in_loop: true, can_ret: blk}, v); + (v.visit_block)((*b), Context { + in_loop: true, + can_ret: blk + }, v); } expr_break(_) => { if !cx.in_loop { diff --git a/src/librustc/middle/check_match.rs b/src/librustc/middle/check_match.rs index bd07ca84c9aad..85ed4e74efb71 100644 --- a/src/librustc/middle/check_match.rs +++ b/src/librustc/middle/check_match.rs @@ -134,39 +134,47 @@ pub fn raw_pat(p: @pat) -> @pat { pub fn check_exhaustive(cx: @MatchCheckCtxt, sp: span, pats: ~[@pat]) { assert(!pats.is_empty()); let ext = match is_useful(cx, vec::map(pats, |p| ~[*p]), ~[wild()]) { - not_useful => return, // This is good, wildcard pattern isn't reachable - useful_ => None, - useful(ty, ref ctor) => { - match ty::get(ty).sty { - ty::ty_bool => { - match (*ctor) { - val(const_bool(true)) => Some(~"true"), - val(const_bool(false)) => Some(~"false"), - _ => None - } - } - ty::ty_enum(id, _) => { - let vid = match (*ctor) { variant(id) => id, - _ => fail!(~"check_exhaustive: non-variant ctor") }; - match vec::find(*ty::enum_variants(cx.tcx, id), - |v| v.id == vid) { - Some(v) => Some(cx.tcx.sess.str_of(v.name)), - None => fail!(~"check_exhaustive: bad variant in ctor") - } - } - ty::ty_unboxed_vec(*) | ty::ty_evec(*) => { - match (*ctor) { - vec(n) => Some(fmt!("vectors of length %u", n)), - _ => None + not_useful => { + // This is good, wildcard pattern isn't reachable + return; + } + useful_ => None, + useful(ty, ref ctor) => { + match ty::get(ty).sty { + ty::ty_bool => { + match (*ctor) { + val(const_bool(true)) => Some(@~"true"), + val(const_bool(false)) => Some(@~"false"), + _ => None + } + } + ty::ty_enum(id, _) => { + let vid = match *ctor { + variant(id) => id, + _ => fail!(~"check_exhaustive: non-variant ctor"), + }; + let variants = ty::enum_variants(cx.tcx, id); + + match variants.find(|v| v.id == vid) { + Some(v) => Some(cx.tcx.sess.str_of(v.name)), + None => { + fail!(~"check_exhaustive: bad variant in ctor") + } + } + } + ty::ty_unboxed_vec(*) | ty::ty_evec(*) => { + match *ctor { + vec(n) => Some(@fmt!("vectors of length %u", n)), + _ => None + } + } + _ => None } - } - _ => None } - } }; let msg = ~"non-exhaustive patterns" + match ext { - Some(ref s) => ~": " + (*s) + ~" not covered", - None => ~"" + Some(ref s) => ~": " + **s + ~" not covered", + None => ~"" }; cx.tcx.sess.span_err(sp, msg); } diff --git a/src/librustc/middle/kind.rs b/src/librustc/middle/kind.rs index 29a3a83364290..b08adef88c98c 100644 --- a/src/librustc/middle/kind.rs +++ b/src/librustc/middle/kind.rs @@ -62,28 +62,30 @@ pub const try_adding: &str = "Try adding a move"; pub type rval_map = HashMap; -pub type ctx = { +pub struct Context { tcx: ty::ctxt, method_map: typeck::method_map, last_use_map: liveness::last_use_map, current_item: node_id -}; +} pub fn check_crate(tcx: ty::ctxt, method_map: typeck::method_map, last_use_map: liveness::last_use_map, crate: @crate) { - let ctx = {tcx: tcx, - method_map: method_map, - last_use_map: last_use_map, - current_item: -1}; + let ctx = Context { + tcx: tcx, + method_map: method_map, + last_use_map: last_use_map, + 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: fn@(i: @item, cx: ctx, v: visit::vt) { - visit::visit_item(i, {current_item: i.id,.. cx}, v); + visit_item: fn@(i: @item, cx: Context, v: visit::vt) { + visit::visit_item(i, Context { current_item: i.id,.. cx }, v); }, .. *visit::default_visitor() }); @@ -91,13 +93,13 @@ pub fn check_crate(tcx: ty::ctxt, tcx.sess.abort_if_errors(); } -type check_fn = fn@(ctx, @freevar_entry); +type check_fn = fn@(Context, @freevar_entry); // Yields the appropriate function to check the kind of closed over // variables. `id` is the node_id for some expression that creates the // closure. -fn with_appropriate_checker(cx: ctx, id: node_id, b: fn(check_fn)) { - fn check_for_uniq(cx: ctx, fv: @freevar_entry) { +fn with_appropriate_checker(cx: Context, id: node_id, b: fn(check_fn)) { + fn check_for_uniq(cx: Context, fv: @freevar_entry) { // all captured data must be owned, regardless of whether it is // moved in or copied in. let id = ast_util::def_id_of_def(fv.def).node; @@ -108,7 +110,7 @@ fn with_appropriate_checker(cx: ctx, id: node_id, b: fn(check_fn)) { check_imm_free_var(cx, fv.def, fv.span); } - fn check_for_box(cx: ctx, fv: @freevar_entry) { + fn check_for_box(cx: Context, fv: @freevar_entry) { // all captured data must be owned let id = ast_util::def_id_of_def(fv.def).node; let var_t = ty::node_id_to_type(cx.tcx, id); @@ -118,11 +120,11 @@ fn with_appropriate_checker(cx: ctx, id: node_id, b: fn(check_fn)) { check_imm_free_var(cx, fv.def, fv.span); } - fn check_for_block(_cx: ctx, _fv: @freevar_entry) { + fn check_for_block(_cx: Context, _fv: @freevar_entry) { // no restrictions } - fn check_for_bare(cx: ctx, fv: @freevar_entry) { + fn check_for_bare(cx: Context, fv: @freevar_entry) { cx.tcx.sess.span_err( fv.span, ~"attempted dynamic environment capture"); @@ -152,7 +154,7 @@ fn with_appropriate_checker(cx: ctx, id: node_id, b: fn(check_fn)) { // Check that the free variables used in a shared/sendable closure conform // to the copy/move kind bounds. Then recursively check the function body. fn check_fn(fk: visit::fn_kind, decl: fn_decl, body: blk, sp: span, - fn_id: node_id, cx: ctx, v: visit::vt) { + fn_id: node_id, cx: Context, v: visit::vt) { // Check kinds on free variables: do with_appropriate_checker(cx, fn_id) |chk| { @@ -164,7 +166,7 @@ fn check_fn(fk: visit::fn_kind, decl: fn_decl, body: blk, sp: span, visit::visit_fn(fk, decl, body, sp, fn_id, cx, v); } -fn check_arm(a: arm, cx: ctx, v: visit::vt) { +fn check_arm(a: arm, cx: Context, v: visit::vt) { for vec::each(a.pats) |p| { do pat_util::pat_bindings(cx.tcx.def_map, *p) |mode, id, span, _pth| { if mode == bind_by_copy { @@ -177,7 +179,7 @@ fn check_arm(a: arm, cx: ctx, v: visit::vt) { visit::visit_arm(a, cx, v); } -pub fn check_expr(e: @expr, cx: ctx, v: visit::vt) { +pub fn check_expr(e: @expr, cx: Context, v: visit::vt) { debug!("kind::check_expr(%s)", expr_to_str(e, cx.tcx.sess.intr())); // Handle any kind bounds on type parameters @@ -244,7 +246,7 @@ pub fn check_expr(e: @expr, cx: ctx, v: visit::vt) { visit::visit_expr(e, cx, v); } -fn check_ty(aty: @Ty, cx: ctx, v: visit::vt) { +fn check_ty(aty: @Ty, cx: Context, v: visit::vt) { match aty.node { ty_path(_, id) => { do option::iter(&cx.tcx.node_type_substs.find(&id)) |ts| { @@ -260,7 +262,7 @@ fn check_ty(aty: @Ty, cx: ctx, v: visit::vt) { visit::visit_ty(aty, cx, v); } -pub fn check_bounds(cx: ctx, +pub fn check_bounds(cx: Context, _type_parameter_id: node_id, sp: span, ty: ty::t, @@ -310,7 +312,7 @@ pub fn check_bounds(cx: ctx, } } -fn is_nullary_variant(cx: ctx, ex: @expr) -> bool { +fn is_nullary_variant(cx: Context, ex: @expr) -> bool { match ex.node { expr_path(_) => { match cx.tcx.def_map.get(&ex.id) { @@ -324,7 +326,7 @@ fn is_nullary_variant(cx: ctx, ex: @expr) -> bool { } } -fn check_imm_free_var(cx: ctx, def: def, sp: span) { +fn check_imm_free_var(cx: Context, def: def, sp: span) { match def { def_local(_, is_mutbl) => { if is_mutbl { @@ -344,7 +346,7 @@ fn check_imm_free_var(cx: ctx, def: def, sp: span) { } } -fn check_copy(cx: ctx, ty: ty::t, sp: span, reason: &str) { +fn check_copy(cx: Context, ty: ty::t, sp: span, reason: &str) { debug!("type_contents(%s)=%s", ty_to_str(cx.tcx, ty), ty::type_contents(cx.tcx, ty).to_str()); @@ -356,7 +358,7 @@ fn check_copy(cx: ctx, ty: ty::t, sp: span, reason: &str) { } } -pub fn check_owned(cx: ctx, ty: ty::t, sp: span) -> bool { +pub fn check_owned(cx: Context, ty: ty::t, sp: span) -> bool { if !ty::type_is_owned(cx.tcx, ty) { cx.tcx.sess.span_err( sp, fmt!("value has non-owned type `%s`", @@ -410,7 +412,7 @@ pub fn check_durable(tcx: ty::ctxt, ty: ty::t, sp: span) -> bool { /// (3) The type parameter is owned (and therefore does not contain /// borrowed ptrs). pub fn check_cast_for_escaping_regions( - cx: ctx, + cx: Context, source: @expr, target: @expr) { @@ -454,7 +456,7 @@ pub fn check_cast_for_escaping_regions( } /// Ensures that values placed into a ~Trait are copyable and sendable. -pub fn check_kind_bounds_of_cast(cx: ctx, source: @expr, target: @expr) { +pub fn check_kind_bounds_of_cast(cx: Context, source: @expr, target: @expr) { let target_ty = ty::expr_ty(cx.tcx, target); match ty::get(target_ty).sty { ty::ty_trait(_, _, ty::vstore_uniq) => { diff --git a/src/librustc/middle/lang_items.rs b/src/librustc/middle/lang_items.rs index 6bcc71514d4a3..b997c94a71b4d 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() -> LanguageItems { + static pub fn new(&self) -> LanguageItems { LanguageItems { items: [ None, ..34 ] } @@ -96,7 +96,7 @@ pub impl LanguageItems { } } - static pub fn item_name(index: uint) -> &static/str { + static pub fn item_name(&self, index: uint) -> &static/str { match index { 0 => "const", 1 => "copy", @@ -256,45 +256,46 @@ fn LanguageItemCollector(crate: @crate, -> LanguageItemCollector/&r { let item_refs = HashMap(); - item_refs.insert(~"const", ConstTraitLangItem as uint); - item_refs.insert(~"copy", CopyTraitLangItem as uint); - item_refs.insert(~"owned", OwnedTraitLangItem as uint); - item_refs.insert(~"durable", DurableTraitLangItem as uint); - - item_refs.insert(~"drop", DropTraitLangItem as uint); - - item_refs.insert(~"add", AddTraitLangItem as uint); - item_refs.insert(~"sub", SubTraitLangItem as uint); - item_refs.insert(~"mul", MulTraitLangItem as uint); - item_refs.insert(~"div", DivTraitLangItem as uint); - item_refs.insert(~"modulo", ModuloTraitLangItem as uint); - item_refs.insert(~"neg", NegTraitLangItem as uint); - item_refs.insert(~"not", NotTraitLangItem as uint); - item_refs.insert(~"bitxor", BitXorTraitLangItem as uint); - item_refs.insert(~"bitand", BitAndTraitLangItem as uint); - item_refs.insert(~"bitor", BitOrTraitLangItem as uint); - item_refs.insert(~"shl", ShlTraitLangItem as uint); - item_refs.insert(~"shr", ShrTraitLangItem as uint); - item_refs.insert(~"index", IndexTraitLangItem as uint); - - item_refs.insert(~"eq", EqTraitLangItem as uint); - item_refs.insert(~"ord", OrdTraitLangItem as uint); - - item_refs.insert(~"str_eq", StrEqFnLangItem as uint); - item_refs.insert(~"uniq_str_eq", UniqStrEqFnLangItem as uint); - item_refs.insert(~"annihilate", AnnihilateFnLangItem as uint); - item_refs.insert(~"log_type", LogTypeFnLangItem as uint); - item_refs.insert(~"fail_", FailFnLangItem as uint); - item_refs.insert(~"fail_bounds_check", FailBoundsCheckFnLangItem as uint); - item_refs.insert(~"exchange_malloc", ExchangeMallocFnLangItem as uint); - item_refs.insert(~"exchange_free", ExchangeFreeFnLangItem as uint); - item_refs.insert(~"malloc", MallocFnLangItem as uint); - item_refs.insert(~"free", FreeFnLangItem as uint); - item_refs.insert(~"borrow_as_imm", BorrowAsImmFnLangItem as uint); - item_refs.insert(~"return_to_mut", ReturnToMutFnLangItem as uint); - item_refs.insert(~"check_not_borrowed", + item_refs.insert(@~"const", ConstTraitLangItem as uint); + item_refs.insert(@~"copy", CopyTraitLangItem as uint); + item_refs.insert(@~"owned", OwnedTraitLangItem as uint); + item_refs.insert(@~"durable", DurableTraitLangItem as uint); + + item_refs.insert(@~"drop", DropTraitLangItem as uint); + + item_refs.insert(@~"add", AddTraitLangItem as uint); + item_refs.insert(@~"sub", SubTraitLangItem as uint); + item_refs.insert(@~"mul", MulTraitLangItem as uint); + item_refs.insert(@~"div", DivTraitLangItem as uint); + item_refs.insert(@~"modulo", ModuloTraitLangItem as uint); + item_refs.insert(@~"neg", NegTraitLangItem as uint); + item_refs.insert(@~"not", NotTraitLangItem as uint); + item_refs.insert(@~"bitxor", BitXorTraitLangItem as uint); + item_refs.insert(@~"bitand", BitAndTraitLangItem as uint); + item_refs.insert(@~"bitor", BitOrTraitLangItem as uint); + item_refs.insert(@~"shl", ShlTraitLangItem as uint); + item_refs.insert(@~"shr", ShrTraitLangItem as uint); + item_refs.insert(@~"index", IndexTraitLangItem as uint); + + item_refs.insert(@~"eq", EqTraitLangItem as uint); + item_refs.insert(@~"ord", OrdTraitLangItem as uint); + + item_refs.insert(@~"str_eq", StrEqFnLangItem as uint); + item_refs.insert(@~"uniq_str_eq", UniqStrEqFnLangItem as uint); + item_refs.insert(@~"annihilate", AnnihilateFnLangItem as uint); + item_refs.insert(@~"log_type", LogTypeFnLangItem as uint); + item_refs.insert(@~"fail_", FailFnLangItem as uint); + item_refs.insert(@~"fail_bounds_check", + FailBoundsCheckFnLangItem as uint); + item_refs.insert(@~"exchange_malloc", ExchangeMallocFnLangItem as uint); + item_refs.insert(@~"exchange_free", ExchangeFreeFnLangItem as uint); + item_refs.insert(@~"malloc", MallocFnLangItem as uint); + item_refs.insert(@~"free", FreeFnLangItem as uint); + item_refs.insert(@~"borrow_as_imm", BorrowAsImmFnLangItem as uint); + item_refs.insert(@~"return_to_mut", ReturnToMutFnLangItem as uint); + item_refs.insert(@~"check_not_borrowed", CheckNotBorrowedFnLangItem as uint); - item_refs.insert(~"strdup_uniq", StrDupUniqFnLangItem as uint); + item_refs.insert(@~"strdup_uniq", StrDupUniqFnLangItem as uint); LanguageItemCollector { crate: crate, @@ -310,19 +311,17 @@ struct LanguageItemCollector { crate: @crate, session: Session, - item_refs: HashMap<~str,uint>, + item_refs: HashMap<@~str, uint>, } impl LanguageItemCollector { - fn match_and_collect_meta_item(item_def_id: def_id, + fn match_and_collect_meta_item(&self, item_def_id: def_id, meta_item: meta_item) { match meta_item.node { - meta_name_value(ref key, literal) => { + meta_name_value(key, literal) => { match literal.node { lit_str(value) => { - self.match_and_collect_item(item_def_id, - (/*bad*/copy *key), - /*bad*/copy *value); + self.match_and_collect_item(item_def_id, key, value); } _ => {} // Skip. } @@ -331,7 +330,7 @@ impl LanguageItemCollector { } } - fn collect_item(item_index: uint, item_def_id: def_id) { + fn collect_item(&self, item_index: uint, item_def_id: def_id) { // Check for duplicates. match self.items.items[item_index] { Some(original_def_id) if original_def_id != item_def_id => { @@ -347,8 +346,9 @@ impl LanguageItemCollector { self.items.items[item_index] = Some(item_def_id); } - fn match_and_collect_item(item_def_id: def_id, key: ~str, value: ~str) { - if key != ~"lang" { + fn match_and_collect_item(&self, + item_def_id: def_id, key: @~str, value: @~str) { + if *key != ~"lang" { return; // Didn't match. } @@ -362,7 +362,7 @@ impl LanguageItemCollector { } } - fn collect_local_language_items() { + fn collect_local_language_items(&self) { let this = unsafe { ptr::addr_of(&self) }; visit_crate(*self.crate, (), mk_simple_visitor(@SimpleVisitor { visit_item: |item| { @@ -379,7 +379,7 @@ impl LanguageItemCollector { })); } - fn collect_external_language_items() { + fn collect_external_language_items(&self) { let crate_store = self.session.cstore; do iter_crate_data(crate_store) |crate_number, _crate_metadata| { for each_lang_item(crate_store, crate_number) @@ -390,11 +390,11 @@ impl LanguageItemCollector { } } - fn check_completeness() { + fn check_completeness(&self) { for self.item_refs.each |&key, &item_ref| { match self.items.items[item_ref] { None => { - self.session.err(fmt!("no item found for `%s`", key)); + self.session.err(fmt!("no item found for `%s`", *key)); } Some(_) => { // OK. @@ -403,7 +403,7 @@ impl LanguageItemCollector { } } - fn collect() { + fn collect(&self) { self.collect_local_language_items(); self.collect_external_language_items(); self.check_completeness(); diff --git a/src/librustc/middle/lint.rs b/src/librustc/middle/lint.rs index 6e5146818b0cc..0a06808b63356 100644 --- a/src/librustc/middle/lint.rs +++ b/src/librustc/middle/lint.rs @@ -102,165 +102,205 @@ pub fn level_to_str(lv: level) -> &static/str { } } +#[deriving_eq] pub enum level { allow, warn, deny, forbid } -impl cmp::Eq for level { - pure fn eq(&self, other: &level) -> bool { - ((*self) as uint) == ((*other) as uint) - } - pure fn ne(&self, other: &level) -> bool { !(*self).eq(other) } +struct LintSpec { + lint: lint, + desc: &static/str, + default: level } -type lint_spec = @{lint: lint, - desc: &static/str, - default: level}; - -pub type lint_dict = HashMap<~str,lint_spec>; +pub type LintDict = HashMap<@~str, @LintSpec>; /* Pass names should not contain a '-', as the compiler normalizes '-' to '_' in command-line flags */ -pub fn get_lint_dict() -> lint_dict { +pub fn get_lint_dict() -> LintDict { let v = ~[ - (~"ctypes", - @{lint: ctypes, - desc: "proper use of core::libc types in foreign modules", - default: warn}), - - (~"unused_imports", - @{lint: unused_imports, - desc: "imports that are never used", - default: allow}), - - (~"while_true", - @{lint: while_true, - desc: "suggest using loop { } instead of while(true) { }", - default: warn}), - - (~"path_statement", - @{lint: path_statement, - desc: "path statements with no effect", - default: warn}), - - (~"unrecognized_lint", - @{lint: unrecognized_lint, - desc: "unrecognized lint attribute", - default: warn}), - - (~"non_implicitly_copyable_typarams", - @{lint: non_implicitly_copyable_typarams, - desc: "passing non implicitly copyable types as copy type params", - default: warn}), - - (~"vecs_implicitly_copyable", - @{lint: vecs_implicitly_copyable, - desc: "make vecs and strs not implicitly copyable \ + (@~"ctypes", + @LintSpec { + lint: ctypes, + desc: "proper use of core::libc types in foreign modules", + default: warn + }), + + (@~"unused_imports", + @LintSpec { + lint: unused_imports, + desc: "imports that are never used", + default: allow + }), + + (@~"while_true", + @LintSpec { + lint: while_true, + desc: "suggest using loop { } instead of while(true) { }", + default: warn + }), + + (@~"path_statement", + @LintSpec { + lint: path_statement, + desc: "path statements with no effect", + default: warn + }), + + (@~"unrecognized_lint", + @LintSpec { + lint: unrecognized_lint, + desc: "unrecognized lint attribute", + default: warn + }), + + (@~"non_implicitly_copyable_typarams", + @LintSpec { + lint: non_implicitly_copyable_typarams, + desc: "passing non implicitly copyable types as copy type params", + default: warn + }), + + (@~"vecs_implicitly_copyable", + @LintSpec { + lint: vecs_implicitly_copyable, + desc: "make vecs and strs not implicitly copyable \ (only checked at top level)", - default: warn}), - - (~"implicit_copies", - @{lint: implicit_copies, - desc: "implicit copies of non implicitly copyable data", - default: warn}), - - (~"deprecated_mode", - @{lint: deprecated_mode, - desc: "warn about deprecated uses of modes", - default: warn}), - - (~"deprecated_pattern", - @{lint: deprecated_pattern, - desc: "warn about deprecated uses of pattern bindings", - default: allow}), - - (~"non_camel_case_types", - @{lint: non_camel_case_types, - desc: "types, variants and traits should have camel case names", - default: allow}), - - (~"managed_heap_memory", - @{lint: managed_heap_memory, - desc: "use of managed (@ type) heap memory", - default: allow}), - - (~"owned_heap_memory", - @{lint: owned_heap_memory, - desc: "use of owned (~ type) heap memory", - default: allow}), - - (~"heap_memory", - @{lint: heap_memory, - desc: "use of any (~ type or @ type) heap memory", - default: allow}), - - (~"structural_records", - @{lint: structural_records, - desc: "use of any structural records", - default: deny}), - - (~"legacy modes", - @{lint: legacy_modes, - desc: "allow legacy modes", - default: forbid}), - - (~"type_limits", - @{lint: type_limits, - desc: "comparisons made useless by limits of the types involved", - default: warn}), - - (~"default_methods", - @{lint: default_methods, - desc: "allow default methods", - default: deny}), - - (~"deprecated_self", - @{lint: deprecated_self, - desc: "warn about deprecated uses of `self`", - default: warn}), + default: warn + }), + + (@~"implicit_copies", + @LintSpec { + lint: implicit_copies, + desc: "implicit copies of non implicitly copyable data", + default: warn + }), + + (@~"deprecated_mode", + @LintSpec { + lint: deprecated_mode, + desc: "warn about deprecated uses of modes", + default: warn + }), + + (@~"deprecated_pattern", + @LintSpec { + lint: deprecated_pattern, + desc: "warn about deprecated uses of pattern bindings", + default: allow + }), + + (@~"non_camel_case_types", + @LintSpec { + lint: non_camel_case_types, + desc: "types, variants and traits should have camel case names", + default: allow + }), + + (@~"managed_heap_memory", + @LintSpec { + lint: managed_heap_memory, + desc: "use of managed (@ type) heap memory", + default: allow + }), + + (@~"owned_heap_memory", + @LintSpec { + lint: owned_heap_memory, + desc: "use of owned (~ type) heap memory", + default: allow + }), + + (@~"heap_memory", + @LintSpec { + lint: heap_memory, + desc: "use of any (~ type or @ type) heap memory", + default: allow + }), + + (@~"structural_records", + @LintSpec { + lint: structural_records, + desc: "use of any structural records", + default: deny + }), + + (@~"legacy modes", + @LintSpec { + lint: legacy_modes, + desc: "allow legacy modes", + default: forbid + }), + + (@~"type_limits", + @LintSpec { + lint: type_limits, + desc: "comparisons made useless by limits of the types involved", + default: warn + }), + + (@~"default_methods", + @LintSpec { + lint: default_methods, + desc: "allow default methods", + default: deny + }), + + (@~"deprecated_self", + @LintSpec { + lint: deprecated_self, + desc: "warn about deprecated uses of `self`", + default: warn + }), /* FIXME(#3266)--make liveness warnings lintable - (~"unused_variable", - @{lint: unused_variable, - desc: "detect variables which are not used in any way", - default: warn}), - - (~"dead_assignment", - @{lint: dead_assignment, - desc: "detect assignments that will never be read", - default: warn}), + (@~"unused_variable", + @LintSpec { + lint: unused_variable, + desc: "detect variables which are not used in any way", + default: warn + }), + + (@~"dead_assignment", + @LintSpec { + lint: dead_assignment, + desc: "detect assignments that will never be read", + default: warn + }), */ ]; oldmap::hash_from_vec(v) } // This is a highly not-optimal set of data structure decisions. -type lint_modes = SmallIntMap; -type lint_mode_map = HashMap; +type LintModes = SmallIntMap; +type LintModeMap = HashMap; // settings_map maps node ids of items with non-default lint settings // to their settings; default_settings contains the settings for everything // not in the map. -pub type lint_settings = { - default_settings: lint_modes, - settings_map: lint_mode_map -}; - -pub fn mk_lint_settings() -> lint_settings { - {default_settings: oldsmallintmap::mk(), - settings_map: HashMap()} +pub struct LintSettings { + default_settings: LintModes, + settings_map: LintModeMap +} + +pub fn mk_lint_settings() -> LintSettings { + LintSettings { + default_settings: oldsmallintmap::mk(), + settings_map: HashMap() + } } -pub fn get_lint_level(modes: lint_modes, lint: lint) -> level { +pub fn get_lint_level(modes: LintModes, lint: lint) -> level { match modes.find(lint as uint) { Some(c) => c, None => allow } } -pub fn get_lint_settings_level(settings: lint_settings, +pub fn get_lint_settings_level(settings: LintSettings, lint_mode: lint, _expr_id: ast::node_id, item_id: ast::node_id) @@ -273,26 +313,24 @@ pub fn get_lint_settings_level(settings: lint_settings, // This is kind of unfortunate. It should be somewhere else, or we should use // a persistent data structure... -fn clone_lint_modes(modes: lint_modes) -> lint_modes { +fn clone_lint_modes(modes: LintModes) -> LintModes { oldsmallintmap::SmallIntMap_(@oldsmallintmap::SmallIntMap_ {v: copy modes.v}) } -type ctxt_ = {dict: lint_dict, - curr: lint_modes, - is_default: bool, - sess: Session}; - -enum ctxt { - ctxt_(ctxt_) +struct Context { + dict: LintDict, + curr: LintModes, + is_default: bool, + sess: Session } -impl ctxt { - fn get_level(lint: lint) -> level { +impl Context { + fn get_level(&self, lint: lint) -> level { get_lint_level(self.curr, lint) } - fn set_level(lint: lint, level: level) { + fn set_level(&self, lint: lint, level: level) { if level == allow { self.curr.remove(lint as uint); } else { @@ -300,7 +338,7 @@ impl ctxt { } } - fn span_lint(level: level, span: span, +msg: ~str) { + fn span_lint(&self, level: level, span: span, +msg: ~str) { self.sess.span_lint_level(level, span, msg); } @@ -309,9 +347,9 @@ impl ctxt { * current lint context, call the provided function, then reset the * lints in effect to their previous state. */ - fn with_lint_attrs(attrs: ~[ast::attribute], f: fn(ctxt)) { + fn with_lint_attrs(&self, attrs: ~[ast::attribute], f: fn(Context)) { - let mut new_ctxt = self; + let mut new_ctxt = *self; let mut triples = ~[]; for [allow, warn, deny, forbid].each |level| { @@ -344,15 +382,20 @@ impl ctxt { } } - for triples.each |pair| { - let (meta, level, lintname) = /*bad*/copy *pair; + for triples.each |triple| { + // FIXME(#3874): it would be nicer to write this... + // let (meta, level, lintname) = /*bad*/copy *pair; + let (meta, level, lintname) = match *triple { + (ref meta, level, lintname) => (meta, level, lintname) + }; + match self.dict.find(&lintname) { None => { self.span_lint( new_ctxt.get_level(unrecognized_lint), meta.span, fmt!("unknown `%s` attribute: `%s`", - level_to_str(level), lintname)); + level_to_str(level), *lintname)); } Some(lint) => { @@ -363,7 +406,7 @@ impl ctxt { meta.span, fmt!("%s(%s) overruled by outer forbid(%s)", level_to_str(level), - lintname, lintname)); + *lintname, *lintname)); } // we do multiple unneeded copies of the @@ -371,10 +414,11 @@ impl ctxt { // this shouldn't actually be a problem... let c = clone_lint_modes(new_ctxt.curr); - new_ctxt = - ctxt_({is_default: false, - curr: c, - .. *new_ctxt}); + new_ctxt = Context { + is_default: false, + curr: c, + .. new_ctxt + }; new_ctxt.set_level(lint.lint, level); } } @@ -384,7 +428,7 @@ impl ctxt { } -fn build_settings_item(i: @ast::item, &&cx: ctxt, v: visit::vt) { +fn build_settings_item(i: @ast::item, &&cx: Context, v: visit::vt) { do cx.with_lint_attrs(/*bad*/copy i.attrs) |cx| { if !cx.is_default { cx.sess.lint_settings.settings_map.insert(i.id, cx.curr); @@ -394,10 +438,12 @@ fn build_settings_item(i: @ast::item, &&cx: ctxt, v: visit::vt) { } pub fn build_settings_crate(sess: session::Session, crate: @ast::crate) { - let cx = ctxt_({dict: get_lint_dict(), - curr: oldsmallintmap::mk(), - is_default: true, - sess: sess}); + let cx = Context { + dict: get_lint_dict(), + curr: oldsmallintmap::mk(), + is_default: true, + sess: sess + }; // Install defaults. for cx.dict.each_value |&spec| { @@ -416,7 +462,10 @@ pub fn build_settings_crate(sess: session::Session, crate: @ast::crate) { sess.lint_settings.default_settings.insert(k, v); } - let cx = ctxt_({is_default: true,.. *cx}); + let cx = Context { + is_default: true, + .. cx + }; let visit = visit::mk_vt(@visit::Visitor { visit_item: build_settings_item, @@ -477,7 +526,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, + pure fn is_valid(binop: ast::binop, v: T, min: T, max: T) -> bool { match binop { ast::lt => v <= max, @@ -657,23 +706,21 @@ fn check_item_deprecated_self(cx: ty::ctxt, item: @ast::item) { } fn check_item_structural_records(cx: ty::ctxt, it: @ast::item) { - if !cx.legacy_records { - let visit = item_stopping_visitor( - visit::mk_simple_visitor(@visit::SimpleVisitor { - visit_expr: |e: @ast::expr| { - match e.node { - ast::expr_rec(*) => - cx.sess.span_lint( - structural_records, e.id, it.id, - e.span, - ~"structural records are deprecated"), - _ => () - } - }, - .. *visit::default_simple_visitor() - })); - visit::visit_item(it, (), visit); - } + let visit = item_stopping_visitor( + visit::mk_simple_visitor(@visit::SimpleVisitor { + visit_expr: |e: @ast::expr| { + match e.node { + ast::expr_rec(*) => + cx.sess.span_lint( + structural_records, e.id, it.id, + e.span, + ~"structural records are deprecated"), + _ => () + } + }, + .. *visit::default_simple_visitor() + })); + visit::visit_item(it, (), visit); } fn check_item_ctypes(cx: ty::ctxt, it: @ast::item) { @@ -829,26 +876,23 @@ fn check_item_non_camel_case_types(cx: ty::ctxt, it: @ast::item) { fn is_camel_case(cx: ty::ctxt, ident: ast::ident) -> bool { let ident = cx.sess.str_of(ident); assert !ident.is_empty(); - let ident = ident_without_trailing_underscores(ident); + let ident = ident_without_trailing_underscores(*ident); let ident = ident_without_leading_underscores(ident); char::is_uppercase(str::char_at(ident, 0)) && !ident.contains_char('_') } - fn ident_without_trailing_underscores(+ident: ~str) -> ~str { + fn ident_without_trailing_underscores(ident: &r/str) -> &r/str { match str::rfind(ident, |c| c != '_') { - Some(idx) => (ident).slice(0, idx + 1), - None => { ident } // all underscores + Some(idx) => str::view(ident, 0, idx + 1), + None => ident, // all underscores } } - fn ident_without_leading_underscores(+ident: ~str) -> ~str { + fn ident_without_leading_underscores(ident: &r/str) -> &r/str { match str::find(ident, |c| c != '_') { - Some(idx) => ident.slice(idx, ident.len()), - None => { - // all underscores - ident - } + Some(idx) => str::view(ident, idx, ident.len()), + None => ident // all underscores } } @@ -864,18 +908,18 @@ fn check_item_non_camel_case_types(cx: ty::ctxt, it: @ast::item) { } match it.node { - ast::item_ty(*) | ast::item_struct(*) | - ast::item_trait(*) => { - check_case(cx, it.ident, it.id, it.id, it.span) - } - ast::item_enum(ref enum_definition, _) => { - check_case(cx, it.ident, it.id, it.id, it.span); - for enum_definition.variants.each |variant| { - check_case(cx, variant.node.name, - variant.node.id, it.id, variant.span); + ast::item_ty(*) | ast::item_struct(*) | + ast::item_trait(*) => { + check_case(cx, it.ident, it.id, it.id, it.span) } - } - _ => () + ast::item_enum(ref enum_definition, _) => { + check_case(cx, it.ident, it.id, it.id, it.span); + for enum_definition.variants.each |variant| { + check_case(cx, variant.node.name, + variant.node.id, it.id, variant.span); + } + } + _ => () } } diff --git a/src/librustc/middle/liveness.rs b/src/librustc/middle/liveness.rs index d65c4e0158055..75bf7cf26091c 100644 --- a/src/librustc/middle/liveness.rs +++ b/src/librustc/middle/liveness.rs @@ -255,7 +255,7 @@ impl to_str::ToStr for Variable { // assignment. And so forth. impl LiveNode { - pure fn is_valid() -> bool { *self != uint::max_value } + pure fn is_valid(&self) -> bool { **self != uint::max_value } } fn invalid_node() -> LiveNode { LiveNode(uint::max_value) } @@ -383,11 +383,11 @@ impl IrMaps { } } - fn variable_name(&mut self, var: Variable) -> ~str { + fn variable_name(&mut self, var: Variable) -> @~str { match copy self.var_kinds[*var] { Local(LocalInfo {ident: nm, _}) | Arg(_, nm, _) => self.tcx.sess.str_of(nm), - ImplicitRet => ~"" + ImplicitRet => @~"" } } @@ -699,7 +699,7 @@ fn Liveness(ir: @mut IrMaps, specials: Specials) -> Liveness { } impl Liveness { - fn live_node(node_id: node_id, span: span) -> LiveNode { + fn live_node(&self, node_id: node_id, span: span) -> LiveNode { match self.ir.live_node_map.find(&node_id) { Some(ln) => ln, None => { @@ -714,7 +714,7 @@ impl Liveness { } } - fn variable_from_path(expr: @expr) -> Option { + fn variable_from_path(&self, expr: @expr) -> Option { match expr.node { expr_path(_) => { let def = self.tcx.def_map.get(&expr.id); @@ -726,11 +726,11 @@ impl Liveness { } } - fn variable(node_id: node_id, span: span) -> Variable { + fn variable(&self, node_id: node_id, span: span) -> Variable { self.ir.variable(node_id, span) } - fn variable_from_def_map(node_id: node_id, + fn variable_from_def_map(&self, node_id: node_id, span: span) -> Option { match self.tcx.def_map.find(&node_id) { Some(def) => { @@ -745,7 +745,7 @@ impl Liveness { } } - fn pat_bindings(pat: @pat, f: fn(LiveNode, Variable, span)) { + fn pat_bindings(&self, pat: @pat, f: fn(LiveNode, Variable, span)) { let def_map = self.tcx.def_map; do pat_util::pat_bindings(def_map, pat) |_bm, p_id, sp, _n| { let ln = self.live_node(p_id, sp); @@ -754,7 +754,8 @@ impl Liveness { } } - fn arm_pats_bindings(pats: &[@pat], f: fn(LiveNode, Variable, span)) { + fn arm_pats_bindings(&self, + pats: &[@pat], f: fn(LiveNode, Variable, span)) { // only consider the first pattern; any later patterns must have // the same bindings, and we also consider the first pattern to be // the "authoratative" set of ids @@ -763,11 +764,11 @@ impl Liveness { } } - fn define_bindings_in_pat(pat: @pat, succ: LiveNode) -> LiveNode { + fn define_bindings_in_pat(&self, pat: @pat, succ: LiveNode) -> LiveNode { self.define_bindings_in_arm_pats([pat], succ) } - fn define_bindings_in_arm_pats(pats: &[@pat], + fn define_bindings_in_arm_pats(&self, pats: &[@pat], succ: LiveNode) -> LiveNode { let mut succ = succ; do self.arm_pats_bindings(pats) |ln, var, _sp| { @@ -778,11 +779,11 @@ impl Liveness { succ } - fn idx(ln: LiveNode, var: Variable) -> uint { + fn idx(&self, ln: LiveNode, var: Variable) -> uint { *ln * self.ir.num_vars + *var } - fn live_on_entry(ln: LiveNode, var: Variable) + fn live_on_entry(&self, ln: LiveNode, var: Variable) -> Option { assert ln.is_valid(); @@ -793,18 +794,18 @@ impl Liveness { /* Is this variable live on entry to any of its successor nodes? */ - fn live_on_exit(ln: LiveNode, var: Variable) + fn live_on_exit(&self, ln: LiveNode, var: Variable) -> Option { self.live_on_entry(copy self.successors[*ln], var) } - fn used_on_entry(ln: LiveNode, var: Variable) -> bool { + fn used_on_entry(&self, ln: LiveNode, var: Variable) -> bool { assert ln.is_valid(); self.users[self.idx(ln, var)].used } - fn assigned_on_entry(ln: LiveNode, var: Variable) + fn assigned_on_entry(&self, ln: LiveNode, var: Variable) -> Option { assert ln.is_valid(); @@ -812,13 +813,13 @@ impl Liveness { if writer.is_valid() {Some(self.ir.lnk(writer))} else {None} } - fn assigned_on_exit(ln: LiveNode, var: Variable) + fn assigned_on_exit(&self, ln: LiveNode, var: Variable) -> Option { self.assigned_on_entry(copy self.successors[*ln], var) } - fn indices(ln: LiveNode, op: fn(uint)) { + fn indices(&self, ln: LiveNode, op: fn(uint)) { let node_base_idx = self.idx(ln, Variable(0)); for uint::range(0, self.ir.num_vars) |var_idx| { op(node_base_idx + var_idx) @@ -834,7 +835,7 @@ impl Liveness { } } - fn write_vars(wr: io::Writer, + fn write_vars(&self, wr: io::Writer, ln: LiveNode, test: fn(uint) -> LiveNode) { let node_base_idx = self.idx(ln, Variable(0)); @@ -847,7 +848,7 @@ impl Liveness { } } - fn find_loop_scope(opt_label: Option, id: node_id, sp: span) + fn find_loop_scope(&self, opt_label: Option, id: node_id, sp: span) -> node_id { match opt_label { Some(_) => // Refers to a labeled loop. Use the results of resolve @@ -869,7 +870,7 @@ impl Liveness { } } - fn ln_str(ln: LiveNode) -> ~str { + fn ln_str(&self, ln: LiveNode) -> ~str { do io::with_str_writer |wr| { wr.write_str(~"[ln("); wr.write_uint(*ln); @@ -886,7 +887,7 @@ impl Liveness { } } - fn init_empty(ln: LiveNode, succ_ln: LiveNode) { + fn init_empty(&self, ln: LiveNode, succ_ln: LiveNode) { self.successors[*ln] = succ_ln; // It is not necessary to initialize the @@ -899,7 +900,7 @@ impl Liveness { // } } - fn init_from_succ(ln: LiveNode, succ_ln: LiveNode) { + fn init_from_succ(&self, ln: LiveNode, succ_ln: LiveNode) { // more efficient version of init_empty() / merge_from_succ() self.successors[*ln] = succ_ln; self.indices2(ln, succ_ln, |idx, succ_idx| { @@ -909,7 +910,7 @@ impl Liveness { self.ln_str(ln), self.ln_str(succ_ln)); } - fn merge_from_succ(ln: LiveNode, succ_ln: LiveNode, + fn merge_from_succ(&self, ln: LiveNode, succ_ln: LiveNode, first_merge: bool) -> bool { if ln == succ_ln { return false; } @@ -943,7 +944,7 @@ impl Liveness { // Indicates that a local variable was *defined*; we know that no // uses of the variable can precede the definition (resolve checks // this) so we just clear out all the data. - fn define(writer: LiveNode, var: Variable) { + fn define(&self, writer: LiveNode, var: Variable) { let idx = self.idx(writer, var); self.users[idx].reader = invalid_node(); self.users[idx].writer = invalid_node(); @@ -953,7 +954,7 @@ impl Liveness { } // Either read, write, or both depending on the acc bitset - fn acc(ln: LiveNode, var: Variable, acc: uint) { + fn acc(&self, ln: LiveNode, var: Variable, acc: uint) { let idx = self.idx(ln, var); let user = &mut self.users[idx]; @@ -978,7 +979,7 @@ impl Liveness { // _______________________________________________________________________ - fn compute(decl: fn_decl, body: blk) -> LiveNode { + fn compute(&self, decl: fn_decl, body: blk) -> LiveNode { // if there is a `break` or `again` at the top level, then it's // effectively a return---this only occurs in `for` loops, // where the body is really a closure. @@ -1003,7 +1004,8 @@ impl Liveness { entry_ln } - fn propagate_through_fn_block(decl: fn_decl, blk: blk) -> LiveNode { + fn propagate_through_fn_block(&self, decl: fn_decl, blk: blk) + -> LiveNode { // inputs passed by & mode should be considered live on exit: for decl.inputs.each |arg| { match ty::resolved_mode(self.tcx, arg.mode) { @@ -1036,14 +1038,15 @@ impl Liveness { self.propagate_through_block(blk, self.s.fallthrough_ln) } - fn propagate_through_block(blk: blk, succ: LiveNode) -> LiveNode { + fn propagate_through_block(&self, blk: blk, succ: LiveNode) -> LiveNode { let succ = self.propagate_through_opt_expr(blk.node.expr, succ); do blk.node.stmts.foldr(succ) |stmt, succ| { self.propagate_through_stmt(*stmt, succ) } } - fn propagate_through_stmt(stmt: @stmt, succ: LiveNode) -> LiveNode { + fn propagate_through_stmt(&self, stmt: @stmt, succ: LiveNode) + -> LiveNode { match stmt.node { stmt_decl(decl, _) => { return self.propagate_through_decl(decl, succ); @@ -1059,7 +1062,8 @@ impl Liveness { } } - fn propagate_through_decl(decl: @decl, succ: LiveNode) -> LiveNode { + fn propagate_through_decl(&self, decl: @decl, succ: LiveNode) + -> LiveNode { match /*bad*/copy decl.node { decl_local(locals) => { do locals.foldr(succ) |local, succ| { @@ -1072,7 +1076,8 @@ impl Liveness { } } - fn propagate_through_local(local: @local, succ: LiveNode) -> LiveNode { + fn propagate_through_local(&self, local: @local, succ: LiveNode) + -> LiveNode { // Note: we mark the variable as defined regardless of whether // there is an initializer. Initially I had thought to only mark // the live variable as defined if it was initialized, and then we @@ -1091,21 +1096,22 @@ impl Liveness { self.define_bindings_in_pat(local.node.pat, succ) } - fn propagate_through_exprs(exprs: ~[@expr], + fn propagate_through_exprs(&self, exprs: ~[@expr], succ: LiveNode) -> LiveNode { do exprs.foldr(succ) |expr, succ| { self.propagate_through_expr(*expr, succ) } } - fn propagate_through_opt_expr(opt_expr: Option<@expr>, + fn propagate_through_opt_expr(&self, opt_expr: Option<@expr>, succ: LiveNode) -> LiveNode { do opt_expr.foldl(succ) |succ, expr| { self.propagate_through_expr(*expr, *succ) } } - fn propagate_through_expr(expr: @expr, succ: LiveNode) -> LiveNode { + fn propagate_through_expr(&self, expr: @expr, succ: LiveNode) + -> LiveNode { debug!("propagate_through_expr: %s", expr_to_str(expr, self.tcx.sess.intr())); @@ -1365,7 +1371,7 @@ impl Liveness { } } - fn propagate_through_lvalue_components(expr: @expr, + fn propagate_through_lvalue_components(&self, expr: @expr, succ: LiveNode) -> LiveNode { // # Lvalues // @@ -1424,7 +1430,7 @@ impl Liveness { } // see comment on propagate_through_lvalue() - fn write_lvalue(expr: @expr, + fn write_lvalue(&self, expr: @expr, succ: LiveNode, acc: uint) -> LiveNode { match expr.node { @@ -1438,7 +1444,8 @@ impl Liveness { } } - fn access_path(expr: @expr, succ: LiveNode, acc: uint) -> LiveNode { + fn access_path(&self, expr: @expr, succ: LiveNode, acc: uint) + -> LiveNode { let def = self.tcx.def_map.get(&expr.id); match relevant_def(def) { Some(nid) => { @@ -1454,7 +1461,7 @@ impl Liveness { } } - fn propagate_through_loop(expr: @expr, + fn propagate_through_loop(&self, expr: @expr, cond: Option<@expr>, body: blk, succ: LiveNode) -> LiveNode { @@ -1510,7 +1517,7 @@ impl Liveness { cond_ln } - fn with_loop_nodes(loop_node_id: node_id, + fn with_loop_nodes(&self, loop_node_id: node_id, break_ln: LiveNode, cont_ln: LiveNode, f: fn() -> R) -> R { @@ -1520,7 +1527,7 @@ impl Liveness { self.cont_ln.insert(loop_node_id, cont_ln); let r = f(); self.loop_scope.pop(); - move r + r } } @@ -1646,7 +1653,7 @@ enum ReadKind { } impl @Liveness { - fn check_ret(id: node_id, sp: span, _fk: visit::fn_kind, + fn check_ret(&self, id: node_id, sp: span, _fk: visit::fn_kind, entry_ln: LiveNode) { if self.live_on_entry(entry_ln, self.s.no_ret_var).is_some() { // if no_ret_var is live, then we fall off the end of the @@ -1666,7 +1673,7 @@ impl @Liveness { } } - fn check_move_from_var(ln: LiveNode, + fn check_move_from_var(&self, ln: LiveNode, var: Variable, move_expr: @expr) { @@ -1691,7 +1698,7 @@ impl @Liveness { } } - fn consider_last_use(expr: @expr, ln: LiveNode, var: Variable) { + fn consider_last_use(&self, expr: @expr, ln: LiveNode, var: Variable) { debug!("consider_last_use(expr.id=%?, ln=%s, var=%s)", expr.id, ln.to_str(), var.to_str()); @@ -1701,7 +1708,7 @@ impl @Liveness { } } - fn check_lvalue(expr: @expr, vt: vt<@Liveness>) { + fn check_lvalue(&self, expr: @expr, vt: vt<@Liveness>) { match expr.node { expr_path(_) => { match self.tcx.def_map.get(&expr.id) { @@ -1729,18 +1736,18 @@ impl @Liveness { _ => { // For other kinds of lvalues, no checks are required, // and any embedded expressions are actually rvalues - visit::visit_expr(expr, self, vt); + visit::visit_expr(expr, *self, vt); } } } - fn check_for_reassignments_in_pat(pat: @pat) { + fn check_for_reassignments_in_pat(&self, pat: @pat) { do self.pat_bindings(pat) |ln, var, sp| { self.check_for_reassignment(ln, var, sp); } } - fn check_for_reassignment(ln: LiveNode, var: Variable, + fn check_for_reassignment(&self, ln: LiveNode, var: Variable, orig_span: span) { match self.assigned_on_exit(ln, var) { Some(ExprNode(span)) => { @@ -1761,7 +1768,7 @@ impl @Liveness { } } - fn report_illegal_move(lnk: LiveNodeKind, + fn report_illegal_move(&self, lnk: LiveNodeKind, var: Variable, move_expr: @expr) { @@ -1777,7 +1784,7 @@ impl @Liveness { self.tcx.sess.span_err( move_expr.span, fmt!("illegal move from argument `%s`, which is not \ - copy or move mode", self.tcx.sess.str_of(name))); + copy or move mode", *self.tcx.sess.str_of(name))); return; } Local(*) | ImplicitRet => { @@ -1798,7 +1805,7 @@ impl @Liveness { move_expr.span, fmt!("`%s` moved into closure environment here \ because its type is moved by default", - name)); + *name)); } expr_path(*) => { self.report_illegal_read( @@ -1827,7 +1834,7 @@ impl @Liveness { }; } - fn report_move_location(move_expr: @expr, + fn report_move_location(&self, move_expr: @expr, var: Variable, expr_descr: &str, pronoun: &str) @@ -1838,11 +1845,11 @@ impl @Liveness { move_expr.span, fmt!("%s`%s` moved here because %s has type %s, \ which is moved by default (use `copy` to override)", - expr_descr, name, pronoun, + expr_descr, *name, pronoun, ty_to_str(self.tcx, move_expr_ty))); } - fn report_illegal_read(chk_span: span, + fn report_illegal_read(&self, chk_span: span, lnk: LiveNodeKind, var: Variable, rk: ReadKind) { @@ -1858,12 +1865,12 @@ impl @Liveness { FreeVarNode(span) => { self.tcx.sess.span_err( span, - fmt!("capture of %s: `%s`", msg, name)); + fmt!("capture of %s: `%s`", msg, *name)); } ExprNode(span) => { self.tcx.sess.span_err( span, - fmt!("use of %s: `%s`", msg, name)); + fmt!("use of %s: `%s`", msg, *name)); } ExitNode | VarDefNode(_) => { self.tcx.sess.span_bug( @@ -1873,12 +1880,12 @@ impl @Liveness { } } - fn should_warn(var: Variable) -> Option<~str> { + fn should_warn(&self, var: Variable) -> Option<@~str> { let name = self.ir.variable_name(var); - if name[0] == ('_' as u8) {None} else {Some(name)} + if name[0] == ('_' as u8) { None } else { Some(name) } } - fn warn_about_unused_args(decl: fn_decl, entry_ln: LiveNode) { + fn warn_about_unused_args(&self, decl: fn_decl, entry_ln: LiveNode) { for decl.inputs.each |arg| { do pat_util::pat_bindings(self.tcx.def_map, arg.pat) |_bm, p_id, sp, _n| { @@ -1888,7 +1895,7 @@ impl @Liveness { } } - fn warn_about_unused_or_dead_vars_in_pat(pat: @pat) { + fn warn_about_unused_or_dead_vars_in_pat(&self, pat: @pat) { do self.pat_bindings(pat) |ln, var, sp| { if !self.warn_about_unused(sp, ln, var) { self.warn_about_dead_assign(sp, ln, var); @@ -1896,7 +1903,8 @@ impl @Liveness { } } - fn warn_about_unused(sp: span, ln: LiveNode, var: Variable) -> bool { + fn warn_about_unused(&self, sp: span, ln: LiveNode, var: Variable) + -> bool { if !self.used_on_entry(ln, var) { for self.should_warn(var).each |name| { @@ -1913,11 +1921,11 @@ impl @Liveness { // FIXME(#3266)--make liveness warnings lintable self.tcx.sess.span_warn( sp, fmt!("variable `%s` is assigned to, \ - but never used", *name)); + but never used", **name)); } else { // FIXME(#3266)--make liveness warnings lintable self.tcx.sess.span_warn( - sp, fmt!("unused variable: `%s`", *name)); + sp, fmt!("unused variable: `%s`", **name)); } } return true; @@ -1925,13 +1933,13 @@ impl @Liveness { return false; } - fn warn_about_dead_assign(sp: span, ln: LiveNode, var: Variable) { + fn warn_about_dead_assign(&self, sp: span, ln: LiveNode, var: Variable) { if self.live_on_exit(ln, var).is_none() { for self.should_warn(var).each |name| { // FIXME(#3266)--make liveness warnings lintable self.tcx.sess.span_warn( sp, - fmt!("value assigned to `%s` is never read", *name)); + fmt!("value assigned to `%s` is never read", **name)); } } } diff --git a/src/librustc/middle/mem_categorization.rs b/src/librustc/middle/mem_categorization.rs index c4612e7602417..f027ca99d514f 100644 --- a/src/librustc/middle/mem_categorization.rs +++ b/src/librustc/middle/mem_categorization.rs @@ -263,7 +263,7 @@ pub fn cat_def( return mcx.cat_def(expr_id, expr_span, expr_ty, def); } -pub fn cat_variant( +pub fn cat_variant( tcx: ty::ctxt, method_map: typeck::method_map, arg: N, @@ -277,27 +277,27 @@ pub fn cat_variant( } pub trait ast_node { - fn id() -> ast::node_id; - fn span() -> span; + fn id(&self) -> ast::node_id; + fn span(&self) -> span; } -pub impl @ast::expr: ast_node { - fn id() -> ast::node_id { self.id } - fn span() -> span { self.span } +pub impl ast_node for @ast::expr { + fn id(&self) -> ast::node_id { self.id } + fn span(&self) -> span { self.span } } -pub impl @ast::pat: ast_node { - fn id() -> ast::node_id { self.id } - fn span() -> span { self.span } +pub impl ast_node for @ast::pat { + fn id(&self) -> ast::node_id { self.id } + fn span(&self) -> span { self.span } } pub trait get_type_for_node { - fn ty(node: N) -> ty::t; + fn ty(&self, node: N) -> ty::t; } -pub impl ty::ctxt: get_type_for_node { - fn ty(node: N) -> ty::t { - ty::node_id_to_type(self, node.id()) +pub impl get_type_for_node for ty::ctxt { + fn ty(&self, node: N) -> ty::t { + ty::node_id_to_type(*self, node.id()) } } @@ -313,7 +313,7 @@ impl ToStr for MutabilityCategory { } impl MutabilityCategory { - static fn from_mutbl(m: ast::mutability) -> MutabilityCategory { + static fn from_mutbl(&self, m: ast::mutability) -> MutabilityCategory { match m { m_imm => McImmutable, m_const => McReadOnly, @@ -575,7 +575,7 @@ pub impl mem_categorization_ctxt { } } - fn cat_variant(&self, + fn cat_variant(&self, arg: N, enum_did: ast::def_id, cmt: cmt) -> cmt { @@ -589,7 +589,7 @@ pub impl mem_categorization_ctxt { } } - fn cat_rvalue(&self, elt: N, expr_ty: ty::t) -> cmt { + fn cat_rvalue(&self, elt: N, expr_ty: ty::t) -> cmt { @cmt_ { id:elt.id(), span:elt.span(), @@ -629,7 +629,7 @@ pub impl mem_categorization_ctxt { self.tcx.sess.span_bug( node.span(), fmt!("Cannot find field `%s` in type `%s`", - self.tcx.sess.str_of(f_name), + *self.tcx.sess.str_of(f_name), ty_to_str(self.tcx, base_cmt.ty))); } }; @@ -739,7 +739,7 @@ pub impl mem_categorization_ctxt { } } - fn cat_index(&self, + fn cat_index(&self, elt: N, base_cmt: cmt) -> cmt { let mt = match ty::index(self.tcx, base_cmt.ty) { @@ -792,7 +792,7 @@ pub impl mem_categorization_ctxt { } }; - fn comp(elt: N, of_cmt: cmt, + fn comp(elt: N, of_cmt: cmt, vect: ty::t, mutbl: MutabilityCategory, mt: ty::mt) -> cmt { @@ -809,7 +809,7 @@ pub impl mem_categorization_ctxt { } } - fn cat_tuple_elt(&self, + fn cat_tuple_elt(&self, elt: N, cmt: cmt) -> cmt { @cmt_ { @@ -822,7 +822,7 @@ pub impl mem_categorization_ctxt { } } - fn cat_anon_struct_field(&self, + fn cat_anon_struct_field(&self, elt: N, cmt: cmt) -> cmt { @cmt_ { @@ -995,7 +995,7 @@ pub impl mem_categorization_ctxt { self.ptr_sigil(ptr), derefs) } cat_comp(cmt, comp) => { - fmt!("%s.%s", self.cat_to_repr(cmt.cat), self.comp_to_repr(comp)) + fmt!("%s.%s", self.cat_to_repr(cmt.cat), *self.comp_to_repr(comp)) } cat_discr(cmt, _) => self.cat_to_repr(cmt.cat) } @@ -1018,13 +1018,13 @@ pub impl mem_categorization_ctxt { } } - fn comp_to_repr(&self, comp: comp_kind) -> ~str { + fn comp_to_repr(&self, comp: comp_kind) -> @~str { match comp { comp_field(fld, _) => self.tcx.sess.str_of(fld), - comp_index(*) => ~"[]", - comp_tuple => ~"()", - comp_anon_field => ~"", - comp_variant(_) => ~"" + comp_index(*) => @~"[]", + comp_tuple => @~"()", + comp_anon_field => @~"", + comp_variant(_) => @~"" } } @@ -1043,7 +1043,7 @@ pub impl mem_categorization_ctxt { } lp_comp(lp, comp) => { fmt!("%s.%s", self.lp_to_str(lp), - self.comp_to_repr(comp)) + *self.comp_to_repr(comp)) } } } diff --git a/src/librustc/middle/resolve.rs b/src/librustc/middle/resolve.rs index acb73e90c5d58..689d6ca40eefe 100644 --- a/src/librustc/middle/resolve.rs +++ b/src/librustc/middle/resolve.rs @@ -15,7 +15,7 @@ use driver::session::Session; use metadata::csearch::{each_path, get_method_names_if_trait}; use metadata::csearch::{get_static_methods_if_impl, get_struct_fields}; use metadata::csearch::{get_type_name_if_impl}; -use metadata::cstore::find_use_stmt_cnum; +use metadata::cstore::find_extern_mod_stmt_cnum; use metadata::decoder::{def_like, dl_def, dl_field, dl_impl}; use middle::lang_items::LanguageItems; use middle::lint::{deny, allow, forbid, level, unused_imports, warn}; @@ -55,7 +55,7 @@ use syntax::ast::{ty_bool, ty_char, ty_f, ty_f32, ty_f64, ty_float, ty_i}; use syntax::ast::{ty_i16, ty_i32, ty_i64, ty_i8, ty_int, ty_param, ty_path}; use syntax::ast::{ty_str, ty_u, ty_u16, ty_u32, ty_u64, ty_u8, ty_uint}; use syntax::ast::{type_value_ns, ty_param_bound, unnamed_field}; -use syntax::ast::{variant, view_item, view_item_import}; +use syntax::ast::{variant, view_item, view_item_extern_mod}; use syntax::ast::{view_item_use, view_path_glob, view_path_list}; use syntax::ast::{view_path_simple, visibility, anonymous, named, not}; use syntax::ast::{unsafe_fn}; @@ -96,17 +96,21 @@ pub type BindingMap = HashMap; // Implementation resolution // -// XXX: This kind of duplicates information kept in ty::method. Maybe it -// should go away. +// FIXME #4946: This kind of duplicates information kept in +// ty::method. Maybe it should go away. -pub type MethodInfo = { +pub struct MethodInfo { did: def_id, n_tps: uint, ident: ident, self_type: self_ty_ -}; +} -pub type Impl = { did: def_id, ident: ident, methods: ~[@MethodInfo] }; +pub struct Impl { + did: def_id, + ident: ident, + methods: ~[@MethodInfo] +} // Trait method resolution pub type TraitMap = @HashMap>; @@ -116,7 +120,7 @@ pub type TraitMap = @HashMap>; pub type ExportMap2 = HashMap; pub struct Export2 { - name: ~str, // The name of the target. + name: @~str, // The name of the target. def_id: def_id, // The definition of the target. reexport: bool, // Whether this is a reexport. } @@ -146,12 +150,12 @@ pub enum NamespaceResult { UnboundResult, /// Means that resolve has determined that the name is bound in the Module /// argument, and specified by the NameBindings argument. - BoundResult(@Module, @mut NameBindings) + BoundResult(@mut Module, @mut NameBindings) } pub impl NamespaceResult { - pure fn is_unknown() -> bool { - match self { + pure fn is_unknown(&self) -> bool { + match *self { UnknownResult => true, _ => false } @@ -192,7 +196,7 @@ pub enum ImportDirectiveSubclass { /// The context that we thread through while building the reduced graph. pub enum ReducedGraphParent { - ModuleReducedGraphParent(@Module) + ModuleReducedGraphParent(@mut Module) } pub enum ResolveResult { @@ -202,11 +206,11 @@ pub enum ResolveResult { } pub impl ResolveResult { - fn failed() -> bool { - match self { Failed => true, _ => false } + fn failed(&self) -> bool { + match *self { Failed => true, _ => false } } - fn indeterminate() -> bool { - match self { Indeterminate => true, _ => false } + fn indeterminate(&self) -> bool { + match *self { Indeterminate => true, _ => false } } } @@ -268,8 +272,8 @@ pub enum MethodSort { // allows it to reference private names. Currently, this is used for the test // runner. // -// XXX: The X-ray flag is kind of questionable in the first place. It might -// be better to introduce an expr_xray_path instead. +// 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] pub enum XrayFlag { @@ -289,7 +293,7 @@ pub enum SearchThroughModulesFlag { pub enum ModulePrefixResult { NoPrefixFound, - PrefixFound(@Module, uint) + PrefixFound(@mut Module, uint) } #[deriving_eq] @@ -364,11 +368,13 @@ pub fn ImportDirective(privacy: Privacy, /// The item that an import resolves to. pub struct Target { - target_module: @Module, + target_module: @mut Module, bindings: @mut NameBindings, } -pub fn Target(target_module: @Module, bindings: @mut NameBindings) -> Target { +pub fn Target(target_module: @mut Module, + bindings: @mut NameBindings) + -> Target { Target { target_module: target_module, bindings: bindings @@ -411,7 +417,7 @@ pub fn ImportResolution(privacy: Privacy, } pub impl ImportResolution { - fn target_for_namespace(namespace: Namespace) -> Option { + fn target_for_namespace(&self, namespace: Namespace) -> Option { match namespace { TypeNS => return copy self.type_target, ValueNS => return copy self.value_target @@ -431,8 +437,8 @@ pub fn ImportState() -> ImportState { /// The link from a module up to its nearest parent node. pub enum ParentLink { NoParentLink, - ModuleParentLink(@Module, ident), - BlockParentLink(@Module, node_id) + ModuleParentLink(@mut Module, ident), + BlockParentLink(@mut Module, node_id) } /// The type of module this is. @@ -446,11 +452,11 @@ pub enum ModuleKind { /// One node in the tree of modules. pub struct Module { parent_link: ParentLink, - mut def_id: Option, + def_id: Option, kind: ModuleKind, - children: HashMap, - imports: DVec<@ImportDirective>, + children: @HashMap, + imports: @DVec<@ImportDirective>, // The anonymous children of this node. Anonymous children are pseudo- // modules that are implicitly created around items contained within @@ -467,24 +473,16 @@ pub struct Module { // There will be an anonymous module created around `g` with the ID of the // entry block for `f`. - anonymous_children: HashMap, - - // XXX: This is about to be reworked so that exports are on individual - // items, not names. - // - // The ident is the name of the exported item, while the node ID is the - // ID of the export path. - - exported_names: HashMap, + anonymous_children: @HashMap, // The status of resolving each import in this module. - import_resolutions: HashMap, + import_resolutions: @HashMap, // The number of unresolved globs that this module exports. - mut glob_count: uint, + glob_count: uint, // The index of the import we're resolving. - mut resolved_import_count: uint, + resolved_import_count: uint, } pub fn Module(parent_link: ParentLink, @@ -495,18 +493,17 @@ pub fn Module(parent_link: ParentLink, parent_link: parent_link, def_id: def_id, kind: kind, - children: HashMap(), - imports: DVec(), - anonymous_children: HashMap(), - exported_names: HashMap(), - import_resolutions: HashMap(), + children: @HashMap(), + imports: @DVec(), + anonymous_children: @HashMap(), + import_resolutions: @HashMap(), glob_count: 0, resolved_import_count: 0 } } pub impl Module { - fn all_imports_resolved() -> bool { + fn all_imports_resolved(&self) -> bool { return self.imports.len() == self.resolved_import_count; } } @@ -524,7 +521,7 @@ pub fn unused_import_lint_level(session: Session) -> level { // Records a possibly-private type definition. pub struct TypeNsDef { privacy: Privacy, - module_def: Option<@Module>, + module_def: Option<@mut Module>, type_def: Option } @@ -555,7 +552,7 @@ pub impl NameBindings { kind: ModuleKind, sp: span) { // Merges the module with the existing type def or creates a new one. - let module_ = @Module(parent_link, def_id, kind); + let module_ = @mut Module(parent_link, def_id, kind); match self.type_def { None => { self.type_def = Some(TypeNsDef { @@ -604,7 +601,7 @@ pub impl NameBindings { } /// Returns the module node if applicable. - fn get_module_if_available() -> Option<@Module> { + fn get_module_if_available() -> Option<@mut Module> { match self.type_def { Some(ref type_def) => (*type_def).module_def, None => None @@ -615,7 +612,7 @@ pub impl NameBindings { * Returns the module node. Fails if this node does not have a module * definition. */ - fn get_module(@mut self) -> @Module { + fn get_module(@mut self) -> @mut Module { match self.get_module_if_available() { None => { fail!(~"get_module called on a node with no module \ @@ -709,7 +706,7 @@ pub struct PrimitiveTypeTable { } pub impl PrimitiveTypeTable { - fn intern(intr: @ident_interner, string: @~str, + fn intern(&self, intr: @ident_interner, string: @~str, primitive_type: prim_ty) { let ident = intr.intern(string); self.primitive_types.insert(ident, primitive_type); @@ -764,7 +761,7 @@ pub fn Resolver(session: Session, let current_module = graph_root.get_module(); let self = Resolver { - session: session, + session: @session, lang_items: copy lang_items, crate: crate, @@ -775,8 +772,8 @@ pub fn Resolver(session: Session, unused_import_lint_level: unused_import_lint_level(session), - trait_info: HashMap(), - structs: HashMap(), + trait_info: @HashMap(), + structs: @HashMap(), unresolved_imports: 0, @@ -799,19 +796,19 @@ pub fn Resolver(session: Session, attr_main_fn: None, main_fns: ~[], - def_map: HashMap(), - export_map2: HashMap(), + def_map: @HashMap(), + export_map2: @HashMap(), trait_map: @HashMap(), intr: session.intr() }; - move self + self } /// The main resolver class. pub struct Resolver { - session: Session, + session: @Session, lang_items: LanguageItems, crate: @crate, @@ -821,17 +818,17 @@ pub struct Resolver { unused_import_lint_level: level, - trait_info: HashMap>, - structs: HashMap, + trait_info: @HashMap>, + structs: @HashMap, // The number of imports that are currently unresolved. - mut unresolved_imports: uint, + unresolved_imports: uint, // The module that represents the current item scope. - mut current_module: @Module, + current_module: @mut Module, // The current set of local scopes, for values. - // XXX: Reuse ribs to avoid allocation. + // FIXME #4948: Reuse ribs to avoid allocation. value_ribs: @DVec<@Rib>, // The current set of local scopes, for types. @@ -842,10 +839,10 @@ pub struct Resolver { // Whether the current context is an X-ray context. An X-ray context is // allowed to access private names of any module. - mut xray_context: XrayFlag, + xray_context: XrayFlag, // The trait that the current context can refer to. - mut current_trait_refs: Option<@DVec>, + current_trait_refs: Option<@DVec>, // The ident for the keyword "self". self_ident: ident, @@ -859,19 +856,19 @@ pub struct Resolver { namespaces: ~[Namespace], // The function that has attribute named 'main' - mut attr_main_fn: Option<(node_id, span)>, + attr_main_fn: Option<(node_id, span)>, // The functions named 'main' - mut main_fns: ~[Option<(node_id, span)>], + main_fns: ~[Option<(node_id, span)>], - def_map: DefMap, - export_map2: ExportMap2, + def_map: @DefMap, + export_map2: @ExportMap2, trait_map: TraitMap, } pub impl Resolver { /// The main name resolution procedure. - fn resolve(@self, this: @Resolver) { - self.build_reduced_graph(this); + fn resolve(@mut self) { + self.build_reduced_graph(); self.session.abort_if_errors(); self.resolve_imports(); @@ -895,25 +892,25 @@ pub impl Resolver { // /// Constructs the reduced graph for the entire crate. - fn build_reduced_graph(this: @Resolver) { + fn build_reduced_graph(@mut self) { let initial_parent = ModuleReducedGraphParent(self.graph_root.get_module()); visit_crate(*self.crate, initial_parent, mk_vt(@Visitor { visit_item: |item, context, visitor| - (*this).build_reduced_graph_for_item(item, context, visitor), + self.build_reduced_graph_for_item(item, context, visitor), visit_foreign_item: |foreign_item, context, visitor| - (*this).build_reduced_graph_for_foreign_item(foreign_item, + self.build_reduced_graph_for_foreign_item(foreign_item, context, visitor), visit_view_item: |view_item, context, visitor| - (*this).build_reduced_graph_for_view_item(view_item, + self.build_reduced_graph_for_view_item(view_item, context, visitor), visit_block: |block, context, visitor| - (*this).build_reduced_graph_for_block(block, + self.build_reduced_graph_for_block(block, context, visitor), @@ -922,8 +919,9 @@ pub impl Resolver { } /// Returns the current module tracked by the reduced graph parent. - fn get_module_from_parent(reduced_graph_parent: ReducedGraphParent) - -> @Module { + fn get_module_from_parent(@mut self, + reduced_graph_parent: ReducedGraphParent) + -> @mut Module { match reduced_graph_parent { ModuleReducedGraphParent(module_) => { return module_; @@ -941,7 +939,8 @@ pub impl Resolver { * If this node does not have a module definition and we are not inside * a block, fails. */ - fn add_child(name: ident, + fn add_child(@mut self, + name: ident, reduced_graph_parent: ReducedGraphParent, duplicate_checking_mode: DuplicateCheckingMode, // For printing errors @@ -1015,12 +1014,12 @@ pub impl Resolver { self.session.span_err(sp, fmt!("duplicate definition of %s %s", namespace_to_str(ns), - self.session.str_of(name))); + *self.session.str_of(name))); do child.span_for_namespace(ns).iter() |sp| { self.session.span_note(*sp, fmt!("first definition of %s %s here:", namespace_to_str(ns), - self.session.str_of(name))); + *self.session.str_of(name))); } } return (child, new_parent); @@ -1028,7 +1027,7 @@ pub impl Resolver { } } - fn block_needs_anonymous_module(block: blk) -> bool { + fn block_needs_anonymous_module(@mut self, block: blk) -> bool { // If the block has view items, we need an anonymous module. if block.node.view_items.len() > 0 { return true; @@ -1059,8 +1058,10 @@ pub impl Resolver { return false; } - fn get_parent_link(parent: ReducedGraphParent, - name: ident) -> ParentLink { + fn get_parent_link(@mut self, + parent: ReducedGraphParent, + name: ident) + -> ParentLink { match parent { ModuleReducedGraphParent(module_) => { return ModuleParentLink(module_, name); @@ -1069,7 +1070,8 @@ pub impl Resolver { } /// Constructs the reduced graph for one item. - fn build_reduced_graph_for_item(item: @item, + fn build_reduced_graph_for_item(@mut self, + item: @item, parent: ReducedGraphParent, &&visitor: vt) { let ident = item.ident; @@ -1344,12 +1346,12 @@ pub impl Resolver { // Constructs the reduced graph for one variant. Variants exist in the // type and/or value namespaces. - fn build_reduced_graph_for_variant(variant: variant, + fn build_reduced_graph_for_variant(@mut self, + variant: variant, item_id: def_id, +parent_privacy: Privacy, parent: ReducedGraphParent, &&visitor: vt) { - let ident = variant.node.name; let (child, _) = self.add_child(ident, parent, ForbidDuplicateValues, variant.span); @@ -1392,12 +1394,13 @@ pub impl Resolver { * Constructs the reduced graph for one 'view item'. View items consist * of imports and use directives. */ - fn build_reduced_graph_for_view_item(view_item: @view_item, + fn build_reduced_graph_for_view_item(@mut self, + view_item: @view_item, parent: ReducedGraphParent, &&_visitor: vt) { let privacy = visibility_to_privacy(view_item.vis); match /*bad*/copy view_item.node { - view_item_import(view_paths) => { + view_item_use(view_paths) => { for view_paths.each |view_path| { // Extract and intern the module part of the path. For // globs and lists, the path is found directly in the AST; @@ -1471,8 +1474,9 @@ pub impl Resolver { } } - view_item_use(name, _, node_id) => { - match find_use_stmt_cnum(self.session.cstore, node_id) { + view_item_extern_mod(name, _, node_id) => { + match find_extern_mod_stmt_cnum(self.session.cstore, + node_id) { Some(crate_id) => { let (child_name_bindings, new_parent) = self.add_child(name, parent, ForbidDuplicateTypes, @@ -1499,11 +1503,11 @@ pub impl Resolver { } /// Constructs the reduced graph for one foreign item. - fn build_reduced_graph_for_foreign_item(foreign_item: @foreign_item, + fn build_reduced_graph_for_foreign_item(@mut self, + foreign_item: @foreign_item, parent: ReducedGraphParent, &&visitor: vt) { - let name = foreign_item.ident; let (name_bindings, new_parent) = self.add_child(name, parent, ForbidDuplicateValues, @@ -1529,10 +1533,10 @@ pub impl Resolver { } } - fn build_reduced_graph_for_block(block: blk, + fn build_reduced_graph_for_block(@mut self, + block: blk, parent: ReducedGraphParent, &&visitor: vt) { - let mut new_parent; if self.block_needs_anonymous_module(block) { let block_id = block.node.id; @@ -1542,9 +1546,10 @@ pub impl Resolver { block_id); let parent_module = self.get_module_from_parent(parent); - let new_module = @Module(BlockParentLink(parent_module, block_id), - None, - AnonymousModuleKind); + let new_module = @mut Module( + BlockParentLink(parent_module, block_id), + None, + AnonymousModuleKind); parent_module.anonymous_children.insert(block_id, new_module); new_parent = ModuleReducedGraphParent(new_module); } else { @@ -1554,10 +1559,11 @@ pub impl Resolver { visit_block(block, new_parent, visitor); } - fn handle_external_def(def: def, - modules: HashMap, + fn handle_external_def(@mut self, + def: def, + modules: HashMap, child_name_bindings: @mut NameBindings, - final_ident: ~str, + final_ident: &str, ident: ident, new_parent: ReducedGraphParent) { match def { @@ -1642,7 +1648,7 @@ pub impl Resolver { debug!("(building reduced graph for \ external crate) ... adding \ trait method '%s'", - self.session.str_of(method_name)); + *self.session.str_of(method_name)); // Add it to the trait info if not static. if self_ty != sty_static { @@ -1675,7 +1681,7 @@ pub impl Resolver { * Builds the reduced graph rooted at the 'use' directive for an external * crate. */ - fn build_reduced_graph_for_external_crate(root: @Module) { + fn build_reduced_graph_for_external_crate(@mut self, root: @mut Module) { let modules = HashMap(); // Create all the items reachable by paths. @@ -1749,7 +1755,8 @@ pub impl Resolver { self.handle_external_def(def, modules, child_name_bindings, - self.session.str_of(final_ident), + *self.session.str_of( + final_ident), final_ident, new_parent); } @@ -1767,7 +1774,8 @@ pub impl Resolver { debug!("(building reduced graph for \ external crate) processing \ static methods for type name %s", - self.session.str_of(final_ident)); + *self.session.str_of( + final_ident)); let (child_name_bindings, new_parent) = self.add_child(final_ident, @@ -1813,7 +1821,7 @@ pub impl Resolver { debug!("(building reduced graph for \ external crate) creating \ static method '%s'", - self.session.str_of(ident)); + *self.session.str_of(ident)); let (method_name_bindings, _) = self.add_child( @@ -1844,8 +1852,9 @@ pub impl Resolver { } /// Creates and adds an import directive to the given module. - fn build_import_directive(privacy: Privacy, - module_: @Module, + fn build_import_directive(@mut self, + privacy: Privacy, + module_: @mut Module, module_path: @DVec, subclass: @ImportDirectiveSubclass, span: span, @@ -1863,7 +1872,7 @@ pub impl Resolver { directive: privacy %? %s::%s", privacy, self.idents_to_str(module_path.get()), - self.session.str_of(target)); + *self.session.str_of(target)); match module_.import_resolutions.find(&target) { Some(resolution) => { @@ -1910,7 +1919,7 @@ pub impl Resolver { * Resolves all imports for the crate. This method performs the fixed- * point iteration. */ - fn resolve_imports() { + fn resolve_imports(@mut self) { let mut i = 0; let mut prev_unresolved_imports = 0; loop { @@ -1940,7 +1949,7 @@ pub impl Resolver { * Attempts to resolve imports for the given module and all of its * submodules. */ - fn resolve_imports_for_module_subtree(module_: @Module) { + fn resolve_imports_for_module_subtree(@mut self, module_: @mut Module) { debug!("(resolving imports for module subtree) resolving %s", self.module_to_str(module_)); self.resolve_imports_for_module(module_); @@ -1962,7 +1971,7 @@ pub impl Resolver { } /// Attempts to resolve imports for the given module only. - fn resolve_imports_for_module(module_: @Module) { + fn resolve_imports_for_module(@mut self, module_: @mut Module) { if (*module_).all_imports_resolved() { debug!("(resolving imports for module) all imports resolved for \ %s", @@ -1979,8 +1988,8 @@ pub impl Resolver { // We presumably emitted an error. Continue. let idents = import_directive.module_path.get(); let msg = fmt!("failed to resolve import: %s", - self.import_path_to_str(idents, - *import_directive.subclass)); + *self.import_path_to_str(idents, + *import_directive.subclass)); self.session.span_err(import_directive.span, msg); } Indeterminate => { @@ -1996,27 +2005,32 @@ pub impl Resolver { } } - fn idents_to_str(idents: ~[ident]) -> ~str { - let ident_strs = idents.map(|&ident| self.session.str_of(ident)); - return str::connect(ident_strs, "::"); + fn idents_to_str(@mut self, idents: ~[ident]) -> ~str { + let ident_strs = do idents.map |ident| { + /*bad*/ copy *self.session.str_of(*ident) + }; + str::connect(ident_strs, "::") } - fn import_directive_subclass_to_str(subclass: ImportDirectiveSubclass) - -> ~str { + fn import_directive_subclass_to_str(@mut self, + subclass: ImportDirectiveSubclass) + -> @~str { match subclass { SingleImport(_target, source, _ns) => self.session.str_of(source), - GlobImport => ~"*" + GlobImport => @~"*" } } - fn import_path_to_str(idents: ~[ident], subclass: ImportDirectiveSubclass) - -> ~str { + fn import_path_to_str(@mut self, + idents: ~[ident], + subclass: ImportDirectiveSubclass) + -> @~str { if idents.is_empty() { self.import_directive_subclass_to_str(subclass) } else { - fmt!("%s::%s", + @fmt!("%s::%s", self.idents_to_str(idents), - self.import_directive_subclass_to_str(subclass)) + *self.import_directive_subclass_to_str(subclass)) } } @@ -2027,10 +2041,10 @@ pub impl Resolver { * currently-unresolved imports, or success if we know the name exists. * If successful, the resolved bindings are written into the module. */ - fn resolve_import_for_module(module_: @Module, + fn resolve_import_for_module(@mut self, + module_: @mut Module, import_directive: @ImportDirective) -> ResolveResult<()> { - let mut resolution_result; let module_path = import_directive.module_path; @@ -2122,23 +2136,24 @@ pub impl Resolver { return resolution_result; } - fn resolve_single_import(module_: @Module, - containing_module: @Module, + fn resolve_single_import(@mut self, + module_: @mut Module, + containing_module: @mut Module, target: ident, source: ident) -> ResolveResult<()> { - debug!("(resolving single import) resolving `%s` = `%s::%s` from \ `%s`", - self.session.str_of(target), + *self.session.str_of(target), self.module_to_str(containing_module), - self.session.str_of(source), + *self.session.str_of(source), self.module_to_str(module_)); // We need to resolve both namespaces for this to succeed. // - // XXX: See if there's some way of handling namespaces in a more - // generic way. We have two of them; it seems worth doing... + // FIXME #4949: See if there's some way of handling namespaces in + // a more generic way. We have two of them; it seems worth + // doing... let mut value_result = UnknownResult; let mut type_result = UnknownResult; @@ -2313,17 +2328,17 @@ pub impl Resolver { return Success(()); } - fn resolve_single_module_import(module_: @Module, - containing_module: @Module, + fn resolve_single_module_import(@mut self, + module_: @mut Module, + containing_module: @mut Module, target: ident, source: ident) -> ResolveResult<()> { - debug!("(resolving single module import) resolving `%s` = `%s::%s` \ from `%s`", - self.session.str_of(target), + *self.session.str_of(target), self.module_to_str(containing_module), - self.session.str_of(source), + *self.session.str_of(source), self.module_to_str(module_)); // We need to resolve the module namespace for this to succeed. @@ -2442,9 +2457,10 @@ pub impl Resolver { * succeeds or bails out (as importing * from an empty module or a module * that exports nothing is valid). */ - fn resolve_glob_import(privacy: Privacy, - module_: @Module, - containing_module: @Module, + fn resolve_glob_import(@mut self, + privacy: Privacy, + module_: @mut Module, + containing_module: @mut Module, span: span) -> ResolveResult<()> { // This function works in a highly imperative manner; it eagerly adds @@ -2534,7 +2550,7 @@ pub impl Resolver { 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_), dest_import_resolution.privacy); @@ -2556,11 +2572,12 @@ pub impl Resolver { return Success(()); } - fn resolve_module_path_from_root(module_: @Module, + fn resolve_module_path_from_root(@mut self, + module_: @mut Module, module_path: @DVec, index: uint, span: span) - -> ResolveResult<@Module> { + -> ResolveResult<@mut Module> { let mut search_module = module_; let mut index = index; let module_path_len = (*module_path).len(); @@ -2582,7 +2599,7 @@ pub impl Resolver { Indeterminate => { debug!("(resolving module path for import) module \ resolution is indeterminate: %s", - self.session.str_of(name)); + *self.session.str_of(name)); return Indeterminate; } Success(target) => { @@ -2596,7 +2613,7 @@ pub impl Resolver { self.session.span_err(span, fmt!("not a \ module: %s", - self.session. + *self.session. str_of( name))); return Failed; @@ -2610,7 +2627,7 @@ pub impl Resolver { // There are no type bindings at all. self.session.span_err(span, fmt!("not a module: %s", - self.session.str_of( + *self.session.str_of( name))); return Failed; } @@ -2628,12 +2645,12 @@ pub impl Resolver { * Attempts to resolve the module part of an import directive or path * rooted at the given module. */ - fn resolve_module_path_for_import(module_: @Module, + fn resolve_module_path_for_import(@mut self, + module_: @mut Module, module_path: @DVec, use_lexical_scope: UseLexicalScopeFlag, span: span) - -> ResolveResult<@Module> { - + -> ResolveResult<@mut Module> { let module_path_len = (*module_path).len(); assert module_path_len > 0; @@ -2707,16 +2724,16 @@ pub impl Resolver { span); } - fn resolve_item_in_lexical_scope(module_: @Module, + fn resolve_item_in_lexical_scope(@mut self, + module_: @mut Module, name: ident, namespace: Namespace, search_through_modules: SearchThroughModulesFlag) -> ResolveResult { - debug!("(resolving item in lexical scope) resolving `%s` in \ namespace %? in `%s`", - self.session.str_of(name), + *self.session.str_of(name), namespace, self.module_to_str(module_)); @@ -2821,8 +2838,10 @@ pub impl Resolver { } /** Resolves a module name in the current lexical scope. */ - fn resolve_module_in_lexical_scope(module_: @Module, name: ident) - -> ResolveResult<@Module> { + fn resolve_module_in_lexical_scope(@mut self, + module_: @mut Module, + name: ident) + -> ResolveResult<@mut Module> { // If this module is an anonymous module, resolve the item in the // lexical scope. Otherwise, resolve the item from the crate root. let resolve_result = self.resolve_item_in_lexical_scope( @@ -2866,7 +2885,8 @@ pub impl Resolver { /** * Returns the nearest normal module parent of the given module. */ - fn get_nearest_normal_module_parent(module_: @Module) -> Option<@Module> { + fn get_nearest_normal_module_parent(@mut self, module_: @mut Module) + -> Option<@mut Module> { let mut module_ = module_; loop { match module_.parent_link { @@ -2888,7 +2908,9 @@ pub impl Resolver { * Returns the nearest normal module parent of the given module, or the * module itself if it is a normal module. */ - fn get_nearest_normal_module_parent_or_self(module_: @Module) -> @Module { + fn get_nearest_normal_module_parent_or_self(@mut self, + module_: @mut Module) + -> @mut Module { match module_.kind { NormalModuleKind => return module_, ExternModuleKind | TraitModuleKind | AnonymousModuleKind => { @@ -2904,7 +2926,8 @@ pub impl Resolver { * Resolves a "module prefix". A module prefix is one of (a) `self::`; * (b) some chain of `super::`. */ - fn resolve_module_prefix(module_: @Module, + fn resolve_module_prefix(@mut self, + module_: @mut Module, module_path: @DVec) -> ResolveResult { let interner = self.session.parse_sess.interner; @@ -2950,13 +2973,14 @@ pub impl Resolver { * given namespace. If successful, returns the target corresponding to * the name. */ - fn resolve_name_in_module(module_: @Module, + fn resolve_name_in_module(@mut self, + module_: @mut Module, name: ident, namespace: Namespace, allow_globs: bool) -> ResolveResult { debug!("(resolving name in module) resolving `%s` in `%s`", - self.session.str_of(name), + *self.session.str_of(name), self.module_to_str(module_)); // First, check the direct children of the module. @@ -3010,7 +3034,7 @@ pub impl Resolver { // We're out of luck. debug!("(resolving name in module) failed to resolve %s", - self.session.str_of(name)); + *self.session.str_of(name)); return Failed; } @@ -3019,10 +3043,10 @@ pub impl Resolver { * This needs special handling, as, unlike all of the other imports, it * needs to look in the scope chain for modules and non-modules alike. */ - fn resolve_one_level_renaming_import(module_: @Module, + fn resolve_one_level_renaming_import(@mut self, + module_: @mut Module, import_directive: @ImportDirective) -> ResolveResult<()> { - let mut target_name; let mut source_name; let allowable_namespaces; @@ -3039,8 +3063,8 @@ pub impl Resolver { debug!("(resolving one-level naming result) resolving import `%s` = \ `%s` in `%s`", - self.session.str_of(target_name), - self.session.str_of(source_name), + *self.session.str_of(target_name), + *self.session.str_of(source_name), self.module_to_str(module_)); // Find the matching items in the lexical scope chain for every @@ -3161,7 +3185,7 @@ pub impl Resolver { debug!("(resolving one-level renaming import) writing module \ result %? for `%s` into `%s`", is_none(&module_result), - self.session.str_of(target_name), + *self.session.str_of(target_name), self.module_to_str(module_)); import_resolution.value_target = value_result; @@ -3176,7 +3200,7 @@ pub impl Resolver { return Success(()); } - fn report_unresolved_imports(module_: @Module) { + fn report_unresolved_imports(@mut self, module_: @mut Module) { let index = module_.resolved_import_count; let import_count = module_.imports.len(); if index != import_count { @@ -3206,16 +3230,16 @@ pub impl Resolver { // This pass simply determines what all "export" keywords refer to and // writes the results into the export map. // - // XXX: This pass will be removed once exports change to per-item. Then - // this operation can simply be performed as part of item (or import) + // FIXME #4953 This pass will be removed once exports change to per-item. + // Then this operation can simply be performed as part of item (or import) // processing. - fn record_exports() { + fn record_exports(@mut self) { let root_module = self.graph_root.get_module(); self.record_exports_for_module_subtree(root_module); } - fn record_exports_for_module_subtree(module_: @Module) { + fn record_exports_for_module_subtree(@mut self, module_: @mut Module) { // If this isn't a local crate, then bail out. We don't need to record // exports for nonlocal crates. @@ -3257,13 +3281,13 @@ pub impl Resolver { } } - fn record_exports_for_module(module_: @Module) { + fn record_exports_for_module(@mut self, module_: @mut Module) { let mut exports2 = ~[]; self.add_exports_for_module(&mut exports2, module_); match copy module_.def_id { Some(def_id) => { - self.export_map2.insert(def_id.node, move exports2); + self.export_map2.insert(def_id.node, exports2); debug!("(computing exports) writing exports for %d (some)", def_id.node); } @@ -3271,8 +3295,8 @@ pub impl Resolver { } } - - fn add_exports_of_namebindings(exports2: &mut ~[Export2], + fn add_exports_of_namebindings(@mut self, + exports2: &mut ~[Export2], ident: ident, namebindings: @mut NameBindings, ns: Namespace, @@ -3282,7 +3306,7 @@ pub impl Resolver { (Some(d), Some(Public)) => { debug!("(computing exports) YES: %s '%s' => %?", if reexport { ~"reexport" } else { ~"export"}, - self.session.str_of(ident), + *self.session.str_of(ident), def_id_of_def(d)); exports2.push(Export2 { reexport: reexport, @@ -3299,10 +3323,12 @@ pub impl Resolver { } } - fn add_exports_for_module(exports2: &mut ~[Export2], module_: @Module) { + fn add_exports_for_module(@mut self, + exports2: &mut ~[Export2], + module_: @mut Module) { for module_.children.each |ident, namebindings| { debug!("(computing exports) maybe export '%s'", - self.session.str_of(*ident)); + *self.session.str_of(*ident)); self.add_exports_of_namebindings(&mut *exports2, *ident, *namebindings, @@ -3318,14 +3344,14 @@ pub impl Resolver { for module_.import_resolutions.each |ident, importresolution| { if importresolution.privacy != Public { debug!("(computing exports) not reexporting private `%s`", - self.session.str_of(*ident)); + *self.session.str_of(*ident)); loop; } for [ TypeNS, ValueNS ].each |ns| { match importresolution.target_for_namespace(*ns) { Some(target) => { debug!("(computing exports) maybe reexport '%s'", - self.session.str_of(*ident)); + *self.session.str_of(*ident)); self.add_exports_of_namebindings(&mut *exports2, *ident, target.bindings, @@ -3356,7 +3382,7 @@ pub impl Resolver { // generate a fake "implementation scope" containing all the // implementations thus found, for compatibility with old resolve pass. - fn with_scope(name: Option, f: fn()) { + fn with_scope(@mut self, name: Option, f: fn()) { let orig_module = self.current_module; // Move down in the graph. @@ -3368,7 +3394,7 @@ pub impl Resolver { match orig_module.children.find(&name) { None => { debug!("!!! (with scope) didn't find `%s` in `%s`", - self.session.str_of(name), + *self.session.str_of(name), self.module_to_str(orig_module)); } Some(name_bindings) => { @@ -3376,7 +3402,7 @@ pub impl Resolver { None => { debug!("!!! (with scope) didn't find module \ for `%s` in `%s`", - self.session.str_of(name), + *self.session.str_of(name), self.module_to_str(orig_module)); } Some(module_) => { @@ -3396,10 +3422,13 @@ pub impl Resolver { // Wraps the given definition in the appropriate number of `def_upvar` // wrappers. - fn upvarify(ribs: @DVec<@Rib>, rib_index: uint, def_like: def_like, - span: span, allow_capturing_self: AllowCapturingSelfFlag) + fn upvarify(@mut self, + ribs: @DVec<@Rib>, + rib_index: uint, + def_like: def_like, + span: span, + allow_capturing_self: AllowCapturingSelfFlag) -> Option { - let mut def; let mut is_ty_param; @@ -3503,12 +3532,14 @@ pub impl Resolver { return Some(dl_def(def)); } - fn search_ribs(ribs: @DVec<@Rib>, name: ident, span: span, + fn search_ribs(@mut self, + ribs: @DVec<@Rib>, + name: ident, + span: span, allow_capturing_self: AllowCapturingSelfFlag) -> Option { - - // XXX: This should not use a while loop. - // XXX: Try caching? + // FIXME #4950: This should not use a while loop. + // FIXME #4950: Try caching? let mut i = (*ribs).len(); while i != 0 { @@ -3528,7 +3559,7 @@ pub impl Resolver { return None; } - fn resolve_crate(@self) { + fn resolve_crate(@mut self) { debug!("(resolving crate) starting"); visit_crate(*self.crate, (), mk_vt(@Visitor { @@ -3548,9 +3579,9 @@ pub impl Resolver { })); } - fn resolve_item(item: @item, visitor: ResolveVisitor) { + fn resolve_item(@mut self, item: @item, visitor: ResolveVisitor) { debug!("(resolving item) resolving %s", - self.session.str_of(item.ident)); + *self.session.str_of(item.ident)); // Items with the !resolve_unexported attribute are X-ray contexts. // This is used to allow the test runner to run unexported tests. @@ -3649,7 +3680,7 @@ pub impl Resolver { // Create a new rib for the method-specific type // parameters. // - // XXX: Do we need a node ID here? + // FIXME #4951: Do we need a node ID here? match *method { required(ref ty_m) => { @@ -3776,7 +3807,9 @@ pub impl Resolver { self.xray_context = orig_xray_flag; } - fn with_type_parameter_rib(type_parameters: TypeParameters, f: fn()) { + fn with_type_parameter_rib(@mut self, + type_parameters: TypeParameters, + f: fn()) { match type_parameters { HasTypeParameters(type_parameters, node_id, initial_index, rib_kind) => { @@ -3817,19 +3850,20 @@ pub impl Resolver { } } - fn with_label_rib(f: fn()) { + fn with_label_rib(@mut self, f: fn()) { (*self.label_ribs).push(@Rib(NormalRibKind)); f(); (*self.label_ribs).pop(); } - fn with_constant_rib(f: fn()) { + + fn with_constant_rib(@mut self, f: fn()) { (*self.value_ribs).push(@Rib(ConstantItemRibKind)); f(); (*self.value_ribs).pop(); } - - fn resolve_function(rib_kind: RibKind, + fn resolve_function(@mut self, + rib_kind: RibKind, optional_declaration: Option<@fn_decl>, type_parameters: TypeParameters, block: blk, @@ -3905,7 +3939,8 @@ pub impl Resolver { (*self.value_ribs).pop(); } - fn resolve_type_parameters(type_parameters: ~[ty_param], + fn resolve_type_parameters(@mut self, + type_parameters: ~[ty_param], visitor: ResolveVisitor) { for type_parameters.each |type_parameter| { for type_parameter.bounds.each |&bound| { @@ -3917,11 +3952,12 @@ pub impl Resolver { } } - fn resolve_struct(id: node_id, - type_parameters: @~[ty_param], - fields: ~[@struct_field], - optional_destructor: Option, - visitor: ResolveVisitor) { + fn resolve_struct(@mut self, + id: node_id, + type_parameters: @~[ty_param], + fields: ~[@struct_field], + optional_destructor: Option, + visitor: ResolveVisitor) { // If applicable, create a rib for the type parameters. let borrowed_type_parameters: &~[ty_param] = &*type_parameters; do self.with_type_parameter_rib(HasTypeParameters @@ -3958,7 +3994,8 @@ pub impl Resolver { // Does this really need to take a RibKind or is it always going // to be NormalRibKind? - fn resolve_method(rib_kind: RibKind, + fn resolve_method(@mut self, + rib_kind: RibKind, method: @method, outer_type_parameter_count: uint, visitor: ResolveVisitor) { @@ -3983,7 +4020,8 @@ pub impl Resolver { visitor); } - fn resolve_implementation(id: node_id, + fn resolve_implementation(@mut self, + id: node_id, span: span, type_parameters: ~[ty_param], opt_trait_reference: Option<@trait_ref>, @@ -4059,15 +4097,18 @@ pub impl Resolver { } } - fn resolve_module(module_: _mod, span: span, _name: ident, id: node_id, + fn resolve_module(@mut self, + module_: _mod, + span: span, + _name: ident, + id: node_id, visitor: ResolveVisitor) { - // Write the implementations in scope into the module metadata. debug!("(resolving module) resolving module ID %d", id); visit_mod(module_, span, id, (), visitor); } - fn resolve_local(local: @local, visitor: ResolveVisitor) { + fn resolve_local(@mut self, local: @local, visitor: ResolveVisitor) { let mutability = if local.node.is_mutbl {Mutable} else {Immutable}; // Resolve the type. @@ -4088,9 +4129,9 @@ pub impl Resolver { None, visitor); } - fn binding_mode_map(pat: @pat) -> BindingMap { + fn binding_mode_map(@mut self, pat: @pat) -> BindingMap { let result = HashMap(); - do pat_bindings(self.def_map, pat) |binding_mode, _id, sp, path| { + do pat_bindings(*self.def_map, pat) |binding_mode, _id, sp, path| { let ident = path_to_ident(path); result.insert(ident, binding_info {span: sp, @@ -4099,7 +4140,7 @@ pub impl Resolver { return result; } - fn check_consistent_bindings(arm: arm) { + fn check_consistent_bindings(@mut self, arm: arm) { if arm.pats.len() == 0 { return; } let map_0 = self.binding_mode_map(arm.pats[0]); for arm.pats.eachi() |i, p| { @@ -4112,7 +4153,7 @@ pub impl Resolver { p.span, fmt!("variable `%s` from pattern #1 is \ not bound in pattern #%u", - self.session.str_of(key), i + 1)); + *self.session.str_of(key), i + 1)); } Some(binding_i) => { if binding_0.binding_mode != binding_i.binding_mode { @@ -4120,7 +4161,7 @@ pub impl Resolver { binding_i.span, fmt!("variable `%s` is bound with different \ mode in pattern #%u than in pattern #1", - self.session.str_of(key), i + 1)); + *self.session.str_of(key), i + 1)); } } } @@ -4132,13 +4173,13 @@ pub impl Resolver { binding.span, fmt!("variable `%s` from pattern #%u is \ not bound in pattern #1", - self.session.str_of(key), i + 1)); + *self.session.str_of(key), i + 1)); } } } } - fn resolve_arm(arm: arm, visitor: ResolveVisitor) { + fn resolve_arm(@mut self, arm: arm, visitor: ResolveVisitor) { (*self.value_ribs).push(@Rib(NormalRibKind)); let bindings_list = HashMap(); @@ -4157,7 +4198,7 @@ pub impl Resolver { (*self.value_ribs).pop(); } - fn resolve_block(block: blk, visitor: ResolveVisitor) { + fn resolve_block(@mut self, block: blk, visitor: ResolveVisitor) { debug!("(resolving block) entering block"); (*self.value_ribs).push(@Rib(NormalRibKind)); @@ -4182,7 +4223,7 @@ pub impl Resolver { debug!("(resolving block) leaving block"); } - fn resolve_type(ty: @Ty, visitor: ResolveVisitor) { + fn resolve_type(@mut self, ty: @Ty, visitor: ResolveVisitor) { match ty.node { // Like path expressions, the interpretation of path types depends // on whether the path has multiple elements in it or not. @@ -4216,7 +4257,7 @@ pub impl Resolver { Some(def) => { debug!("(resolving type) resolved `%s` to \ type %?", - self.session.str_of( + *self.session.str_of( path.idents.last()), def); result_def = Some(def); @@ -4255,14 +4296,14 @@ pub impl Resolver { } } - fn resolve_pattern(pattern: @pat, + fn resolve_pattern(@mut self, + pattern: @pat, mode: PatternBindingMode, mutability: Mutability, // Maps idents to the node ID for the (outermost) // pattern that binds them bindings_list: Option>, visitor: ResolveVisitor) { - let pat_id = pattern.id; do walk_pat(pattern) |pattern| { match pattern.node { @@ -4285,7 +4326,7 @@ pub impl Resolver { if mode == RefutableMode => { debug!("(resolving pattern) resolving `%s` to \ struct or enum variant", - self.session.str_of(ident)); + *self.session.str_of(ident)); self.enforce_default_binding_mode( pattern, @@ -4299,13 +4340,13 @@ pub impl Resolver { shadows an enum \ variant or unit-like \ struct in scope", - self.session - .str_of(ident))); + *self.session + .str_of(ident))); } FoundConst(def) if mode == RefutableMode => { debug!("(resolving pattern) resolving `%s` to \ constant", - self.session.str_of(ident)); + *self.session.str_of(ident)); self.enforce_default_binding_mode( pattern, @@ -4320,7 +4361,7 @@ pub impl Resolver { } BareIdentifierPatternUnresolved => { debug!("(resolving pattern) binding `%s`", - self.session.str_of(ident)); + *self.session.str_of(ident)); let is_mutable = mutability == Mutable; @@ -4402,7 +4443,7 @@ pub impl Resolver { self.session.span_err( path.span, fmt!("not an enum variant: %s", - self.session.str_of( + *self.session.str_of( path.idents.last()))); } None => { @@ -4462,7 +4503,7 @@ pub impl Resolver { } } - fn resolve_bare_identifier_pattern(name: ident) + fn resolve_bare_identifier_pattern(@mut self, name: ident) -> BareIdentifierPatternResolution { match self.resolve_item_in_lexical_scope(self.current_module, name, @@ -4504,7 +4545,8 @@ pub impl Resolver { * If `check_ribs` is true, checks the local definitions first; i.e. * doesn't skip straight to the containing module. */ - fn resolve_path(path: @path, + fn resolve_path(@mut self, + path: @path, namespace: Namespace, check_ribs: bool, visitor: ResolveVisitor) @@ -4532,12 +4574,12 @@ pub impl Resolver { path.span); } - fn resolve_identifier(identifier: ident, + fn resolve_identifier(@mut self, + identifier: ident, namespace: Namespace, check_ribs: bool, span: span) -> Option { - if check_ribs { match self.resolve_identifier_in_local_ribs(identifier, namespace, @@ -4555,13 +4597,13 @@ pub impl Resolver { namespace); } - // XXX: Merge me with resolve_name_in_module? - fn resolve_definition_of_name_in_module(containing_module: @Module, + // FIXME #4952: Merge me with resolve_name_in_module? + fn resolve_definition_of_name_in_module(@mut self, + containing_module: @mut Module, name: ident, namespace: Namespace, xray: XrayFlag) -> NameDefinition { - // First, search children. match containing_module.children.find(&name) { Some(child_name_bindings) => { @@ -4618,7 +4660,7 @@ pub impl Resolver { } } - fn intern_module_part_of_path(path: @path) -> @DVec { + fn intern_module_part_of_path(@mut self, path: @path) -> @DVec { let module_path_idents = @DVec(); for path.idents.eachi |index, ident| { if index == path.idents.len() - 1 { @@ -4631,11 +4673,11 @@ pub impl Resolver { return module_path_idents; } - fn resolve_module_relative_path(path: @path, + fn resolve_module_relative_path(@mut self, + path: @path, +xray: XrayFlag, namespace: Namespace) -> Option { - let module_path_idents = self.intern_module_part_of_path(path); let mut containing_module; @@ -4675,11 +4717,11 @@ pub impl Resolver { } } - fn resolve_crate_relative_path(path: @path, + fn resolve_crate_relative_path(@mut self, + path: @path, +xray: XrayFlag, namespace: Namespace) -> Option { - let module_path_idents = self.intern_module_part_of_path(path); let root_module = self.graph_root.get_module(); @@ -4722,7 +4764,8 @@ pub impl Resolver { } } - fn resolve_identifier_in_local_ribs(ident: ident, + fn resolve_identifier_in_local_ribs(@mut self, + ident: ident, namespace: Namespace, span: span) -> Option { @@ -4743,7 +4786,7 @@ pub impl Resolver { Some(dl_def(def)) => { debug!("(resolving path in local ribs) resolved `%s` to \ local: %?", - self.session.str_of(ident), + *self.session.str_of(ident), def); return Some(def); } @@ -4753,7 +4796,8 @@ pub impl Resolver { } } - fn resolve_item_by_identifier_in_lexical_scope(ident: ident, + fn resolve_item_by_identifier_in_lexical_scope(@mut self, + ident: ident, namespace: Namespace) -> Option { // Check the items. @@ -4771,7 +4815,7 @@ pub impl Resolver { Some(def) => { debug!("(resolving item path in lexical scope) \ resolved `%s` to item", - self.session.str_of(ident)); + *self.session.str_of(ident)); return Some(def); } } @@ -4785,14 +4829,14 @@ pub impl Resolver { } } - fn name_exists_in_scope_struct(name: &str) -> bool { + fn name_exists_in_scope_struct(@mut self, name: &str) -> bool { let mut i = self.type_ribs.len(); while i != 0 { i -= 1; let rib = self.type_ribs.get_elt(i); match rib.kind { MethodRibKind(node_id, _) => - for vec::each(self.crate.node.module.items) |item| { + for self.crate.node.module.items.each |item| { if item.id == node_id { match item.node { item_struct(class_def, _) => { @@ -4800,7 +4844,7 @@ pub impl Resolver { match field.node.kind { unnamed_field => {}, named_field(ident, _, _) => { - if str::eq_slice(self.session.str_of(ident), + if str::eq_slice(*self.session.str_of(ident), name) { return true } @@ -4818,7 +4862,7 @@ pub impl Resolver { return false; } - fn resolve_expr(expr: @expr, visitor: ResolveVisitor) { + fn resolve_expr(@mut self, expr: @expr, visitor: ResolveVisitor) { // First, record candidate traits for this expression if it could // result in the invocation of a method call. @@ -4873,20 +4917,6 @@ pub impl Resolver { expr_struct(path, _, _) => { // Resolve the path to the structure it goes to. - // - // XXX: We might want to support explicit type parameters in - // the path, in which case this gets a little more - // complicated: - // - // 1. Should we go through the ast_path_to_ty() path, which - // handles typedefs and the like? - // - // 2. If so, should programmers be able to write this? - // - // class Foo { ... } - // type Bar = Foo; - // let bar = Bar { ... } // no type parameters - match self.resolve_path(path, TypeNS, false, visitor) { Some(def_ty(class_id)) | Some(def_struct(class_id)) if self.structs.contains_key(&class_id) => { @@ -4923,8 +4953,9 @@ pub impl Resolver { None => self.session.span_err(expr.span, fmt!("use of undeclared label \ - `%s`", self.session.str_of( - label))), + `%s`", + *self.session.str_of( + label))), Some(dl_def(def @ def_label(_))) => self.record_def(expr.id, def), Some(_) => @@ -4940,7 +4971,7 @@ pub impl Resolver { } } - fn record_candidate_traits_for_expr_if_necessary(expr: @expr) { + fn record_candidate_traits_for_expr_if_necessary(@mut self, expr: @expr) { match expr.node { expr_field(_, ident, _) => { let traits = self.search_for_traits_containing_method(ident); @@ -5017,9 +5048,11 @@ pub impl Resolver { } } - fn search_for_traits_containing_method(name: ident) -> @DVec { + fn search_for_traits_containing_method(@mut self, + name: ident) + -> @DVec { debug!("(searching for traits containing method) looking for '%s'", - self.session.str_of(name)); + *self.session.str_of(name)); let found_traits = @DVec(); let mut search_module = self.current_module; @@ -5107,15 +5140,16 @@ pub impl Resolver { return found_traits; } - fn add_trait_info_if_containing_method(found_traits: @DVec, + fn add_trait_info_if_containing_method(@mut self, + found_traits: @DVec, trait_def_id: def_id, - name: ident) -> bool { - + name: ident) + -> bool { debug!("(adding trait info if containing method) trying trait %d:%d \ for method '%s'", trait_def_id.crate, trait_def_id.node, - self.session.str_of(name)); + *self.session.str_of(name)); match self.trait_info.find(&trait_def_id) { Some(trait_info) if trait_info.contains_key(&name) => { @@ -5123,7 +5157,7 @@ pub impl Resolver { %d:%d for method '%s'", trait_def_id.crate, trait_def_id.node, - self.session.str_of(name)); + *self.session.str_of(name)); (*found_traits).push(trait_def_id); true } @@ -5133,18 +5167,21 @@ pub impl Resolver { } } - fn add_fixed_trait_for_expr(expr_id: node_id, +trait_id: def_id) { + fn add_fixed_trait_for_expr(@mut self, + expr_id: node_id, + +trait_id: def_id) { let traits = @DVec(); traits.push(trait_id); self.trait_map.insert(expr_id, traits); } - fn record_def(node_id: node_id, def: def) { + fn record_def(@mut self, node_id: node_id, def: def) { debug!("(recording def) recording %? for %?", def, node_id); self.def_map.insert(node_id, def); } - fn enforce_default_binding_mode(pat: @pat, + fn enforce_default_binding_mode(@mut self, + pat: @pat, pat_binding_mode: binding_mode, descr: &str) { match pat_binding_mode { @@ -5169,7 +5206,7 @@ pub impl Resolver { // // be sure that there is only one main function // - fn check_duplicate_main() { + fn check_duplicate_main(@mut self) { if self.attr_main_fn.is_none() { if self.main_fns.len() >= 1u { let mut i = 1u; @@ -5195,7 +5232,7 @@ pub impl Resolver { // resolve data structures. // - fn check_for_unused_imports_if_necessary() { + fn check_for_unused_imports_if_necessary(@mut self) { if self.unused_import_lint_level == allow { return; } @@ -5204,7 +5241,8 @@ pub impl Resolver { self.check_for_unused_imports_in_module_subtree(root_module); } - fn check_for_unused_imports_in_module_subtree(module_: @Module) { + fn check_for_unused_imports_in_module_subtree(@mut self, + module_: @mut Module) { // If this isn't a local crate, then bail out. We don't need to check // for unused imports in external crates. @@ -5243,7 +5281,7 @@ pub impl Resolver { } } - fn check_for_unused_imports_in_module(module_: @Module) { + fn check_for_unused_imports_in_module(@mut self, module_: @mut Module) { for module_.import_resolutions.each_value |&import_resolution| { // Ignore dummy spans for things like automatically injected // imports for the prelude, and also don't warn about the same @@ -5280,7 +5318,7 @@ pub impl Resolver { // /// A somewhat inefficient routine to obtain the name of a module. - fn module_to_str(module_: @Module) -> ~str { + fn module_to_str(@mut self, module_: @mut Module) -> ~str { let idents = DVec(); let mut current_module = module_; loop { @@ -5305,12 +5343,12 @@ pub impl Resolver { return self.idents_to_str(vec::reversed(idents.get())); } - fn dump_module(module_: @Module) { + fn dump_module(@mut self, module_: @mut Module) { debug!("Dump of module `%s`:", self.module_to_str(module_)); debug!("Children:"); for module_.children.each_key |&name| { - debug!("* %s", self.session.str_of(name)); + debug!("* %s", *self.session.str_of(name)); } debug!("Import resolutions:"); @@ -5320,7 +5358,7 @@ pub impl Resolver { None => { value_repr = ~""; } Some(_) => { value_repr = ~" value:?"; - // XXX + // FIXME #4954 } } @@ -5329,31 +5367,33 @@ pub impl Resolver { None => { type_repr = ~""; } Some(_) => { type_repr = ~" type:?"; - // XXX + // FIXME #4954 } } - debug!("* %s:%s%s", self.session.str_of(name), + debug!("* %s:%s%s", *self.session.str_of(name), value_repr, type_repr); } } } +pub struct CrateMap { + def_map: DefMap, + exp_map2: ExportMap2, + trait_map: TraitMap +} + /// Entry point to crate resolution. pub fn resolve_crate(session: Session, lang_items: LanguageItems, crate: @crate) - -> { - def_map: DefMap, - exp_map2: ExportMap2, - trait_map: TraitMap - } { - let resolver = @Resolver(session, lang_items, crate); - resolver.resolve(resolver); - return { - def_map: resolver.def_map, - exp_map2: resolver.export_map2, + -> CrateMap { + let resolver = @mut Resolver(session, lang_items, crate); + resolver.resolve(); + CrateMap { + def_map: *resolver.def_map, + exp_map2: *resolver.export_map2, trait_map: resolver.trait_map - }; + } } diff --git a/src/librustc/middle/trans/_match.rs b/src/librustc/middle/trans/_match.rs index 492adc8631dc9..df6073f9339b4 100644 --- a/src/librustc/middle/trans/_match.rs +++ b/src/librustc/middle/trans/_match.rs @@ -189,7 +189,7 @@ pub enum Lit { // range) pub enum Opt { lit(Lit), - var(/* disr val */int, /* variant dids */{enm: def_id, var: def_id}), + var(/* disr val */int, /* variant dids (enm, var) */(def_id, def_id)), range(@ast::expr, @ast::expr), vec_len_eq(uint), vec_len_ge(uint) @@ -287,7 +287,7 @@ pub fn variant_opt(tcx: ty::ctxt, pat_id: ast::node_id) -> Opt { let variants = ty::enum_variants(tcx, enum_id); for vec::each(*variants) |v| { if var_id == v.id { - return var(v.disr_val, {enm: enum_id, var: var_id}); + return var(v.disr_val, (enum_id, var_id)); } } ::core::util::unreachable(); @@ -372,9 +372,10 @@ pub fn expand_nested_bindings(bcx: block, m: &[@Match/&r], match br.pats[col].node { ast::pat_ident(_, path, Some(inner)) => { let pats = vec::append( - vec::slice(br.pats, 0u, col), + vec::slice(br.pats, 0u, col).to_vec(), vec::append(~[inner], - vec::view(br.pats, col + 1u, br.pats.len()))); + vec::slice(br.pats, col + 1u, + br.pats.len()))); let binding_info = br.data.bindings_map.get(&path_to_ident(path)); @@ -416,8 +417,8 @@ pub fn enter_match(bcx: block, dm: DefMap, m: &[@Match/&r], Some(sub) => { let pats = vec::append( - vec::append(sub, vec::view(br.pats, 0u, col)), - vec::view(br.pats, col + 1u, br.pats.len())); + vec::append(sub, vec::slice(br.pats, 0u, col)), + vec::slice(br.pats, col + 1u, br.pats.len())); let self = br.pats[col]; match self.node { @@ -559,7 +560,7 @@ pub fn enter_opt(bcx: block, m: &[@Match/&r], opt: &Opt, col: uint, Some(fp) => reordered_patterns.push(fp.pat) } } - Some(dvec::unwrap(move reordered_patterns)) + Some(dvec::unwrap(reordered_patterns)) } else { None } @@ -759,7 +760,7 @@ pub fn enter_region(bcx: block, // Returns the options in one column of matches. An option is something that // needs to be conditionally matched at runtime; for example, the discriminant // on a set of enum variants or a literal. -pub fn get_options(ccx: @crate_ctxt, m: &[@Match], col: uint) -> ~[Opt] { +pub fn get_options(ccx: @CrateContext, m: &[@Match], col: uint) -> ~[Opt] { fn add_to_set(tcx: ty::ctxt, set: &DVec, val: Opt) { if set.any(|l| opt_eq(tcx, l, &val)) {return;} set.push(val); @@ -815,39 +816,46 @@ pub fn get_options(ccx: @crate_ctxt, m: &[@Match], col: uint) -> ~[Opt] { _ => {} } } - return dvec::unwrap(move found); + return dvec::unwrap(found); +} + +pub struct ExtractedBlock { + vals: ~[ValueRef], + bcx: block } pub fn extract_variant_args(bcx: block, pat_id: ast::node_id, - vdefs: {enm: def_id, var: def_id}, + vdefs: (def_id, def_id), val: ValueRef) - -> {vals: ~[ValueRef], bcx: block} { + -> ExtractedBlock { + let (enm, evar) = vdefs; let _icx = bcx.insn_ctxt("match::extract_variant_args"); - let ccx = bcx.fcx.ccx; + let ccx = *bcx.fcx.ccx; let enum_ty_substs = match ty::get(node_id_type(bcx, pat_id)).sty { ty::ty_enum(id, ref substs) => { - assert id == vdefs.enm; + assert id == enm; /*bad*/copy (*substs).tps } _ => bcx.sess().bug(~"extract_variant_args: pattern has non-enum type") }; let mut blobptr = val; - let variants = ty::enum_variants(ccx.tcx, vdefs.enm); - let size = ty::enum_variant_with_id(ccx.tcx, vdefs.enm, - vdefs.var).args.len(); + let variants = ty::enum_variants(ccx.tcx, enm); + let size = ty::enum_variant_with_id(ccx.tcx, enm, + evar).args.len(); if size > 0u && (*variants).len() != 1u { let enumptr = PointerCast(bcx, val, T_opaque_enum_ptr(ccx)); blobptr = GEPi(bcx, enumptr, [0u, 1u]); } - let vdefs_tg = vdefs.enm; - let vdefs_var = vdefs.var; + let vdefs_tg = enm; + let vdefs_var = evar; let args = do vec::from_fn(size) |i| { GEP_enum(bcx, blobptr, vdefs_tg, vdefs_var, /*bad*/copy enum_ty_substs, i) }; - return {vals: args, bcx: bcx}; + + ExtractedBlock { vals: args, bcx: bcx } } pub fn extract_vec_elems(bcx: block, @@ -855,7 +863,7 @@ pub fn extract_vec_elems(bcx: block, elem_count: uint, tail: bool, val: ValueRef) - -> {vals: ~[ValueRef], bcx: block} { + -> ExtractedBlock { let _icx = bcx.insn_ctxt("match::extract_vec_elems"); let vt = tvec::vec_types(bcx, node_id_type(bcx, pat_id)); let unboxed = load_if_immediate(bcx, val, vt.vec_ty); @@ -884,7 +892,8 @@ pub fn extract_vec_elems(bcx: block, elems.push(scratch.val); scratch.add_clean(bcx); } - return {vals: elems, bcx: bcx}; + + ExtractedBlock { vals: elems, bcx: bcx } } // NB: This function does not collect fields from struct-like enum variants. @@ -1242,7 +1251,7 @@ pub fn compile_submatch(bcx: block, match data.arm.guard { Some(guard_expr) => { bcx = compile_guard(bcx, guard_expr, m[0].data, - vec::view(m, 1, m.len()), + vec::slice(m, 1, m.len()), vals, chk); } _ => () @@ -1261,9 +1270,9 @@ pub fn compile_submatch(bcx: block, } }; - let vals_left = vec::append(vec::slice(vals, 0u, col), - vec::view(vals, col + 1u, vals.len())); - let ccx = bcx.fcx.ccx; + let vals_left = vec::append(vec::slice(vals, 0u, col).to_vec(), + vec::slice(vals, col + 1u, vals.len())); + let ccx = *bcx.fcx.ccx; let mut pat_id = 0; for vec::each(m) |br| { // Find a real id (we're adding placeholder wildcard patterns, but @@ -1359,14 +1368,30 @@ pub fn compile_submatch(bcx: block, let mut test_val = val; if opts.len() > 0u { match opts[0] { - var(_, vdef) => { - if (*ty::enum_variants(tcx, vdef.enm)).len() == 1u { + var(_, (enm, _)) => { + let variants = ty::enum_variants(tcx, enm); + if variants.len() == 1 { kind = single; } else { let enumptr = PointerCast(bcx, val, T_opaque_enum_ptr(ccx)); let discrimptr = GEPi(bcx, enumptr, [0u, 0u]); - test_val = Load(bcx, discrimptr); + + + assert variants.len() > 1; + let min_discrim = do variants.foldr(0) |&x, y| { + int::min(x.disr_val, y) + }; + let max_discrim = do variants.foldr(0) |&x, y| { + int::max(x.disr_val, y) + }; + + test_val = LoadRangeAssert(bcx, discrimptr, + min_discrim as c_ulonglong, + (max_discrim + 1) + as c_ulonglong, + lib::llvm::True); + kind = switch; } } @@ -1628,7 +1653,7 @@ pub fn trans_match_inner(scope_cx: block, // Special case for empty types let fail_cx = @mut None; let f: mk_fail = || mk_fail(scope_cx, discr_expr.span, - ~"scrutinizing value that can't exist", fail_cx); + @~"scrutinizing value that can't exist", fail_cx); Some(f) } else { None @@ -1657,10 +1682,10 @@ pub fn trans_match_inner(scope_cx: block, arm_cxs.push(bcx); } - bcx = controlflow::join_blocks(scope_cx, dvec::unwrap(move arm_cxs)); + bcx = controlflow::join_blocks(scope_cx, dvec::unwrap(arm_cxs)); return bcx; - fn mk_fail(bcx: block, sp: span, +msg: ~str, + fn mk_fail(bcx: block, sp: span, msg: @~str, finished: @mut Option) -> BasicBlockRef { match *finished { Some(bb) => return bb, _ => () } let fail_cx = sub_block(bcx, ~"case_fallthrough"); @@ -1685,7 +1710,7 @@ pub fn bind_irrefutable_pat(bcx: block, binding_mode: IrrefutablePatternBindingMode) -> block { let _icx = bcx.insn_ctxt("match::bind_irrefutable_pat"); - let ccx = bcx.fcx.ccx; + let ccx = *bcx.fcx.ccx; let mut bcx = bcx; // Necessary since bind_irrefutable_pat is called outside trans_match diff --git a/src/librustc/middle/trans/base.rs b/src/librustc/middle/trans/base.rs index 8d6d299c92f89..f5fa83e3fff3f 100644 --- a/src/librustc/middle/trans/base.rs +++ b/src/librustc/middle/trans/base.rs @@ -37,7 +37,7 @@ use lib::llvm::{ModuleRef, ValueRef, TypeRef, BasicBlockRef}; use lib::llvm::{True, False}; use lib::llvm::{llvm, mk_target_data, mk_type_names}; use lib; -use metadata::common::link_meta; +use metadata::common::LinkMeta; use metadata::{csearch, cstore, decoder, encoder}; use middle::astencode; use middle::borrowck::RootInfo; @@ -90,7 +90,7 @@ use syntax::visit::vt; use syntax::{ast, ast_util, codemap, ast_map}; pub struct icx_popper { - ccx: @crate_ctxt, + ccx: @CrateContext, drop { if self.ccx.sess.count_llvm_insns() { self.ccx.stats.llvm_insn_ctxt.pop(); @@ -98,43 +98,43 @@ pub struct icx_popper { } } -pub fn icx_popper(ccx: @crate_ctxt) -> icx_popper { +pub fn icx_popper(ccx: @CrateContext) -> icx_popper { icx_popper { ccx: ccx } } pub trait get_insn_ctxt { - fn insn_ctxt(s: &str) -> icx_popper; + fn insn_ctxt(&self, s: &str) -> icx_popper; } -pub impl @crate_ctxt: get_insn_ctxt { - fn insn_ctxt(s: &str) -> icx_popper { +pub impl get_insn_ctxt for @CrateContext { + fn insn_ctxt(&self, s: &str) -> icx_popper { debug!("new insn_ctxt: %s", s); if self.sess.count_llvm_insns() { self.stats.llvm_insn_ctxt.push(str::from_slice(s)); } - icx_popper(self) + icx_popper(*self) } } -pub impl block: get_insn_ctxt { - fn insn_ctxt(s: &str) -> icx_popper { +pub impl get_insn_ctxt for block { + fn insn_ctxt(&self, s: &str) -> icx_popper { self.ccx().insn_ctxt(s) } } -pub impl fn_ctxt: get_insn_ctxt { - fn insn_ctxt(s: &str) -> icx_popper { +pub impl get_insn_ctxt for fn_ctxt { + fn insn_ctxt(&self, s: &str) -> icx_popper { self.ccx.insn_ctxt(s) } } -pub fn log_fn_time(ccx: @crate_ctxt, +name: ~str, start: time::Timespec, +pub fn log_fn_time(ccx: @CrateContext, +name: ~str, start: time::Timespec, end: time::Timespec) { let elapsed = 1000 * ((end.sec - start.sec) as int) + ((end.nsec as int) - (start.nsec as int)) / 1000000; - ccx.stats.fn_times.push({ident: name, time: elapsed}); + ccx.stats.fn_times.push((name, elapsed)); } pub fn decl_fn(llmod: ModuleRef, name: &str, cc: lib::llvm::CallConv, @@ -286,7 +286,7 @@ pub fn malloc_raw_dyn(bcx: block, let ccx = bcx.ccx(); let (mk_fn, langcall) = match heap { - heap_shared => { + heap_managed | heap_managed_unique => { (ty::mk_imm_box, bcx.tcx().lang_items.malloc_fn()) } heap_exchange => { @@ -310,7 +310,9 @@ pub fn malloc_raw_dyn(bcx: block, langcall, ~[tydesc, size], expr::SaveIn(rval)); - return rslt(bcx, PointerCast(bcx, Load(bcx, rval), llty)); + let r = rslt(bcx, PointerCast(bcx, Load(bcx, rval), llty)); + maybe_set_managed_unique_rc(r.bcx, r.val, heap); + r } /** @@ -339,38 +341,65 @@ pub fn malloc_raw(bcx: block, t: ty::t, heap: heap) -> Result { malloc_raw_dyn(bcx, t, heap, llsize_of(bcx.ccx(), type_of(bcx.ccx(), t))) } +pub struct MallocResult { + bcx: block, + box: ValueRef, + body: ValueRef +} + // malloc_general_dyn: usefully wraps malloc_raw_dyn; allocates a box, // and pulls out the body pub fn malloc_general_dyn(bcx: block, t: ty::t, heap: heap, size: ValueRef) - -> {bcx: block, box: ValueRef, body: ValueRef} { + -> MallocResult { let _icx = bcx.insn_ctxt("malloc_general"); let Result {bcx: bcx, val: llbox} = malloc_raw_dyn(bcx, t, heap, size); let non_gc_box = non_gc_box_cast(bcx, llbox); let body = GEPi(bcx, non_gc_box, [0u, abi::box_field_body]); - return {bcx: bcx, box: llbox, body: body}; + + MallocResult { bcx: bcx, box: llbox, body: body } } pub fn malloc_general(bcx: block, t: ty::t, heap: heap) - -> {bcx: block, box: ValueRef, body: ValueRef} { + -> MallocResult { malloc_general_dyn(bcx, t, heap, llsize_of(bcx.ccx(), type_of(bcx.ccx(), t))) } pub fn malloc_boxed(bcx: block, t: ty::t) - -> {bcx: block, box: ValueRef, body: ValueRef} { - malloc_general(bcx, t, heap_shared) + -> MallocResult { + malloc_general(bcx, t, heap_managed) +} + +pub fn heap_for_unique(bcx: block, t: ty::t) -> heap { + if ty::type_contents(bcx.tcx(), t).contains_managed() { + heap_managed_unique + } else { + heap_exchange + } +} + +pub fn maybe_set_managed_unique_rc(bcx: block, bx: ValueRef, heap: heap) { + if heap == heap_managed_unique { + // In cases where we are looking at a unique-typed allocation in the + // managed heap (thus have refcount 1 from the managed allocator), + // such as a ~(@foo) or such. These need to have their refcount forced + // to -2 so the annihilator ignores them. + let rc = GEPi(bcx, bx, [0u, abi::box_field_refcnt]); + Store(bcx, C_int(bcx.ccx(), -2), rc); + } } + pub fn malloc_unique(bcx: block, t: ty::t) - -> {bcx: block, box: ValueRef, body: ValueRef} { - malloc_general(bcx, t, heap_exchange) + -> MallocResult { + malloc_general(bcx, t, heap_for_unique(bcx, t)) } // Type descriptor and type glue stuff -pub fn get_tydesc_simple(ccx: @crate_ctxt, t: ty::t) -> ValueRef { +pub fn get_tydesc_simple(ccx: @CrateContext, t: ty::t) -> ValueRef { get_tydesc(ccx, t).tydesc } -pub fn get_tydesc(ccx: @crate_ctxt, t: ty::t) -> @mut tydesc_info { +pub fn get_tydesc(ccx: @CrateContext, t: ty::t) -> @mut tydesc_info { match ccx.tydescs.find(&t) { Some(inf) => inf, _ => { @@ -455,8 +484,7 @@ pub fn set_glue_inlining(f: ValueRef, t: ty::t) { // Double-check that we never ask LLVM to declare the same symbol twice. It // silently mangles such symbols, breaking our linkage model. -pub fn note_unique_llvm_symbol(ccx: @crate_ctxt, +sym: ~str) { - // XXX: Bad copy. +pub fn note_unique_llvm_symbol(ccx: @CrateContext, +sym: ~str) { if ccx.all_llvm_symbols.contains_key(&sym) { ccx.sess.bug(~"duplicate LLVM symbol: " + sym); } @@ -464,7 +492,7 @@ pub fn note_unique_llvm_symbol(ccx: @crate_ctxt, +sym: ~str) { } -pub fn get_res_dtor(ccx: @crate_ctxt, did: ast::def_id, +pub fn get_res_dtor(ccx: @CrateContext, did: ast::def_id, parent_id: ast::def_id, substs: ~[ty::t]) -> ValueRef { let _icx = ccx.insn_ctxt("trans_res_dtor"); @@ -473,7 +501,10 @@ pub fn get_res_dtor(ccx: @crate_ctxt, did: ast::def_id, inline::maybe_instantiate_inline(ccx, did, true) } else { did }; assert did.crate == ast::local_crate; - monomorphize::monomorphic_fn(ccx, did, substs, None, None, None).val + let (val, _) = + monomorphize::monomorphic_fn(ccx, did, substs, None, None, None); + + val } else if did.crate == ast::local_crate { get_item_val(ccx, did.node) } else { @@ -489,7 +520,7 @@ pub fn get_res_dtor(ccx: @crate_ctxt, did: ast::def_id, } // Structural comparison: a rather involved form of glue. -pub fn maybe_name_value(cx: @crate_ctxt, v: ValueRef, s: ~str) { +pub fn maybe_name_value(cx: @CrateContext, v: ValueRef, s: ~str) { if cx.sess.opts.save_temps { let _: () = str::as_c_str(s, |buf| { unsafe { @@ -522,7 +553,7 @@ pub fn compare_scalar_types(cx: block, rslt( controlflow::trans_fail( cx, None, - ~"attempt to compare values of type type"), + @~"attempt to compare values of type type"), C_nil()) } _ => { @@ -628,7 +659,10 @@ pub fn iter_structural_ty(cx: block, av: ValueRef, t: ty::t, for vec::each(fn_ty.sig.inputs) |a| { let llfldp_a = GEP_enum(cx, a_tup, tid, v_id, /*bad*/copy tps, j); - // XXX: Is "None" right here? + // This assumes the self type is absent (it passes + // None for the self_ty_opt arg of substs_tps). + // I think that's ok since you can't have an enum + // inside a trait. let ty_subst = ty::subst_tps(ccx.tcx, tps, None, a.ty); cx = f(cx, llfldp_a, ty_subst); j += 1u; @@ -637,7 +671,7 @@ pub fn iter_structural_ty(cx: block, av: ValueRef, t: ty::t, _ => cx.tcx().sess.bug(fmt!("iter_variant: not a function type: \ %s (variant name = %s)", cx.ty_to_str(fn_ty), - cx.sess().str_of(variant.name))) + *cx.sess().str_of(variant.name))) } return cx; } @@ -774,7 +808,7 @@ pub fn fail_if_zero(cx: block, span: span, divmod: ast::binop, } }; do with_cond(cx, is_zero) |bcx| { - controlflow::trans_fail(bcx, Some(span), /*bad*/copy text) + controlflow::trans_fail(bcx, Some(span), @/*bad*/copy text) } } @@ -782,7 +816,7 @@ pub fn null_env_ptr(bcx: block) -> ValueRef { C_null(T_opaque_box_ptr(bcx.ccx())) } -pub fn trans_external_path(ccx: @crate_ctxt, did: ast::def_id, t: ty::t) +pub fn trans_external_path(ccx: @CrateContext, did: ast::def_id, t: ty::t) -> ValueRef { let name = csearch::get_symbol(ccx.sess.cstore, did).to_managed(); // Sad match ty::get(t).sty { @@ -798,7 +832,7 @@ pub fn trans_external_path(ccx: @crate_ctxt, did: ast::def_id, t: ty::t) }; } -pub fn get_discrim_val(cx: @crate_ctxt, span: span, enum_did: ast::def_id, +pub fn get_discrim_val(cx: @CrateContext, span: span, enum_did: ast::def_id, variant_did: ast::def_id) -> ValueRef { // Can't use `discrims` from the crate context here because // those discriminants have an extra level of indirection, @@ -854,8 +888,8 @@ pub fn need_invoke(bcx: block) -> bool { // Walk the scopes to look for cleanups let mut cur = bcx; loop { - match cur.kind { - block_scope(ref inf) => { + match *cur.kind { + block_scope(ref mut inf) => { for vec::each((*inf).cleanups) |cleanup| { match *cleanup { clean(_, cleanup_type) | clean_temp(_, _, cleanup_type) => { @@ -886,16 +920,21 @@ pub fn have_cached_lpad(bcx: block) -> bool { return res; } -pub fn in_lpad_scope_cx(bcx: block, f: fn(scope_info)) { +pub fn in_lpad_scope_cx(bcx: block, f: fn(&mut scope_info)) { let mut bcx = bcx; loop { - match bcx.kind { - block_scope(ref inf) => { - if (*inf).cleanups.len() > 0u || bcx.parent.is_none() { - f((*inf)); return; + { + // XXX: Borrow check bug workaround. + let kind: &mut block_kind = &mut *bcx.kind; + match *kind { + block_scope(ref mut inf) => { + if inf.cleanups.len() > 0u || bcx.parent.is_none() { + f(inf); + return; + } + } + _ => () } - } - _ => () } bcx = block_parent(bcx); } @@ -988,7 +1027,7 @@ pub fn add_root_cleanup(bcx: block, let mut bcx_sid = bcx; loop { bcx_sid = match bcx_sid.node_info { - Some({id, _}) if id == scope_id => { + Some(NodeInfo { id, _ }) if id == scope_id => { return bcx_sid } _ => { @@ -1035,22 +1074,19 @@ pub fn load_if_immediate(cx: block, v: ValueRef, t: ty::t) -> ValueRef { return v; } -pub fn trans_trace(bcx: block, sp_opt: Option, +trace_str: ~str) { +pub fn trans_trace(bcx: block, sp_opt: Option, trace_str: @~str) { if !bcx.sess().trace() { return; } let _icx = bcx.insn_ctxt("trans_trace"); - // XXX: Bad copy. - add_comment(bcx, copy trace_str); + add_comment(bcx, *trace_str); let V_trace_str = C_cstr(bcx.ccx(), trace_str); - let {V_filename, V_line} = match sp_opt { + let (V_filename, V_line) = match sp_opt { Some(sp) => { let sess = bcx.sess(); let loc = sess.parse_sess.cm.lookup_char_pos(sp.lo); - {V_filename: C_cstr(bcx.ccx(), /*bad*/copy loc.file.name), - V_line: loc.line as int} + (C_cstr(bcx.ccx(), @/*bad*/copy loc.file.name), loc.line as int) } None => { - {V_filename: C_cstr(bcx.ccx(), ~""), - V_line: 0} + (C_cstr(bcx.ccx(), @~""), 0) } }; let ccx = bcx.ccx(); @@ -1148,7 +1184,7 @@ pub fn trans_stmt(cx: block, s: ast::stmt) -> block { } } } - ast::decl_item(i) => trans_item(cx.fcx.ccx, *i) + ast::decl_item(i) => trans_item(*cx.fcx.ccx, *i) } } ast::stmt_mac(*) => cx.tcx().sess.bug(~"unexpanded macro") @@ -1160,7 +1196,7 @@ pub fn trans_stmt(cx: block, s: ast::stmt) -> block { // You probably don't want to use this one. See the // next three functions instead. pub fn new_block(cx: fn_ctxt, parent: Option, +kind: block_kind, - is_lpad: bool, +name: ~str, opt_node_info: Option) + is_lpad: bool, +name: ~str, opt_node_info: Option) -> block { let s = if cx.ccx.sess.opts.save_temps || cx.ccx.sess.opts.debuginfo { @@ -1169,12 +1205,12 @@ pub fn new_block(cx: fn_ctxt, parent: Option, +kind: block_kind, special_idents::invalid }; unsafe { - let llbb: BasicBlockRef = str::as_c_str(cx.ccx.sess.str_of(s), |buf| { + let llbb = str::as_c_str(*cx.ccx.sess.str_of(s), |buf| { llvm::LLVMAppendBasicBlock(cx.llfn, buf) }); let bcx = mk_block(llbb, parent, - move kind, + kind, is_lpad, opt_node_info, cx); @@ -1189,21 +1225,21 @@ pub fn simple_block_scope() -> block_kind { block_scope(scope_info { loop_break: None, loop_label: None, - mut cleanups: ~[], - mut cleanup_paths: ~[], - mut landing_pad: None + cleanups: ~[], + cleanup_paths: ~[], + landing_pad: None }) } // Use this when you're at the top block of a function or the like. -pub fn top_scope_block(fcx: fn_ctxt, opt_node_info: Option) +pub fn top_scope_block(fcx: fn_ctxt, opt_node_info: Option) -> block { return new_block(fcx, None, simple_block_scope(), false, ~"function top level", opt_node_info); } pub fn scope_block(bcx: block, - opt_node_info: Option, + opt_node_info: Option, +n: ~str) -> block { return new_block(bcx.fcx, Some(bcx), simple_block_scope(), bcx.is_lpad, n, opt_node_info); @@ -1213,13 +1249,13 @@ pub fn loop_scope_block(bcx: block, loop_break: block, loop_label: Option, +n: ~str, - opt_node_info: Option) -> block { + opt_node_info: Option) -> block { return new_block(bcx.fcx, Some(bcx), block_scope(scope_info { loop_break: Some(loop_break), loop_label: loop_label, - mut cleanups: ~[], - mut cleanup_paths: ~[], - mut landing_pad: None + cleanups: ~[], + cleanup_paths: ~[], + landing_pad: None }), bcx.is_lpad, n, opt_node_info); } @@ -1289,23 +1325,33 @@ pub fn cleanup_and_leave(bcx: block, if bcx.sess().trace() { trans_trace( bcx, None, - fmt!("cleanup_and_leave(%s)", cur.to_str())); + @fmt!("cleanup_and_leave(%s)", cur.to_str())); } - match cur.kind { - block_scope(ref inf) if (*inf).cleanups.len() > 0u => { - for vec::find((*inf).cleanup_paths, - |cp| cp.target == leave).each |cp| { - Br(bcx, cp.dest); - return; + { + // XXX: Borrow check bug workaround. + let kind: &mut block_kind = &mut *cur.kind; + match *kind { + block_scope(ref mut inf) if !inf.cleanups.is_empty() => { + for vec::find((*inf).cleanup_paths, + |cp| cp.target == leave).each |cp| { + Br(bcx, cp.dest); + return; + } + let sub_cx = sub_block(bcx, ~"cleanup"); + Br(bcx, sub_cx.llbb); + inf.cleanup_paths.push(cleanup_path { + target: leave, + dest: sub_cx.llbb + }); + bcx = trans_block_cleanups_(sub_cx, + block_cleanups(cur), + is_lpad); + } + _ => () } - let sub_cx = sub_block(bcx, ~"cleanup"); - Br(bcx, sub_cx.llbb); - (*inf).cleanup_paths.push({target: leave, dest: sub_cx.llbb}); - bcx = trans_block_cleanups_(sub_cx, block_cleanups(cur), is_lpad); - } - _ => () } + match upto { Some(bb) => { if cur.llbb == bb { break; } } _ => () @@ -1335,7 +1381,7 @@ pub fn leave_block(bcx: block, out_of: block) -> block { } pub fn with_scope(bcx: block, - opt_node_info: Option, + opt_node_info: Option, +name: ~str, f: fn(block) -> block) -> block { let _icx = bcx.insn_ctxt("with_scope"); @@ -1350,7 +1396,7 @@ pub fn with_scope(bcx: block, } pub fn with_scope_result(bcx: block, - opt_node_info: Option, + opt_node_info: Option, +name: ~str, f: fn(block) -> Result) -> Result { let _icx = bcx.insn_ctxt("with_scope_result"); @@ -1360,7 +1406,7 @@ pub fn with_scope_result(bcx: block, rslt(leave_block(bcx, scope_cx), val) } -pub fn with_scope_datumblock(bcx: block, opt_node_info: Option, +pub fn with_scope_datumblock(bcx: block, opt_node_info: Option, +name: ~str, f: fn(block) -> datum::DatumBlock) -> datum::DatumBlock { use middle::trans::datum::DatumBlock; @@ -1400,7 +1446,7 @@ pub fn alloc_local(cx: block, local: @ast::local) -> block { let val = alloc_ty(cx, t); if cx.sess().opts.debuginfo { do option::iter(&simple_name) |name| { - str::as_c_str(cx.ccx().sess.str_of(*name), |buf| { + str::as_c_str(*cx.ccx().sess.str_of(*name), |buf| { unsafe { llvm::LLVMSetValueName(val, buf) } @@ -1528,14 +1574,20 @@ pub fn arrayalloca(cx: block, t: TypeRef, v: ValueRef) -> ValueRef { base::raw_block(cx.fcx, false, cx.fcx.llstaticallocas), t, v); } +pub struct BasicBlocks { + sa: BasicBlockRef, + rt: BasicBlockRef +} + // Creates the standard set of basic blocks for a function -pub fn mk_standard_basic_blocks(llfn: ValueRef) -> - {sa: BasicBlockRef, rt: BasicBlockRef} { +pub fn mk_standard_basic_blocks(llfn: ValueRef) -> BasicBlocks { unsafe { - {sa: str::as_c_str(~"static_allocas", + BasicBlocks { + sa: str::as_c_str(~"static_allocas", |buf| llvm::LLVMAppendBasicBlock(llfn, buf)), - rt: str::as_c_str(~"return", - |buf| llvm::LLVMAppendBasicBlock(llfn, buf))} + rt: str::as_c_str(~"return", + |buf| llvm::LLVMAppendBasicBlock(llfn, buf)) + } } } @@ -1546,37 +1598,37 @@ pub fn mk_standard_basic_blocks(llfn: ValueRef) -> // - create_llargs_for_fn_args. // - new_fn_ctxt // - trans_args -pub fn new_fn_ctxt_w_id(ccx: @crate_ctxt, +pub fn new_fn_ctxt_w_id(ccx: @CrateContext, +path: path, llfndecl: ValueRef, id: ast::node_id, impl_id: Option, - +param_substs: Option, + param_substs: Option<@param_substs>, sp: Option) -> fn_ctxt { let llbbs = mk_standard_basic_blocks(llfndecl); - return @fn_ctxt_ { + return @mut fn_ctxt_ { llfn: llfndecl, llenv: unsafe { llvm::LLVMGetParam(llfndecl, 1u as c_uint) }, llretptr: unsafe { llvm::LLVMGetParam(llfndecl, 0u as c_uint) }, - mut llstaticallocas: llbbs.sa, - mut llloadenv: None, - mut llreturn: llbbs.rt, - mut llself: None, - mut personality: None, - mut loop_ret: None, - llargs: HashMap(), - lllocals: HashMap(), - llupvars: HashMap(), + llstaticallocas: llbbs.sa, + llloadenv: None, + llreturn: llbbs.rt, + llself: None, + personality: None, + loop_ret: None, + llargs: @HashMap(), + lllocals: @HashMap(), + llupvars: @HashMap(), id: id, impl_id: impl_id, param_substs: param_substs, span: sp, path: path, - ccx: ccx + ccx: @ccx }; } -pub fn new_fn_ctxt(ccx: @crate_ctxt, +pub fn new_fn_ctxt(ccx: @CrateContext, +path: path, llfndecl: ValueRef, sp: Option) @@ -1734,13 +1786,13 @@ pub enum self_arg { impl_self(ty::t), impl_owned_self(ty::t), no_self, } // trans_closure: Builds an LLVM function out of a source function. // If the function closes over its environment a closure will be // returned. -pub fn trans_closure(ccx: @crate_ctxt, +pub fn trans_closure(ccx: @CrateContext, +path: path, decl: &ast::fn_decl, body: &ast::blk, llfndecl: ValueRef, ty_self: self_arg, - +param_substs: Option, + param_substs: Option<@param_substs>, id: ast::node_id, impl_id: Option, maybe_load_env: fn(fn_ctxt), @@ -1762,7 +1814,7 @@ pub fn trans_closure(ccx: @crate_ctxt, llvm::LLVMSetGC(fcx.llfn, strategy); } } - ccx.uses_gc = true; + *ccx.uses_gc = true; } // Create the first basic block in the function and keep a handle on it to @@ -1798,13 +1850,13 @@ pub fn trans_closure(ccx: @crate_ctxt, // trans_fn: creates an LLVM function corresponding to a source language // function. -pub fn trans_fn(ccx: @crate_ctxt, +pub fn trans_fn(ccx: @CrateContext, +path: path, decl: &ast::fn_decl, body: &ast::blk, llfndecl: ValueRef, ty_self: self_arg, - +param_substs: Option, + param_substs: Option<@param_substs>, id: ast::node_id, impl_id: Option) { let do_time = ccx.sess.trans_stats(); @@ -1813,8 +1865,8 @@ pub fn trans_fn(ccx: @crate_ctxt, debug!("trans_fn(ty_self=%?)", ty_self); let _icx = ccx.insn_ctxt("trans_fn"); ccx.stats.n_fns += 1; - // XXX: Bad copy of `path`. - trans_closure(ccx, copy path, decl, body, llfndecl, ty_self, + let the_path_str = path_str(ccx.sess, path); + trans_closure(ccx, path, decl, body, llfndecl, ty_self, param_substs, id, impl_id, |fcx| { if ccx.sess.opts.extra_debuginfo { @@ -1824,17 +1876,17 @@ pub fn trans_fn(ccx: @crate_ctxt, |_bcx| { }); if do_time { let end = time::get_time(); - log_fn_time(ccx, path_str(ccx.sess, path), start, end); + log_fn_time(ccx, the_path_str, start, end); } } -pub fn trans_enum_variant(ccx: @crate_ctxt, +pub fn trans_enum_variant(ccx: @CrateContext, enum_id: ast::node_id, variant: ast::variant, args: ~[ast::variant_arg], disr: int, is_degen: bool, - +param_substs: Option, + param_substs: Option<@param_substs>, llfndecl: ValueRef) { let _icx = ccx.insn_ctxt("trans_enum_variant"); // Translate variant arguments to function arguments. @@ -1850,9 +1902,8 @@ pub fn trans_enum_variant(ccx: @crate_ctxt, id: varg.id, } }; - // XXX: Bad copy of `param_substs`. let fcx = new_fn_ctxt_w_id(ccx, ~[], llfndecl, variant.node.id, None, - copy param_substs, None); + param_substs, None); // XXX: Bad copy. let raw_llargs = create_llargs_for_fn_args(fcx, no_self, copy fn_args); let ty_param_substs = match param_substs { @@ -1894,10 +1945,10 @@ pub fn trans_enum_variant(ccx: @crate_ctxt, // NB: In theory this should be merged with the function above. But the AST // structures are completely different, so very little code would be shared. -pub fn trans_tuple_struct(ccx: @crate_ctxt, +pub fn trans_tuple_struct(ccx: @CrateContext, fields: ~[@ast::struct_field], ctor_id: ast::node_id, - +param_substs: Option, + param_substs: Option<@param_substs>, llfndecl: ValueRef) { let _icx = ccx.insn_ctxt("trans_tuple_struct"); @@ -1947,11 +1998,11 @@ pub fn trans_tuple_struct(ccx: @crate_ctxt, finish_fn(fcx, lltop); } -pub fn trans_struct_dtor(ccx: @crate_ctxt, +pub fn trans_struct_dtor(ccx: @CrateContext, +path: path, body: &ast::blk, dtor_id: ast::node_id, - +psubsts: Option, + psubsts: Option<@param_substs>, hash_id: Option, parent_id: ast::def_id) -> ValueRef { @@ -1968,7 +2019,7 @@ pub fn trans_struct_dtor(ccx: @crate_ctxt, let lldty = type_of_dtor(ccx, class_ty); // XXX: Bad copies. - let s = get_dtor_symbol(ccx, copy path, dtor_id, copy psubsts); + let s = get_dtor_symbol(ccx, copy path, dtor_id, psubsts); /* Register the dtor as a function. It has external linkage */ let lldecl = decl_internal_cdecl_fn(ccx.llmod, s, lldty); @@ -1986,7 +2037,7 @@ pub fn trans_struct_dtor(ccx: @crate_ctxt, lldecl } -pub fn trans_enum_def(ccx: @crate_ctxt, enum_definition: ast::enum_def, +pub fn trans_enum_def(ccx: @CrateContext, enum_definition: ast::enum_def, id: ast::node_id, degen: bool, path: @ast_map::path, vi: @~[ty::VariantInfo], i: &mut uint) { @@ -2020,7 +2071,7 @@ pub fn trans_enum_def(ccx: @crate_ctxt, enum_definition: ast::enum_def, } } -pub fn trans_item(ccx: @crate_ctxt, item: ast::item) { +pub fn trans_item(ccx: @CrateContext, item: ast::item) { let _icx = ccx.insn_ctxt("trans_item"); let path = match ccx.tcx.items.get(&item.id) { ast_map::node_item(_, p) => p, @@ -2087,7 +2138,7 @@ pub fn trans_item(ccx: @crate_ctxt, item: ast::item) { } } -pub fn trans_struct_def(ccx: @crate_ctxt, struct_def: @ast::struct_def, +pub fn trans_struct_def(ccx: @CrateContext, struct_def: @ast::struct_def, path: @ast_map::path, id: ast::node_id) { // Translate the destructor. @@ -2114,7 +2165,7 @@ pub fn trans_struct_def(ccx: @crate_ctxt, struct_def: @ast::struct_def, // separate modules in the compiled program. That's because modules exist // only as a convenience for humans working with the code, to organize names // and control visibility. -pub fn trans_mod(ccx: @crate_ctxt, m: ast::_mod) { +pub fn trans_mod(ccx: @CrateContext, m: ast::_mod) { let _icx = ccx.insn_ctxt("trans_mod"); for vec::each(m.items) |item| { trans_item(ccx, **item); @@ -2126,7 +2177,7 @@ pub fn get_pair_fn_ty(llpairty: TypeRef) -> TypeRef { return struct_elt(llpairty, 0u); } -pub fn register_fn(ccx: @crate_ctxt, +pub fn register_fn(ccx: @CrateContext, sp: span, +path: path, node_id: ast::node_id, @@ -2136,7 +2187,7 @@ pub fn register_fn(ccx: @crate_ctxt, register_fn_full(ccx, sp, path, node_id, attrs, t) } -pub fn register_fn_full(ccx: @crate_ctxt, +pub fn register_fn_full(ccx: @CrateContext, sp: span, +path: path, node_id: ast::node_id, @@ -2148,7 +2199,7 @@ pub fn register_fn_full(ccx: @crate_ctxt, lib::llvm::CCallConv, llfty) } -pub fn register_fn_fuller(ccx: @crate_ctxt, +pub fn register_fn_fuller(ccx: @CrateContext, sp: span, +path: path, node_id: ast::node_id, @@ -2189,12 +2240,13 @@ pub fn is_main_fn(sess: &Session, node_id: ast::node_id) -> bool { // Create a _rust_main(args: ~[str]) function which will be called from the // runtime rust_start function -pub fn create_main_wrapper(ccx: @crate_ctxt, _sp: span, main_llfn: ValueRef) { +pub fn create_main_wrapper(ccx: @CrateContext, + _sp: span, main_llfn: ValueRef) { let llfn = create_main(ccx, main_llfn); create_entry_fn(ccx, llfn); - fn create_main(ccx: @crate_ctxt, main_llfn: ValueRef) -> ValueRef { + fn create_main(ccx: @CrateContext, main_llfn: ValueRef) -> ValueRef { let nt = ty::mk_nil(ccx.tcx); let llfty = type_of_fn(ccx, ~[], nt); let llfdecl = decl_fn(ccx.llmod, ~"_rust_main", @@ -2216,7 +2268,7 @@ pub fn create_main_wrapper(ccx: @crate_ctxt, _sp: span, main_llfn: ValueRef) { return llfdecl; } - fn create_entry_fn(ccx: @crate_ctxt, rust_main: ValueRef) { + fn create_entry_fn(ccx: @CrateContext, rust_main: ValueRef) { #[cfg(windows)] fn main_name() -> ~str { return ~"WinMain@16"; } #[cfg(unix)] @@ -2281,7 +2333,7 @@ pub fn fill_fn_pair(bcx: block, pair: ValueRef, llfn: ValueRef, Store(bcx, llenvblobptr, env_cell); } -pub fn item_path(ccx: @crate_ctxt, i: @ast::item) -> path { +pub fn item_path(ccx: @CrateContext, i: @ast::item) -> path { vec::append( /*bad*/copy *match ccx.tcx.items.get(&i.id) { ast_map::node_item(_, p) => p, @@ -2293,10 +2345,10 @@ pub fn item_path(ccx: @crate_ctxt, i: @ast::item) -> path { /* If there's already a symbol for the dtor with and substs , return it; otherwise, create one and register it, returning it as well */ -pub fn get_dtor_symbol(ccx: @crate_ctxt, +pub fn get_dtor_symbol(ccx: @CrateContext, +path: path, id: ast::node_id, - +substs: Option) + substs: Option<@param_substs>) -> ~str { let t = ty::node_id_to_type(ccx.tcx, id); match ccx.item_symbols.find(&id) { @@ -2331,7 +2383,7 @@ pub fn get_dtor_symbol(ccx: @crate_ctxt, } } -pub fn get_item_val(ccx: @crate_ctxt, id: ast::node_id) -> ValueRef { +pub fn get_item_val(ccx: @CrateContext, id: ast::node_id) -> ValueRef { debug!("get_item_val(id=`%?`)", id); let tcx = ccx.tcx; match ccx.item_vals.find(&id) { @@ -2500,7 +2552,7 @@ pub fn get_item_val(ccx: @crate_ctxt, id: ast::node_id) -> ValueRef { } } -pub fn register_method(ccx: @crate_ctxt, +pub fn register_method(ccx: @CrateContext, id: ast::node_id, pth: @ast_map::path, m: @ast::method) -> ValueRef { @@ -2513,7 +2565,7 @@ pub fn register_method(ccx: @crate_ctxt, } // The constant translation pass. -pub fn trans_constant(ccx: @crate_ctxt, it: @ast::item) { +pub fn trans_constant(ccx: @CrateContext, it: @ast::item) { let _icx = ccx.insn_ctxt("trans_constant"); match it.node { ast::item_enum(ref enum_definition, _) => { @@ -2550,7 +2602,7 @@ pub fn trans_constant(ccx: @crate_ctxt, it: @ast::item) { } } -pub fn trans_constants(ccx: @crate_ctxt, crate: &ast::crate) { +pub fn trans_constants(ccx: @CrateContext, crate: &ast::crate) { visit::visit_crate( *crate, (), visit::mk_simple_visitor(@visit::SimpleVisitor { @@ -2564,7 +2616,7 @@ pub fn vp2i(cx: block, v: ValueRef) -> ValueRef { return PtrToInt(cx, v, ccx.int_type); } -pub fn p2i(ccx: @crate_ctxt, v: ValueRef) -> ValueRef { +pub fn p2i(ccx: @CrateContext, v: ValueRef) -> ValueRef { unsafe { return llvm::LLVMConstPtrToInt(v, ccx.int_type); } @@ -2784,8 +2836,8 @@ pub fn trap(bcx: block) { } } -pub fn decl_gc_metadata(ccx: @crate_ctxt, llmod_id: ~str) { - if !ccx.sess.opts.gc || !ccx.uses_gc { +pub fn decl_gc_metadata(ccx: @CrateContext, llmod_id: ~str) { + if !ccx.sess.opts.gc || !*ccx.uses_gc { return; } @@ -2802,7 +2854,7 @@ pub fn decl_gc_metadata(ccx: @crate_ctxt, llmod_id: ~str) { } } -pub fn create_module_map(ccx: @crate_ctxt) -> ValueRef { +pub fn create_module_map(ccx: @CrateContext) -> ValueRef { let elttype = T_struct(~[ccx.int_type, ccx.int_type]); let maptype = T_array(elttype, ccx.module_data.len() + 1); let map = str::as_c_str(~"_rust_mod_map", |buf| { @@ -2815,7 +2867,7 @@ pub fn create_module_map(ccx: @crate_ctxt) -> ValueRef { } let mut elts: ~[ValueRef] = ~[]; for ccx.module_data.each |&key, &val| { - let elt = C_struct(~[p2i(ccx, C_cstr(ccx, key)), + let elt = C_struct(~[p2i(ccx, C_cstr(ccx, @/*bad*/ copy key)), p2i(ccx, val)]); elts.push(elt); } @@ -2828,7 +2880,7 @@ pub fn create_module_map(ccx: @crate_ctxt) -> ValueRef { } -pub fn decl_crate_map(sess: session::Session, mapmeta: link_meta, +pub fn decl_crate_map(sess: session::Session, mapmeta: LinkMeta, llmod: ModuleRef) -> ValueRef { let targ_cfg = sess.targ_cfg; let int_type = T_int(targ_cfg); @@ -2853,15 +2905,15 @@ pub fn decl_crate_map(sess: session::Session, mapmeta: link_meta, return map; } -pub fn fill_crate_map(ccx: @crate_ctxt, map: ValueRef) { +pub fn fill_crate_map(ccx: @CrateContext, map: ValueRef) { let mut subcrates: ~[ValueRef] = ~[]; let mut i = 1; let cstore = ccx.sess.cstore; while cstore::have_crate_data(cstore, i) { let cdata = cstore::get_crate_data(cstore, i); - let nm = ~"_rust_crate_map_" + cdata.name + - ~"_" + cstore::get_crate_vers(cstore, i) + - ~"_" + cstore::get_crate_hash(cstore, i); + let nm = ~"_rust_crate_map_" + *cdata.name + + ~"_" + *cstore::get_crate_vers(cstore, i) + + ~"_" + *cstore::get_crate_hash(cstore, i); let cr = str::as_c_str(nm, |buf| { unsafe { llvm::LLVMAddGlobal(ccx.llmod, ccx.int_type, buf) @@ -2894,12 +2946,13 @@ pub fn fill_crate_map(ccx: @crate_ctxt, map: ValueRef) { } } -pub fn crate_ctxt_to_encode_parms(cx: @crate_ctxt) -> encoder::encode_parms { +pub fn crate_ctxt_to_encode_parms(cx: @CrateContext) + -> encoder::EncodeParams { let encode_inlined_item: encoder::encode_inlined_item = |ecx, ebml_w, path, ii| astencode::encode_inlined_item(ecx, ebml_w, path, ii, cx.maps); - return { + encoder::EncodeParams { diag: cx.sess.diagnostic(), tcx: cx.tcx, reachable: cx.reachable, @@ -2909,10 +2962,10 @@ pub fn crate_ctxt_to_encode_parms(cx: @crate_ctxt) -> encoder::encode_parms { link_meta: /*bad*/copy cx.link_meta, cstore: cx.sess.cstore, encode_inlined_item: encode_inlined_item - }; + } } -pub fn write_metadata(cx: @crate_ctxt, crate: &ast::crate) { +pub fn write_metadata(cx: @CrateContext, crate: &ast::crate) { if !*cx.sess.building_library { return; } let encode_parms = crate_ctxt_to_encode_parms(cx); let llmeta = C_bytes(encoder::encode_metadata(encode_parms, crate)); @@ -2940,7 +2993,7 @@ pub fn write_metadata(cx: @crate_ctxt, crate: &ast::crate) { } // Writes the current ABI version into the crate. -pub fn write_abi_version(ccx: @crate_ctxt) { +pub fn write_abi_version(ccx: @CrateContext) { mk_global(ccx, ~"rust_abi_version", C_uint(ccx, abi::abi_version), false); } @@ -2950,7 +3003,7 @@ pub fn trans_crate(sess: session::Session, tcx: ty::ctxt, output: &Path, emap2: resolve::ExportMap2, - maps: astencode::Maps) -> (ModuleRef, link_meta) { + maps: astencode::Maps) -> (ModuleRef, LinkMeta) { let symbol_hasher = @hash::default_state(); let link_meta = @@ -3003,7 +3056,7 @@ pub fn trans_crate(sess: session::Session, None }; - let ccx = @crate_ctxt { + let ccx = @CrateContext { sess: sess, llmod: llmod, td: td, @@ -3019,7 +3072,7 @@ pub fn trans_crate(sess: session::Session, discrims: HashMap(), discrim_symbols: HashMap(), tydescs: ty::new_ty_hash(), - mut finished_tydescs: false, + finished_tydescs: @mut false, external: HashMap(), monomorphized: HashMap(), monomorphizing: HashMap(), @@ -3030,6 +3083,7 @@ pub fn trans_crate(sess: session::Session, const_values: HashMap(), module_data: HashMap(), lltypes: ty::new_ty_hash(), + llsizingtypes: ty::new_ty_hash(), names: new_namegen(sess.parse_sess.interner), next_addrspace: new_addrspace_gen(), symbol_hasher: symbol_hasher, @@ -3060,9 +3114,9 @@ pub fn trans_crate(sess: session::Session, builder: BuilderRef_res(unsafe { llvm::LLVMCreateBuilder() }), shape_cx: mk_ctxt(llmod), crate_map: crate_map, - mut uses_gc: false, + uses_gc: @mut false, dbg_cx: dbg_cx, - mut do_not_commit_warning_issued: false + do_not_commit_warning_issued: @mut false }; { diff --git a/src/librustc/middle/trans/build.rs b/src/librustc/middle/trans/build.rs index 43953b68f599b..85e8be0987899 100644 --- a/src/librustc/middle/trans/build.rs +++ b/src/librustc/middle/trans/build.rs @@ -14,8 +14,9 @@ use lib::llvm::llvm; use lib::llvm::{CallConv, TypeKind, AtomicBinOp, AtomicOrdering}; use lib::llvm::{Opcode, IntPredicate, RealPredicate, True, False}; use lib::llvm::{ValueRef, TypeRef, BasicBlockRef, BuilderRef, ModuleRef}; -use libc::{c_uint, c_int}; +use libc::{c_uint, c_int, c_ulonglong}; use middle::trans::common::*; +use middle::trans::machine::llsize_of_real; use core::cast::transmute; use core::cast; @@ -536,6 +537,25 @@ pub fn Load(cx: block, PointerVal: ValueRef) -> ValueRef { } } +pub fn LoadRangeAssert(cx: block, PointerVal: ValueRef, lo: c_ulonglong, + hi: c_ulonglong, signed: lib::llvm::Bool) -> ValueRef { + let value = Load(cx, PointerVal); + + unsafe { + let t = llvm::LLVMGetElementType(llvm::LLVMTypeOf(PointerVal)); + let min = llvm::LLVMConstInt(t, lo, signed); + let max = llvm::LLVMConstInt(t, hi, signed); + + + do vec::as_imm_buf([min, max]) |ptr, len| { + llvm::LLVMSetMetadata(value, lib::llvm::MD_range as c_uint, + llvm::LLVMMDNode(ptr, len as c_uint)); + } + } + + value +} + pub fn Store(cx: block, Val: ValueRef, Ptr: ValueRef) { unsafe { if cx.unreachable { return; } @@ -834,7 +854,7 @@ pub fn add_span_comment(bcx: block, sp: span, text: ~str) { } } -pub fn add_comment(bcx: block, text: ~str) { +pub fn add_comment(bcx: block, text: &str) { unsafe { let ccx = bcx.ccx(); if !ccx.sess.no_asm_comments() { diff --git a/src/librustc/middle/trans/cabi_x86_64.rs b/src/librustc/middle/trans/cabi_x86_64.rs index a3c5e094ea819..9f717682dae09 100644 --- a/src/librustc/middle/trans/cabi_x86_64.rs +++ b/src/librustc/middle/trans/cabi_x86_64.rs @@ -274,11 +274,11 @@ fn classify_ty(ty: TypeRef) -> ~[x86_64_reg_class] { if words > 4 { all_mem(cls); let cls = cls; - return move cls; + return cls; } classify(ty, cls, 0, 0); fixup(ty, cls); - return move cls; + return cls; } fn llreg_ty(cls: &[x86_64_reg_class]) -> TypeRef { diff --git a/src/librustc/middle/trans/callee.rs b/src/librustc/middle/trans/callee.rs index 709ab9365ed99..c1dac70ae97d9 100644 --- a/src/librustc/middle/trans/callee.rs +++ b/src/librustc/middle/trans/callee.rs @@ -256,7 +256,7 @@ pub fn trans_fn_ref_with_vtables( // Should be either intra-crate or inlined. assert def_id.crate == ast::local_crate; - let mut {val, must_cast} = + let mut (val, must_cast) = monomorphize::monomorphic_fn(ccx, def_id, type_params, vtables, opt_impl_did, Some(ref_id)); if must_cast && ref_id != 0 { @@ -410,7 +410,7 @@ pub fn body_contains_ret(body: ast::blk) -> bool { // See [Note-arg-mode] pub fn trans_call_inner( ++in_cx: block, - call_info: Option, + call_info: Option, fn_expr_ty: ty::t, ret_ty: ty::t, get_callee: fn(block) -> Callee, @@ -510,8 +510,8 @@ pub fn trans_call_inner( } else if ret_in_loop { let ret_flag_result = bool_to_i1(bcx, Load(bcx, ret_flag.get())); bcx = do with_cond(bcx, ret_flag_result) |bcx| { - do option::iter(© bcx.fcx.loop_ret) |lret| { - Store(bcx, C_bool(true), lret.flagptr); + do option::iter(© bcx.fcx.loop_ret) |&(flagptr, _)| { + Store(bcx, C_bool(true), flagptr); Store(bcx, C_bool(false), bcx.fcx.llretptr); } base::cleanup_and_leave(bcx, None, Some(bcx.fcx.llreturn)); @@ -529,14 +529,19 @@ pub enum CallArgs { ArgVals(&[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) - -> {bcx: block, args: ~[ValueRef], retslot: ValueRef} { + +autoref_arg: AutorefArg) -> Args { let _icx = cx.insn_ctxt("trans_args"); let mut temp_cleanups = ~[]; let arg_tys = ty::ty_fn_args(fn_ty); @@ -593,7 +598,7 @@ pub fn trans_args(cx: block, revoke_clean(bcx, *c) } - return {bcx: bcx, args: llargs, retslot: llretslot}; + Args { bcx: bcx, args: llargs, retslot: llretslot } } pub enum AutorefArg { diff --git a/src/librustc/middle/trans/closure.rs b/src/librustc/middle/trans/closure.rs index c70425da9fa39..1409199a0d2d7 100644 --- a/src/librustc/middle/trans/closure.rs +++ b/src/librustc/middle/trans/closure.rs @@ -131,7 +131,7 @@ pub impl EnvAction { } pub impl EnvValue { - fn to_str(ccx: @crate_ctxt) -> ~str { + fn to_str(&self, ccx: @CrateContext) -> ~str { fmt!("%s(%s)", self.action.to_str(), self.datum.to_str(ccx)) } } @@ -178,10 +178,10 @@ pub fn allocate_cbox(bcx: block, sigil: ast::Sigil, cdata_ty: ty::t) // Allocate and initialize the box: match sigil { ast::ManagedSigil => { - malloc_raw(bcx, cdata_ty, heap_shared) + malloc_raw(bcx, cdata_ty, heap_managed) } ast::OwnedSigil => { - malloc_raw(bcx, cdata_ty, heap_exchange) + malloc_raw(bcx, cdata_ty, heap_for_unique(bcx, cdata_ty)) } ast::BorrowedSigil => { let cbox_ty = tuplify_box_ty(tcx, cdata_ty); @@ -192,11 +192,11 @@ pub fn allocate_cbox(bcx: block, sigil: ast::Sigil, cdata_ty: ty::t) } } -pub type closure_result = { - llbox: ValueRef, // llvalue of ptr to closure - cdata_ty: ty::t, // type of the closure data - bcx: block // final bcx -}; +pub struct ClosureResult { + llbox: ValueRef, // llvalue of ptr to closure + cdata_ty: ty::t, // type of the closure data + bcx: block // final bcx +} // Given a block context and a list of tydescs and values to bind // construct a closure out of them. If copying is true, it is a @@ -204,7 +204,7 @@ pub type closure_result = { // Otherwise, it is stack allocated and copies pointers to the upvars. pub fn store_environment(bcx: block, bound_values: ~[EnvValue], - sigil: ast::Sigil) -> closure_result { + sigil: ast::Sigil) -> ClosureResult { let _icx = bcx.insn_ctxt("closure::store_environment"); let ccx = bcx.ccx(), tcx = ccx.tcx; @@ -254,7 +254,7 @@ pub fn store_environment(bcx: block, revoke_clean(bcx, *cleanup); } - return {llbox: llbox, cdata_ty: cdata_ty, bcx: bcx}; + ClosureResult { llbox: llbox, cdata_ty: cdata_ty, bcx: bcx } } // Given a context and a list of upvars, build a closure. This just @@ -262,7 +262,7 @@ pub fn store_environment(bcx: block, pub fn build_closure(bcx0: block, cap_vars: &[moves::CaptureVar], sigil: ast::Sigil, - include_ret_handle: Option) -> closure_result { + include_ret_handle: Option) -> ClosureResult { let _icx = bcx0.insn_ctxt("closure::build_closure"); // If we need to, package up the iterator body to call let mut bcx = bcx0;; @@ -302,7 +302,7 @@ pub fn build_closure(bcx0: block, // Return value (we just pass a by-ref () and cast it later to // the right thing): let ret_true = match bcx.fcx.loop_ret { - Some({retptr, _}) => retptr, + Some((_, retptr)) => retptr, None => bcx.fcx.llretptr }; let ret_casted = PointerCast(bcx, ret_true, T_ptr(T_nil())); @@ -360,7 +360,7 @@ pub fn load_environment(fcx: fn_ctxt, let flagptr = Load(bcx, GEPi(bcx, llcdata, [0u, i])); let retptr = Load(bcx, GEPi(bcx, llcdata, [0u, i+1u])); - fcx.loop_ret = Some({flagptr: flagptr, retptr: retptr}); + fcx.loop_ret = Some((flagptr, retptr)); } } @@ -418,8 +418,8 @@ pub fn trans_expr_fn(bcx: block, let cap_vars = ccx.maps.capture_map.get(&user_id); let ret_handle = match is_loop_body {Some(x) => x, None => None}; - let {llbox, cdata_ty, bcx} = build_closure(bcx, cap_vars, sigil, - ret_handle); + let ClosureResult {llbox, cdata_ty, bcx} + = build_closure(bcx, cap_vars, sigil, ret_handle); trans_closure(ccx, sub_path, decl, body, llfn, no_self, /*bad*/ copy bcx.fcx.param_substs, user_id, None, @@ -574,7 +574,7 @@ pub fn make_opaque_cbox_free_glue( // Free the ty descr (if necc) and the box itself match sigil { ast::ManagedSigil => glue::trans_free(bcx, cbox), - ast::OwnedSigil => glue::trans_unique_free(bcx, cbox), + ast::OwnedSigil => glue::trans_exchange_free(bcx, cbox), ast::BorrowedSigil => { bcx.sess().bug(~"impossible") } diff --git a/src/librustc/middle/trans/common.rs b/src/librustc/middle/trans/common.rs index 03a91fa15fa08..969119f0aaf63 100644 --- a/src/librustc/middle/trans/common.rs +++ b/src/librustc/middle/trans/common.rs @@ -21,9 +21,9 @@ use driver::session; use driver::session::Session; use lib::llvm::{ModuleRef, ValueRef, TypeRef, BasicBlockRef, BuilderRef}; use lib::llvm::{True, False, Bool}; -use lib::llvm::{llvm, target_data, type_names, associate_type, name_has_type}; +use lib::llvm::{llvm, TargetData, TypeNames, associate_type, name_has_type}; use lib; -use metadata::common::link_meta; +use metadata::common::LinkMeta; use metadata::{csearch}; use middle::astencode; use middle::resolve; @@ -136,7 +136,7 @@ pub struct Stats { n_closures: uint, llvm_insn_ctxt: @mut ~[~str], llvm_insns: HashMap<~str, uint>, - fn_times: @mut ~[{ident: ~str, time: int}] + fn_times: @mut ~[(~str, int)] // (ident, time) } pub struct BuilderRef_res { @@ -157,25 +157,25 @@ pub fn BuilderRef_res(B: BuilderRef) -> BuilderRef_res { type ExternMap = HashMap<@str, ValueRef>; // Crate context. Every crate we compile has one of these. -pub struct crate_ctxt { +pub struct CrateContext { sess: session::Session, llmod: ModuleRef, - td: target_data, - tn: type_names, + td: TargetData, + tn: @TypeNames, externs: ExternMap, intrinsics: HashMap<~str, ValueRef>, item_vals: HashMap, exp_map2: resolve::ExportMap2, reachable: reachable::map, item_symbols: HashMap, - link_meta: link_meta, + link_meta: LinkMeta, enum_sizes: HashMap, discrims: HashMap, discrim_symbols: HashMap, tydescs: HashMap, // Set when running emit_tydescs to enforce that no more tydescs are // created. - mut finished_tydescs: bool, + finished_tydescs: @mut bool, // Track mapping of external ids to local items imported for inlining external: HashMap>, // Cache instances of monomorphized functions @@ -186,7 +186,7 @@ pub struct crate_ctxt { // Cache generated vtables vtables: HashMap, // Cache of constant strings, - const_cstr_cache: HashMap<~str, ValueRef>, + const_cstr_cache: HashMap<@~str, ValueRef>, // Reverse-direction for const ptrs cast from globals. // Key is an int, cast from a ValueRef holding a *T, @@ -202,6 +202,7 @@ pub struct crate_ctxt { const_values: HashMap, module_data: HashMap<~str, ValueRef>, lltypes: HashMap, + llsizingtypes: HashMap, names: namegen, next_addrspace: addrspace_gen, symbol_hasher: @hash::State, @@ -211,7 +212,7 @@ pub struct crate_ctxt { tcx: ty::ctxt, maps: astencode::Maps, stats: @mut Stats, - upcalls: @upcall::upcalls, + upcalls: @upcall::Upcalls, tydesc_type: TypeRef, int_type: TypeRef, float_type: TypeRef, @@ -223,9 +224,9 @@ pub struct crate_ctxt { // Set when at least one function uses GC. Needed so that // decl_gc_metadata knows whether to link to the module metadata, which // is not emitted by LLVM's GC pass when no functions use GC. - mut uses_gc: bool, - dbg_cx: Option, - mut do_not_commit_warning_issued: bool + uses_gc: @mut bool, + dbg_cx: Option, + do_not_commit_warning_issued: @mut bool } // Types used for llself. @@ -272,34 +273,34 @@ pub struct fn_ctxt_ { // the function, due to LLVM's quirks. // A block for all the function's static allocas, so that LLVM // will coalesce them into a single alloca call. - mut llstaticallocas: BasicBlockRef, + llstaticallocas: BasicBlockRef, // A block containing code that copies incoming arguments to space // already allocated by code in one of the llallocas blocks. // (LLVM requires that arguments be copied to local allocas before // allowing most any operation to be performed on them.) - mut llloadenv: Option, - mut llreturn: BasicBlockRef, + llloadenv: Option, + llreturn: BasicBlockRef, // The 'self' value currently in use in this function, if there // is one. // // NB: This is the type of the self *variable*, not the self *type*. The // self type is set only for default methods, while the self variable is // set for all methods. - mut llself: Option, + llself: Option, // The a value alloca'd for calls to upcalls.rust_personality. Used when // outputting the resume instruction. - mut personality: Option, + personality: Option, // If this is a for-loop body that returns, this holds the pointers needed - // for that - mut loop_ret: Option<{flagptr: ValueRef, retptr: ValueRef}>, + // for that (flagptr, retptr) + loop_ret: Option<(ValueRef, ValueRef)>, // Maps arguments to allocas created for them in llallocas. - llargs: HashMap, + llargs: @HashMap, // Maps the def_ids for local variables to the allocas created for // them in llallocas. - lllocals: HashMap, + lllocals: @HashMap, // Same as above, but for closure upvars - llupvars: HashMap, + llupvars: @HashMap, // The node_id of the function, or -1 if it doesn't correspond to // a user-defined function. @@ -310,7 +311,7 @@ pub struct fn_ctxt_ { // If this function is being monomorphized, this contains the type // substitutions used. - param_substs: Option, + param_substs: Option<@param_substs>, // The source span and nesting context where this function comes from, for // error reporting and symbol generation. @@ -318,21 +319,23 @@ pub struct fn_ctxt_ { path: path, // This function's enclosing crate context. - ccx: @crate_ctxt + ccx: @@CrateContext } -pub type fn_ctxt = @fn_ctxt_; +pub type fn_ctxt = @mut fn_ctxt_; -pub fn warn_not_to_commit(ccx: @crate_ctxt, msg: ~str) { - if !ccx.do_not_commit_warning_issued { - ccx.do_not_commit_warning_issued = true; +pub fn warn_not_to_commit(ccx: @CrateContext, msg: ~str) { + if !*ccx.do_not_commit_warning_issued { + *ccx.do_not_commit_warning_issued = true; ccx.sess.warn(msg + ~" -- do not commit like this!"); } } // Heap selectors. Indicate which heap something should go on. +#[deriving_eq] pub enum heap { - heap_shared, + heap_managed, + heap_managed_unique, heap_exchange, } @@ -349,9 +352,12 @@ pub enum cleanup { // Used to remember and reuse existing cleanup paths // target: none means the path ends in an resume instruction -pub type cleanup_path = {target: Option, dest: BasicBlockRef}; +pub struct cleanup_path { + target: Option, + dest: BasicBlockRef +} -pub fn scope_clean_changed(scope_info: scope_info) { +pub fn scope_clean_changed(scope_info: &mut scope_info) { if scope_info.cleanup_paths.len() > 0u { scope_info.cleanup_paths = ~[]; } scope_info.landing_pad = None; } @@ -371,7 +377,7 @@ pub fn cleanup_type(cx: ty::ctxt, ty: ty::t) -> cleantype { // non-immediates, we must add an additional level of indirection, which // allows us to alloca a pointer with the right addrspace. pub fn root_for_cleanup(bcx: block, v: ValueRef, t: ty::t) - -> {root: ValueRef, rooted: bool} { + -> (ValueRef, bool) { let ccx = bcx.ccx(); let addrspace = base::get_tydesc(ccx, t).addrspace; @@ -379,9 +385,9 @@ pub fn root_for_cleanup(bcx: block, v: ValueRef, t: ty::t) let llty = type_of::type_of_rooted(ccx, t); let root = base::alloca(bcx, llty); build::Store(bcx, build::PointerCast(bcx, v, llty), root); - {root: root, rooted: true} + (root, true) } else { - {root: v, rooted: false} + (v, false) } } @@ -390,7 +396,7 @@ pub fn add_clean(bcx: block, val: ValueRef, t: ty::t) { debug!("add_clean(%s, %s, %s)", bcx.to_str(), val_str(bcx.ccx().tn, val), ty_to_str(bcx.ccx().tcx, t)); - let {root, rooted} = root_for_cleanup(bcx, val, t); + let (root, rooted) = root_for_cleanup(bcx, val, t); let cleanup_type = cleanup_type(bcx.tcx(), t); do in_scope_cx(bcx) |scope_info| { scope_info.cleanups.push( @@ -418,7 +424,7 @@ pub fn add_clean_temp_mem(bcx: block, val: ValueRef, t: ty::t) { debug!("add_clean_temp_mem(%s, %s, %s)", bcx.to_str(), val_str(bcx.ccx().tn, val), ty_to_str(bcx.ccx().tcx, t)); - let {root, rooted} = root_for_cleanup(bcx, val, t); + let (root, rooted) = root_for_cleanup(bcx, val, t); let cleanup_type = cleanup_type(bcx.tcx(), t); do in_scope_cx(bcx) |scope_info| { scope_info.cleanups.push( @@ -431,7 +437,7 @@ pub fn add_clean_frozen_root(bcx: block, val: ValueRef, t: ty::t) { debug!("add_clean_frozen_root(%s, %s, %s)", bcx.to_str(), val_str(bcx.ccx().tn, val), ty_to_str(bcx.ccx().tcx, t)); - let {root, rooted} = root_for_cleanup(bcx, val, t); + let (root, rooted) = root_for_cleanup(bcx, val, t); let cleanup_type = cleanup_type(bcx.tcx(), t); do in_scope_cx(bcx) |scope_info| { scope_info.cleanups.push( @@ -454,12 +460,12 @@ pub fn add_clean_frozen_root(bcx: block, val: ValueRef, t: ty::t) { } pub fn add_clean_free(cx: block, ptr: ValueRef, heap: heap) { let free_fn = match heap { - heap_shared => { + heap_managed | heap_managed_unique => { let f: @fn(block) -> block = |a| glue::trans_free(a, ptr); f } heap_exchange => { - let f: @fn(block) -> block = |a| glue::trans_unique_free(a, ptr); + let f: @fn(block) -> block = |a| glue::trans_exchange_free(a, ptr); f } }; @@ -484,8 +490,8 @@ pub fn revoke_clean(cx: block, val: ValueRef) { }); for cleanup_pos.each |i| { scope_info.cleanups = - vec::append(vec::slice(scope_info.cleanups, 0u, *i), - vec::view(scope_info.cleanups, + vec::append(vec::slice(scope_info.cleanups, 0u, *i).to_vec(), + vec::slice(scope_info.cleanups, *i + 1u, scope_info.cleanups.len())); scope_clean_changed(scope_info); @@ -494,9 +500,9 @@ pub fn revoke_clean(cx: block, val: ValueRef) { } pub fn block_cleanups(bcx: block) -> ~[cleanup] { - match bcx.kind { + match *bcx.kind { block_non_scope => ~[], - block_scope(ref inf) => /*bad*/copy inf.cleanups + block_scope(ref mut inf) => /*bad*/copy inf.cleanups } } @@ -520,43 +526,43 @@ pub struct scope_info { // A list of functions that must be run at when leaving this // block, cleaning up any variables that were introduced in the // block. - mut cleanups: ~[cleanup], + cleanups: ~[cleanup], // Existing cleanup paths that may be reused, indexed by destination and // cleared when the set of cleanups changes. - mut cleanup_paths: ~[cleanup_path], + cleanup_paths: ~[cleanup_path], // Unwinding landing pad. Also cleared when cleanups change. - mut landing_pad: Option, + landing_pad: Option, } pub trait get_node_info { - fn info() -> Option; + fn info(&self) -> Option; } -pub impl @ast::expr: get_node_info { - fn info() -> Option { - Some({id: self.id, span: self.span}) +pub impl get_node_info for @ast::expr { + fn info(&self) -> Option { + Some(NodeInfo { id: self.id, span: self.span }) } } -pub impl ast::blk: get_node_info { - fn info() -> Option { - Some({id: self.node.id, span: self.span}) +pub impl get_node_info for ast::blk { + fn info(&self) -> Option { + Some(NodeInfo { id: self.node.id, span: self.span }) } } // XXX: Work around a trait parsing bug. remove after snapshot pub type optional_boxed_ast_expr = Option<@ast::expr>; -pub impl optional_boxed_ast_expr: get_node_info { - fn info() -> Option { +pub impl get_node_info for optional_boxed_ast_expr { + fn info(&self) -> Option { self.chain_ref(|s| s.info()) } } -pub type node_info = { +pub struct NodeInfo { id: ast::node_id, span: span -}; +} // Basic block context. We create a block context for each basic block // (single-entry, single-exit sequence of instructions) we generate from Rust @@ -570,22 +576,22 @@ pub struct block_ { // instructions into that block by way of this block context. // The block pointing to this one in the function's digraph. llbb: BasicBlockRef, - mut terminated: bool, - mut unreachable: bool, + terminated: bool, + unreachable: bool, parent: Option, // The 'kind' of basic block this is. - kind: block_kind, + kind: @mut block_kind, // Is this block part of a landing pad? is_lpad: bool, // info about the AST node this block originated from, if any - node_info: Option, + node_info: Option, // The function context for the function to which this block is // attached. fcx: fn_ctxt } pub fn block_(llbb: BasicBlockRef, parent: Option, -kind: block_kind, - is_lpad: bool, node_info: Option, fcx: fn_ctxt) + is_lpad: bool, node_info: Option, fcx: fn_ctxt) -> block_ { block_ { @@ -593,21 +599,19 @@ pub fn block_(llbb: BasicBlockRef, parent: Option, -kind: block_kind, terminated: false, unreachable: false, parent: parent, - kind: move kind, + kind: @mut kind, is_lpad: is_lpad, node_info: node_info, fcx: fcx } } -/* This must be enum and not type, or trans goes into an infinite loop (#2572) - */ -pub enum block = @block_; +pub type block = @mut block_; pub fn mk_block(llbb: BasicBlockRef, parent: Option, -kind: block_kind, - is_lpad: bool, node_info: Option, fcx: fn_ctxt) + is_lpad: bool, node_info: Option, fcx: fn_ctxt) -> block { - block(@block_(llbb, parent, move kind, is_lpad, node_info, fcx)) + @mut block_(llbb, parent, kind, is_lpad, node_info, fcx) } // First two args are retptr, env @@ -623,13 +627,13 @@ pub fn rslt(bcx: block, val: ValueRef) -> Result { } pub impl Result { - fn unpack(bcx: &mut block) -> ValueRef { + fn unpack(&self, bcx: &mut block) -> ValueRef { *bcx = self.bcx; return self.val; } } -pub fn ty_str(tn: type_names, t: TypeRef) -> @str { +pub fn ty_str(tn: @TypeNames, t: TypeRef) -> @str { return lib::llvm::type_to_str(tn, t); } @@ -639,7 +643,7 @@ pub fn val_ty(v: ValueRef) -> TypeRef { } } -pub fn val_str(tn: type_names, v: ValueRef) -> @str { +pub fn val_str(tn: @TypeNames, v: ValueRef) -> @str { return ty_str(tn, val_ty(v)); } @@ -656,17 +660,21 @@ pub fn struct_elt(llstructty: TypeRef, n: uint) -> TypeRef { } } -pub fn in_scope_cx(cx: block, f: fn(scope_info)) { +pub fn in_scope_cx(cx: block, f: &fn(&mut scope_info)) { let mut cur = cx; loop { - match cur.kind { - block_scope(ref inf) => { - debug!("in_scope_cx: selected cur=%s (cx=%s)", - cur.to_str(), cx.to_str()); - f((*inf)); - return; - } - _ => () + { + // XXX: Borrow check bug workaround. + let kind: &mut block_kind = &mut *cur.kind; + match *kind { + block_scope(ref mut inf) => { + debug!("in_scope_cx: selected cur=%s (cx=%s)", + cur.to_str(), cx.to_str()); + f(inf); + return; + } + _ => () + } } cur = block_parent(cur); } @@ -683,27 +691,27 @@ pub fn block_parent(cx: block) -> block { // Accessors pub impl block { - pure fn ccx() -> @crate_ctxt { self.fcx.ccx } - pure fn tcx() -> ty::ctxt { self.fcx.ccx.tcx } - pure fn sess() -> Session { self.fcx.ccx.sess } + pure fn ccx(&self) -> @CrateContext { *self.fcx.ccx } + pure fn tcx(&self) -> ty::ctxt { self.fcx.ccx.tcx } + pure fn sess(&self) -> Session { self.fcx.ccx.sess } - fn node_id_to_str(id: ast::node_id) -> ~str { + fn node_id_to_str(&self, id: ast::node_id) -> ~str { ast_map::node_id_to_str(self.tcx().items, id, self.sess().intr()) } - fn expr_to_str(e: @ast::expr) -> ~str { + fn expr_to_str(&self, e: @ast::expr) -> ~str { expr_repr(self.tcx(), e) } - fn expr_is_lval(e: @ast::expr) -> bool { + fn expr_is_lval(&self, e: @ast::expr) -> bool { ty::expr_is_lval(self.tcx(), self.ccx().maps.method_map, e) } - fn expr_kind(e: @ast::expr) -> ty::ExprKind { + fn expr_kind(&self, e: @ast::expr) -> ty::ExprKind { ty::expr_kind(self.tcx(), self.ccx().maps.method_map, e) } - fn def(nid: ast::node_id) -> ast::def { + fn def(&self, nid: ast::node_id) -> ast::def { match self.tcx().def_map.find(&nid) { Some(v) => v, None => { @@ -713,15 +721,15 @@ pub impl block { } } - fn val_str(val: ValueRef) -> @str { + fn val_str(&self, val: ValueRef) -> @str { val_str(self.ccx().tn, val) } - fn llty_str(llty: TypeRef) -> @str { + fn llty_str(&self, llty: TypeRef) -> @str { ty_str(self.ccx().tn, llty) } - fn ty_to_str(t: ty::t) -> ~str { + fn ty_to_str(&self, t: ty::t) -> ~str { ty_to_str(self.tcx(), t) } fn to_str(&self) -> ~str { @@ -773,7 +781,7 @@ pub fn T_int(targ_cfg: @session::config) -> TypeRef { }; } -pub fn T_int_ty(cx: @crate_ctxt, t: ast::int_ty) -> TypeRef { +pub fn T_int_ty(cx: @CrateContext, t: ast::int_ty) -> TypeRef { match t { ast::ty_i => cx.int_type, ast::ty_char => T_char(), @@ -784,7 +792,7 @@ pub fn T_int_ty(cx: @crate_ctxt, t: ast::int_ty) -> TypeRef { } } -pub fn T_uint_ty(cx: @crate_ctxt, t: ast::uint_ty) -> TypeRef { +pub fn T_uint_ty(cx: @CrateContext, t: ast::uint_ty) -> TypeRef { match t { ast::ty_u => cx.int_type, ast::ty_u8 => T_i8(), @@ -794,7 +802,7 @@ pub fn T_uint_ty(cx: @crate_ctxt, t: ast::uint_ty) -> TypeRef { } } -pub fn T_float_ty(cx: @crate_ctxt, t: ast::float_ty) -> TypeRef { +pub fn T_float_ty(cx: @CrateContext, t: ast::float_ty) -> TypeRef { match t { ast::ty_f => cx.float_type, ast::ty_f32 => T_f32(), @@ -824,7 +832,7 @@ pub fn T_fn(inputs: ~[TypeRef], output: TypeRef) -> TypeRef { } } -pub fn T_fn_pair(cx: @crate_ctxt, tfn: TypeRef) -> TypeRef { +pub fn T_fn_pair(cx: @CrateContext, tfn: TypeRef) -> TypeRef { return T_struct(~[T_ptr(tfn), T_opaque_cbox_ptr(cx)]); } @@ -894,7 +902,7 @@ pub fn T_task(targ_cfg: @session::config) -> TypeRef { return t; } -pub fn T_tydesc_field(cx: @crate_ctxt, field: uint) -> TypeRef { +pub fn T_tydesc_field(cx: @CrateContext, field: uint) -> TypeRef { // Bit of a kludge: pick the fn typeref out of the tydesc.. unsafe { @@ -909,7 +917,7 @@ pub fn T_tydesc_field(cx: @crate_ctxt, field: uint) -> TypeRef { } } -pub fn T_generic_glue_fn(cx: @crate_ctxt) -> TypeRef { +pub fn T_generic_glue_fn(cx: @CrateContext) -> TypeRef { let s = @"glue_fn"; match name_has_type(cx.tn, s) { Some(t) => return t, @@ -950,7 +958,7 @@ pub fn T_vec2(targ_cfg: @session::config, t: TypeRef) -> TypeRef { T_array(t, 0u)]); // elements } -pub fn T_vec(ccx: @crate_ctxt, t: TypeRef) -> TypeRef { +pub fn T_vec(ccx: @CrateContext, t: TypeRef) -> TypeRef { return T_vec2(ccx.sess.targ_cfg, t); } @@ -972,16 +980,16 @@ pub fn tuplify_box_ty(tcx: ty::ctxt, t: ty::t) -> ty::t { t]); } -pub fn T_box_header_fields(cx: @crate_ctxt) -> ~[TypeRef] { +pub fn T_box_header_fields(cx: @CrateContext) -> ~[TypeRef] { let ptr = T_ptr(T_i8()); return ~[cx.int_type, T_ptr(cx.tydesc_type), ptr, ptr]; } -pub fn T_box_header(cx: @crate_ctxt) -> TypeRef { +pub fn T_box_header(cx: @CrateContext) -> TypeRef { return T_struct(T_box_header_fields(cx)); } -pub fn T_box(cx: @crate_ctxt, t: TypeRef) -> TypeRef { +pub fn T_box(cx: @CrateContext, t: TypeRef) -> TypeRef { return T_struct(vec::append(T_box_header_fields(cx), ~[t])); } @@ -991,15 +999,15 @@ pub fn T_box_ptr(t: TypeRef) -> TypeRef { } } -pub fn T_opaque_box(cx: @crate_ctxt) -> TypeRef { +pub fn T_opaque_box(cx: @CrateContext) -> TypeRef { return T_box(cx, T_i8()); } -pub fn T_opaque_box_ptr(cx: @crate_ctxt) -> TypeRef { +pub fn T_opaque_box_ptr(cx: @CrateContext) -> TypeRef { return T_box_ptr(T_opaque_box(cx)); } -pub fn T_unique(cx: @crate_ctxt, t: TypeRef) -> TypeRef { +pub fn T_unique(cx: @CrateContext, t: TypeRef) -> TypeRef { return T_struct(vec::append(T_box_header_fields(cx), ~[t])); } @@ -1009,21 +1017,21 @@ pub fn T_unique_ptr(t: TypeRef) -> TypeRef { } } -pub fn T_port(cx: @crate_ctxt, _t: TypeRef) -> TypeRef { +pub fn T_port(cx: @CrateContext, _t: TypeRef) -> TypeRef { return T_struct(~[cx.int_type]); // Refcount } -pub fn T_chan(cx: @crate_ctxt, _t: TypeRef) -> TypeRef { +pub fn T_chan(cx: @CrateContext, _t: TypeRef) -> TypeRef { return T_struct(~[cx.int_type]); // Refcount } -pub fn T_taskptr(cx: @crate_ctxt) -> TypeRef { return T_ptr(cx.task_type); } +pub fn T_taskptr(cx: @CrateContext) -> TypeRef { return T_ptr(cx.task_type); } // This type must never be used directly; it must always be cast away. -pub fn T_typaram(tn: type_names) -> TypeRef { +pub fn T_typaram(tn: @TypeNames) -> TypeRef { let s = @"typaram"; match name_has_type(tn, s) { Some(t) => return t, @@ -1034,21 +1042,21 @@ pub fn T_typaram(tn: type_names) -> TypeRef { return t; } -pub fn T_typaram_ptr(tn: type_names) -> TypeRef { +pub fn T_typaram_ptr(tn: @TypeNames) -> TypeRef { return T_ptr(T_typaram(tn)); } -pub fn T_opaque_cbox_ptr(cx: @crate_ctxt) -> TypeRef { +pub fn T_opaque_cbox_ptr(cx: @CrateContext) -> TypeRef { // closures look like boxes (even when they are fn~ or fn&) // see trans_closure.rs return T_opaque_box_ptr(cx); } -pub fn T_enum_discrim(cx: @crate_ctxt) -> TypeRef { +pub fn T_enum_discrim(cx: @CrateContext) -> TypeRef { return cx.int_type; } -pub fn T_opaque_enum(cx: @crate_ctxt) -> TypeRef { +pub fn T_opaque_enum(cx: @CrateContext) -> TypeRef { let s = @"opaque_enum"; match name_has_type(cx.tn, s) { Some(t) => return t, @@ -1059,15 +1067,15 @@ pub fn T_opaque_enum(cx: @crate_ctxt) -> TypeRef { return t; } -pub fn T_opaque_enum_ptr(cx: @crate_ctxt) -> TypeRef { +pub fn T_opaque_enum_ptr(cx: @CrateContext) -> TypeRef { return T_ptr(T_opaque_enum(cx)); } -pub fn T_captured_tydescs(cx: @crate_ctxt, n: uint) -> TypeRef { +pub fn T_captured_tydescs(cx: @CrateContext, n: uint) -> TypeRef { return T_struct(vec::from_elem::(n, T_ptr(cx.tydesc_type))); } -pub fn T_opaque_trait(cx: @crate_ctxt, vstore: ty::vstore) -> TypeRef { +pub fn T_opaque_trait(cx: @CrateContext, vstore: ty::vstore) -> TypeRef { match vstore { ty::vstore_box => { T_struct(~[T_ptr(cx.tydesc_type), T_opaque_box_ptr(cx)]) @@ -1125,11 +1133,11 @@ pub fn C_i64(i: i64) -> ValueRef { return C_integral(T_i64(), i as u64, True); } -pub fn C_int(cx: @crate_ctxt, i: int) -> ValueRef { +pub fn C_int(cx: @CrateContext, i: int) -> ValueRef { return C_integral(cx.int_type, i as u64, True); } -pub fn C_uint(cx: @crate_ctxt, i: uint) -> ValueRef { +pub fn C_uint(cx: @CrateContext, i: uint) -> ValueRef { return C_integral(cx.int_type, i as u64, False); } @@ -1140,15 +1148,15 @@ pub fn C_u8(i: uint) -> ValueRef { // This is a 'c-like' raw string, which differs from // our boxed-and-length-annotated strings. -pub fn C_cstr(cx: @crate_ctxt, +s: ~str) -> ValueRef { +pub fn C_cstr(cx: @CrateContext, s: @~str) -> ValueRef { unsafe { match cx.const_cstr_cache.find(&s) { - Some(llval) => return llval, - None => () + Some(llval) => return llval, + None => () } - let sc = do str::as_c_str(s) |buf| { - llvm::LLVMConstString(buf, str::len(s) as c_uint, False) + let sc = do str::as_c_str(*s) |buf| { + llvm::LLVMConstString(buf, s.len() as c_uint, False) }; let g = str::as_c_str(fmt!("str%u", (cx.names)(~"str").repr), @@ -1165,9 +1173,9 @@ pub fn C_cstr(cx: @crate_ctxt, +s: ~str) -> ValueRef { // NB: Do not use `do_spill_noroot` to make this into a constant string, or // you will be kicked off fast isel. See issue #4352 for an example of this. -pub fn C_estr_slice(cx: @crate_ctxt, +s: ~str) -> ValueRef { +pub fn C_estr_slice(cx: @CrateContext, s: @~str) -> ValueRef { unsafe { - let len = str::len(s); + let len = s.len(); let cs = llvm::LLVMConstPointerCast(C_cstr(cx, s), T_ptr(T_i8())); C_struct(~[cs, C_uint(cx, len + 1u /* +1 for null */)]) } @@ -1240,7 +1248,7 @@ pub fn C_bytes_plus_null(bytes: ~[u8]) -> ValueRef { } } -pub fn C_shape(ccx: @crate_ctxt, +bytes: ~[u8]) -> ValueRef { +pub fn C_shape(ccx: @CrateContext, +bytes: ~[u8]) -> ValueRef { unsafe { let llshape = C_bytes_plus_null(bytes); let name = fmt!("shape%u", (ccx.names)(~"shape").repr); @@ -1280,7 +1288,7 @@ pub struct mono_id_ { pub type mono_id = @mono_id_; -pub impl mono_param_id : to_bytes::IterBytes { +pub impl to_bytes::IterBytes for mono_param_id { pure fn iter_bytes(&self, +lsb0: bool, f: to_bytes::Cb) { match /*bad*/copy *self { mono_precise(t, mids) => @@ -1294,7 +1302,7 @@ pub impl mono_param_id : to_bytes::IterBytes { } } -pub impl mono_id_ : to_bytes::IterBytes { +pub impl to_bytes::IterBytes for mono_id_ { pure fn iter_bytes(&self, +lsb0: bool, f: to_bytes::Cb) { to_bytes::iter_bytes_2(&self.def, &self.params, lsb0, f); } @@ -1323,7 +1331,7 @@ pub fn path_str(sess: session::Session, p: path) -> ~str { ast_map::path_name(s) | ast_map::path_mod(s) => { if first { first = false; } else { r += ~"::"; } - r += sess.str_of(s); + r += *sess.str_of(s); } } } @@ -1394,7 +1402,7 @@ pub fn resolve_vtable_in_fn_ctxt(fcx: fn_ctxt, +vt: typeck::vtable_origin) } typeck::vtable_param(n_param, n_bound) => { match fcx.param_substs { - Some(ref substs) => { + Some(substs) => { find_vtable(tcx, substs, n_param, n_bound) } _ => { diff --git a/src/librustc/middle/trans/consts.rs b/src/librustc/middle/trans/consts.rs index d86d4c97c3bed..ab85da304cb89 100644 --- a/src/librustc/middle/trans/consts.rs +++ b/src/librustc/middle/trans/consts.rs @@ -20,7 +20,7 @@ use middle::ty; use syntax::{ast, ast_util, codemap, ast_map}; -pub fn const_lit(cx: @crate_ctxt, e: @ast::expr, lit: ast::lit) +pub fn const_lit(cx: @CrateContext, e: @ast::expr, lit: ast::lit) -> ValueRef { let _icx = cx.insn_ctxt("trans_lit"); match lit.node { @@ -55,11 +55,11 @@ pub fn const_lit(cx: @crate_ctxt, e: @ast::expr, lit: ast::lit) } ast::lit_bool(b) => C_bool(b), ast::lit_nil => C_nil(), - ast::lit_str(s) => C_estr_slice(cx, /*bad*/copy *s) + ast::lit_str(s) => C_estr_slice(cx, s) } } -pub fn const_ptrcast(cx: @crate_ctxt, a: ValueRef, t: TypeRef) -> ValueRef { +pub fn const_ptrcast(cx: @CrateContext, a: ValueRef, t: TypeRef) -> ValueRef { unsafe { let b = llvm::LLVMConstPointerCast(a, T_ptr(t)); assert cx.const_globals.insert(b as int, a); @@ -67,7 +67,7 @@ pub fn const_ptrcast(cx: @crate_ctxt, a: ValueRef, t: TypeRef) -> ValueRef { } } -pub fn const_vec(cx: @crate_ctxt, e: @ast::expr, es: &[@ast::expr]) +pub fn const_vec(cx: @CrateContext, e: @ast::expr, es: &[@ast::expr]) -> (ValueRef, ValueRef, TypeRef) { unsafe { let vec_ty = ty::expr_ty(cx.tcx, e); @@ -86,7 +86,7 @@ pub fn const_vec(cx: @crate_ctxt, e: @ast::expr, es: &[@ast::expr]) } } -pub fn const_deref(cx: @crate_ctxt, v: ValueRef) -> ValueRef { +pub fn const_deref(cx: @CrateContext, v: ValueRef) -> ValueRef { unsafe { let v = match cx.const_globals.find(&(v as int)) { Some(v) => v, @@ -98,7 +98,7 @@ pub fn const_deref(cx: @crate_ctxt, v: ValueRef) -> ValueRef { } } -pub fn const_get_elt(cx: @crate_ctxt, v: ValueRef, us: &[c_uint]) +pub fn const_get_elt(cx: @CrateContext, v: ValueRef, us: &[c_uint]) -> ValueRef { unsafe { let r = do vec::as_imm_buf(us) |p, len| { @@ -112,7 +112,7 @@ pub fn const_get_elt(cx: @crate_ctxt, v: ValueRef, us: &[c_uint]) } } -pub fn const_autoderef(cx: @crate_ctxt, ty: ty::t, v: ValueRef) +pub fn const_autoderef(cx: @CrateContext, ty: ty::t, v: ValueRef) -> (ty::t, ValueRef) { let mut t1 = ty; let mut v1 = v; @@ -128,7 +128,7 @@ pub fn const_autoderef(cx: @crate_ctxt, ty: ty::t, v: ValueRef) } } -pub fn get_const_val(cx: @crate_ctxt, def_id: ast::def_id) -> ValueRef { +pub fn get_const_val(cx: @CrateContext, def_id: ast::def_id) -> ValueRef { if !ast_util::is_local(def_id) { cx.tcx.sess.bug(~"cross-crate constants"); } @@ -145,7 +145,7 @@ pub fn get_const_val(cx: @crate_ctxt, def_id: ast::def_id) -> ValueRef { cx.const_values.get(&def_id.node) } -pub fn const_expr(cx: @crate_ctxt, e: @ast::expr) -> ValueRef { +pub fn const_expr(cx: @CrateContext, e: @ast::expr) -> ValueRef { unsafe { let _icx = cx.insn_ctxt("const_expr"); return match /*bad*/copy e.node { @@ -483,7 +483,7 @@ pub fn const_expr(cx: @crate_ctxt, e: @ast::expr) -> ValueRef { } } -pub fn trans_const(ccx: @crate_ctxt, _e: @ast::expr, id: ast::node_id) { +pub fn trans_const(ccx: @CrateContext, _e: @ast::expr, id: ast::node_id) { unsafe { let _icx = ccx.insn_ctxt("trans_const"); let g = base::get_item_val(ccx, id); diff --git a/src/librustc/middle/trans/controlflow.rs b/src/librustc/middle/trans/controlflow.rs index 792c5958822e0..4cf12576a78ee 100644 --- a/src/librustc/middle/trans/controlflow.rs +++ b/src/librustc/middle/trans/controlflow.rs @@ -237,7 +237,7 @@ pub fn trans_break_cont(bcx: block, let mut unwind = bcx; let mut target; loop { - match unwind.kind { + match *unwind.kind { block_scope(scope_info { loop_break: Some(brk), loop_label: l, @@ -289,7 +289,7 @@ pub fn trans_ret(bcx: block, e: Option<@ast::expr>) -> block { let _icx = bcx.insn_ctxt("trans_ret"); let mut bcx = bcx; let retptr = match copy bcx.fcx.loop_ret { - Some({flagptr, retptr}) => { + Some((flagptr, retptr)) => { // This is a loop body return. Must set continue flag (our retptr) // to false, return flag to true, and then store the value in the // parent's retptr. @@ -320,8 +320,8 @@ pub fn trans_check_expr(bcx: block, s: ~str) -> block { let _icx = bcx.insn_ctxt("trans_check_expr"); - let expr_str = s + ~" " + expr_to_str(pred_expr, bcx.ccx().sess.intr()) - + ~" failed"; + let expr_str = @(s + ~" " + expr_to_str(pred_expr, bcx.ccx().sess.intr()) + + ~" failed"); let Result {bcx, val} = { do with_scope_result(bcx, chk_expr.info(), ~"check") |bcx| { expr::trans_to_datum(bcx, pred_expr).to_result() @@ -329,7 +329,7 @@ pub fn trans_check_expr(bcx: block, }; let val = bool_to_i1(bcx, val); do with_cond(bcx, Not(bcx, val)) |bcx| { - trans_fail(bcx, Some(pred_expr.span), /*bad*/copy expr_str) + trans_fail(bcx, Some(pred_expr.span), expr_str) } } @@ -356,13 +356,13 @@ pub fn trans_fail_expr(bcx: block, ppaux::ty_to_str(tcx, arg_datum.ty)); } } - _ => return trans_fail(bcx, sp_opt, ~"explicit failure") + _ => trans_fail(bcx, sp_opt, @~"explicit failure") } } pub fn trans_fail(bcx: block, sp_opt: Option, - +fail_str: ~str) + fail_str: @~str) -> block { let _icx = bcx.insn_ctxt("trans_fail"); let V_fail_str = C_cstr(bcx.ccx(), fail_str); @@ -375,16 +375,15 @@ fn trans_fail_value(bcx: block, -> block { let _icx = bcx.insn_ctxt("trans_fail_value"); let ccx = bcx.ccx(); - let {V_filename, V_line} = match sp_opt { + let (V_filename, V_line) = match sp_opt { Some(sp) => { let sess = bcx.sess(); let loc = sess.parse_sess.cm.lookup_char_pos(sp.lo); - {V_filename: C_cstr(bcx.ccx(), /*bad*/copy loc.file.name), - V_line: loc.line as int} + (C_cstr(bcx.ccx(), @/*bad*/ copy loc.file.name), + loc.line as int) } None => { - {V_filename: C_cstr(bcx.ccx(), ~""), - V_line: 0} + (C_cstr(bcx.ccx(), @~""), 0) } }; let V_str = PointerCast(bcx, V_fail_str, T_ptr(T_i8())); @@ -403,7 +402,7 @@ pub fn trans_fail_bounds_check(bcx: block, sp: span, let loc = bcx.sess().parse_sess.cm.lookup_char_pos(sp.lo); let line = C_int(ccx, loc.line as int); - let filename_cstr = C_cstr(bcx.ccx(), /*bad*/copy loc.file.name); + let filename_cstr = C_cstr(bcx.ccx(), @/*bad*/copy loc.file.name); let filename = PointerCast(bcx, filename_cstr, T_ptr(T_i8())); let args = ~[filename, line, index, len]; diff --git a/src/librustc/middle/trans/datum.rs b/src/librustc/middle/trans/datum.rs index d301a31357be3..ba56eb56c0a9d 100644 --- a/src/librustc/middle/trans/datum.rs +++ b/src/librustc/middle/trans/datum.rs @@ -104,6 +104,7 @@ use core::uint; use core::vec; use syntax::parse::token::special_idents; +#[deriving_eq] pub enum CopyAction { INIT, DROP_EXISTING @@ -141,23 +142,23 @@ pub enum DatumMode { } pub impl DatumMode { - fn is_by_ref() -> bool { - match self { ByRef => true, ByValue => false } + fn is_by_ref(&self) -> bool { + match *self { ByRef => true, ByValue => false } } - fn is_by_value() -> bool { - match self { ByRef => false, ByValue => true } + fn is_by_value(&self) -> bool { + match *self { ByRef => false, ByValue => true } } } -pub impl DatumMode: cmp::Eq { +pub impl cmp::Eq for DatumMode { pure fn eq(&self, other: &DatumMode) -> bool { (*self) as uint == (*other as uint) } pure fn ne(&self, other: &DatumMode) -> bool { !(*self).eq(other) } } -pub impl DatumMode: to_bytes::IterBytes { +pub impl to_bytes::IterBytes for DatumMode { pure fn iter_bytes(&self, +lsb0: bool, f: to_bytes::Cb) { (*self as uint).iter_bytes(lsb0, f) } @@ -215,7 +216,7 @@ pub fn appropriate_mode(ty: ty::t) -> DatumMode { } pub impl Datum { - fn store_to(bcx: block, id: ast::node_id, + fn store_to(&self, bcx: block, id: ast::node_id, action: CopyAction, dst: ValueRef) -> block { /*! * @@ -230,7 +231,7 @@ pub impl Datum { } } - fn store_to_dest(bcx: block, id: ast::node_id, + fn store_to_dest(&self, bcx: block, id: ast::node_id, dest: expr::Dest) -> block { match dest { expr::Ignore => { @@ -242,7 +243,7 @@ pub impl Datum { } } - fn store_to_datum(bcx: block, id: ast::node_id, + fn store_to_datum(&self, bcx: block, id: ast::node_id, action: CopyAction, datum: Datum) -> block { debug!("store_to_datum(self=%s, action=%?, datum=%s)", self.to_str(bcx.ccx()), action, datum.to_str(bcx.ccx())); @@ -250,17 +251,20 @@ pub impl Datum { self.store_to(bcx, id, action, datum.val) } - fn move_to_datum(bcx: block, action: CopyAction, datum: Datum) -> block { + fn move_to_datum(&self, bcx: block, action: CopyAction, datum: Datum) + -> block { assert datum.mode.is_by_ref(); self.move_to(bcx, action, datum.val) } - fn copy_to_datum(bcx: block, action: CopyAction, datum: Datum) -> block { + fn copy_to_datum(&self, bcx: block, action: CopyAction, datum: Datum) + -> block { assert datum.mode.is_by_ref(); self.copy_to(bcx, action, datum.val) } - fn copy_to(bcx: block, action: CopyAction, dst: ValueRef) -> block { + fn copy_to(&self, bcx: block, action: CopyAction, dst: ValueRef) + -> block { /*! * * Copies the value into `dst`, which should be a pointer to a @@ -302,7 +306,7 @@ pub impl Datum { } } - fn copy_to_no_check(bcx: block, action: CopyAction, + fn copy_to_no_check(&self, bcx: block, action: CopyAction, dst: ValueRef) -> block { /*! @@ -332,7 +336,8 @@ pub impl Datum { // This works like copy_val, except that it deinitializes the source. // Since it needs to zero out the source, src also needs to be an lval. // - fn move_to(bcx: block, action: CopyAction, dst: ValueRef) -> block { + fn move_to(&self, bcx: block, action: CopyAction, dst: ValueRef) + -> block { let _icx = bcx.insn_ctxt("move_to"); let mut bcx = bcx; @@ -361,7 +366,7 @@ pub impl Datum { return bcx; } - fn add_clean(bcx: block) { + fn add_clean(&self, bcx: block) { /*! * * Schedules this datum for cleanup in `bcx`. The datum @@ -378,7 +383,7 @@ pub impl Datum { } } - fn cancel_clean(bcx: block) { + fn cancel_clean(&self, bcx: block) { if ty::type_needs_drop(bcx.tcx(), self.ty) { match self.source { RevokeClean => { @@ -395,7 +400,7 @@ pub impl Datum { } } - fn to_str(ccx: &crate_ctxt) -> ~str { + fn to_str(&self, ccx: &CrateContext) -> ~str { fmt!("Datum { val=%s, ty=%s, mode=%?, source=%? }", val_str(ccx.tn, self.val), ty_to_str(ccx.tcx, self.ty), @@ -403,7 +408,7 @@ pub impl Datum { self.source) } - fn to_value_datum(bcx: block) -> Datum { + fn to_value_datum(&self, bcx: block) -> Datum { /*! * * Yields a by-ref form of this datum. This may involve @@ -412,7 +417,7 @@ pub impl Datum { * it will not live longer than the current datum. */ match self.mode { - ByValue => self, + ByValue => *self, ByRef => { Datum {val: self.to_value_llval(bcx), mode: ByValue, ty: self.ty, source: RevokeClean} @@ -420,7 +425,7 @@ pub impl Datum { } } - fn to_value_llval(bcx: block) -> ValueRef { + fn to_value_llval(&self, bcx: block) -> ValueRef { /*! * * Yields the value itself. */ @@ -430,12 +435,18 @@ pub impl Datum { } else { match self.mode { ByValue => self.val, - ByRef => Load(bcx, self.val) + ByRef => { + if ty::type_is_bool(self.ty) { + LoadRangeAssert(bcx, self.val, 0, 2, lib::llvm::True) + } else { + Load(bcx, self.val) + } + } } } } - fn to_ref_datum(bcx: block) -> Datum { + fn to_ref_datum(&self, bcx: block) -> Datum { /*! * * Yields a by-ref form of this datum. This may involve @@ -444,7 +455,7 @@ pub impl Datum { * it will not live longer than the current datum. */ match self.mode { - ByRef => self, + ByRef => *self, ByValue => { Datum {val: self.to_ref_llval(bcx), mode: ByRef, ty: self.ty, source: RevokeClean} @@ -452,7 +463,7 @@ pub impl Datum { } } - fn to_ref_llval(bcx: block) -> ValueRef { + fn to_ref_llval(&self, bcx: block) -> ValueRef { match self.mode { ByRef => self.val, ByValue => { @@ -467,13 +478,13 @@ pub impl Datum { } } - fn appropriate_mode() -> DatumMode { + fn appropriate_mode(&self) -> DatumMode { /*! See the `appropriate_mode()` function */ appropriate_mode(self.ty) } - fn to_appropriate_llval(bcx: block) -> ValueRef { + fn to_appropriate_llval(&self, bcx: block) -> ValueRef { /*! * * Yields an llvalue with the `appropriate_mode()`. */ @@ -484,7 +495,7 @@ pub impl Datum { } } - fn to_appropriate_datum(bcx: block) -> Datum { + fn to_appropriate_datum(&self, bcx: block) -> Datum { /*! * * Yields a datum with the `appropriate_mode()`. */ @@ -495,7 +506,7 @@ pub impl Datum { } } - fn GEPi(bcx: block, + fn GEPi(&self, bcx: block, ixs: &[uint], ty: ty::t, source: DatumCleanup) @@ -509,7 +520,7 @@ pub impl Datum { } } - fn root(bcx: block, root_info: RootInfo) -> block { + fn root(&self, bcx: block, root_info: RootInfo) -> block { /*! * * In some cases, borrowck will decide that an @T/@[]/@str @@ -523,7 +534,8 @@ pub impl Datum { if bcx.sess().trace() { trans_trace( bcx, None, - fmt!("preserving until end of scope %d", root_info.scope)); + @fmt!("preserving until end of scope %d", + root_info.scope)); } let scratch = scratch_datum(bcx, self.ty, true); @@ -547,7 +559,7 @@ pub impl Datum { } } - fn perform_write_guard(bcx: block) -> block { + fn perform_write_guard(&self, bcx: block) -> block { // Create scratch space, but do not root it. let llval = match self.mode { ByValue => self.val, @@ -561,7 +573,7 @@ pub impl Datum { expr::Ignore) } - fn drop_val(bcx: block) -> block { + fn drop_val(&self, bcx: block) -> block { if !ty::type_needs_drop(bcx.tcx(), self.ty) { return bcx; } @@ -572,7 +584,7 @@ pub impl Datum { }; } - fn box_body(bcx: block) -> Datum { + fn box_body(&self, bcx: block) -> Datum { /*! * * This datum must represent an @T or ~T box. Returns a new @@ -592,7 +604,7 @@ pub impl Datum { Datum {val: body, ty: content_ty, mode: ByRef, source: ZeroMem} } - fn to_rptr(bcx: block) -> Datum { + fn to_rptr(&self, bcx: block) -> Datum { //! // // Returns a new datum of region-pointer type containing the @@ -610,7 +622,7 @@ pub impl Datum { mode: ByValue, source: RevokeClean} } - fn try_deref( + fn try_deref(&self, bcx: block, // block wherein to generate insn's expr_id: ast::node_id, // id of expr being deref'd derefs: uint, // number of times deref'd already @@ -648,11 +660,11 @@ pub impl Datum { if is_auto { // unsafe ptrs are not AUTO-derefable return (None, bcx); } else { - return (Some(deref_ptr(bcx, &self, mt.ty)), bcx); + return (Some(deref_ptr(bcx, self, mt.ty)), bcx); } } ty::ty_rptr(_, mt) => { - return (Some(deref_ptr(bcx, &self, mt.ty)), bcx); + return (Some(deref_ptr(bcx, self, mt.ty)), bcx); } ty::ty_enum(did, ref substs) => { // Check whether this enum is a newtype enum: @@ -687,7 +699,7 @@ pub impl Datum { // code in place here to do the right // thing if this change ever goes through. assert ty::type_is_immediate(ty); - (Some(Datum {ty: ty, ..self}), bcx) + (Some(Datum {ty: ty, ..*self}), bcx) } }; } @@ -725,7 +737,7 @@ pub impl Datum { // code in place here to do the right thing if this // change ever goes through. assert ty::type_is_immediate(ty); - (Some(Datum {ty: ty, ..self}), bcx) + (Some(Datum {ty: ty, ..*self}), bcx) } } } @@ -744,7 +756,7 @@ pub impl Datum { } } - fn deref(bcx: block, + fn deref(&self, bcx: block, expr: @ast::expr, // the expression whose value is being deref'd derefs: uint) -> DatumBlock { @@ -757,7 +769,7 @@ pub impl Datum { } } - fn autoderef(bcx: block, + fn autoderef(&self, bcx: block, expr_id: ast::node_id, max: uint) -> DatumBlock { @@ -767,7 +779,7 @@ pub impl Datum { expr_id, max, self.to_str(bcx.ccx())); let _indenter = indenter(); - let mut datum = self; + let mut datum = *self; let mut derefs = 0u; let mut bcx = bcx; while derefs < max { @@ -788,56 +800,56 @@ pub impl Datum { DatumBlock { bcx: bcx, datum: datum } } - fn get_base_and_len(bcx: block) -> (ValueRef, ValueRef) { + fn get_base_and_len(&self, bcx: block) -> (ValueRef, ValueRef) { tvec::get_base_and_len(bcx, self.to_appropriate_llval(bcx), self.ty) } - fn to_result(bcx: block) -> common::Result { + fn to_result(&self, bcx: block) -> common::Result { rslt(bcx, self.to_appropriate_llval(bcx)) } } pub impl DatumBlock { - fn unpack(bcx: &mut block) -> Datum { + fn unpack(&self, bcx: &mut block) -> Datum { *bcx = self.bcx; return self.datum; } - fn assert_by_ref() -> DatumBlock { + fn assert_by_ref(&self) -> DatumBlock { assert self.datum.mode.is_by_ref(); - self + *self } - fn drop_val() -> block { + fn drop_val(&self) -> block { self.datum.drop_val(self.bcx) } - fn store_to(id: ast::node_id, action: CopyAction, + fn store_to(&self, id: ast::node_id, action: CopyAction, dst: ValueRef) -> block { self.datum.store_to(self.bcx, id, action, dst) } - fn copy_to(action: CopyAction, dst: ValueRef) -> block { + fn copy_to(&self, action: CopyAction, dst: ValueRef) -> block { self.datum.copy_to(self.bcx, action, dst) } - fn move_to(action: CopyAction, dst: ValueRef) -> block { + fn move_to(&self, action: CopyAction, dst: ValueRef) -> block { self.datum.move_to(self.bcx, action, dst) } - fn to_value_llval() -> ValueRef { + fn to_value_llval(&self) -> ValueRef { self.datum.to_value_llval(self.bcx) } - fn to_result() -> common::Result { + fn to_result(&self) -> common::Result { rslt(self.bcx, self.datum.to_appropriate_llval(self.bcx)) } - fn ccx() -> @crate_ctxt { + fn ccx(&self) -> @CrateContext { self.bcx.ccx() } - fn tcx() -> ty::ctxt { + fn tcx(&self) -> ty::ctxt { self.bcx.tcx() } @@ -846,14 +858,3 @@ pub impl DatumBlock { } } -pub impl CopyAction : cmp::Eq { - pure fn eq(&self, other: &CopyAction) -> bool { - match ((*self), (*other)) { - (INIT, INIT) => true, - (DROP_EXISTING, DROP_EXISTING) => true, - (INIT, _) => false, - (DROP_EXISTING, _) => false, - } - } - pure fn ne(&self, other: &CopyAction) -> bool { !(*self).eq(other) } -} diff --git a/src/librustc/middle/trans/debuginfo.rs b/src/librustc/middle/trans/debuginfo.rs index 7c6f03cb364bc..8a28769756e6e 100644 --- a/src/librustc/middle/trans/debuginfo.rs +++ b/src/librustc/middle/trans/debuginfo.rs @@ -60,12 +60,12 @@ const DW_ATE_signed_char: int = 0x06; const DW_ATE_unsigned: int = 0x07; const DW_ATE_unsigned_char: int = 0x08; -fn llstr(s: ~str) -> ValueRef { - str::as_c_str(s, |sbuf| { +fn llstr(s: &str) -> ValueRef { + do str::as_c_str(s) |sbuf| { unsafe { - llvm::LLVMMDString(sbuf, str::len(s) as libc::c_uint) + llvm::LLVMMDString(sbuf, s.len() as libc::c_uint) } - }) + } } fn lltag(lltag: int) -> ValueRef { lli32(LLVMDebugVersion | lltag) @@ -79,10 +79,9 @@ fn lli64(val: int) -> ValueRef { fn lli1(bval: bool) -> ValueRef { C_i1(bval) } -fn llmdnode(elems: ~[ValueRef]) -> ValueRef { +fn llmdnode(elems: &[ValueRef]) -> ValueRef { unsafe { - llvm::LLVMMDNode(vec::raw::to_ptr(elems), - vec::len(elems) as libc::c_uint) + llvm::LLVMMDNode(vec::raw::to_ptr(elems), elems.len() as libc::c_uint) } } fn llunused() -> ValueRef { @@ -94,7 +93,7 @@ fn llnull() -> ValueRef { } } -fn add_named_metadata(cx: @crate_ctxt, name: ~str, val: ValueRef) { +fn add_named_metadata(cx: @CrateContext, name: ~str, val: ValueRef) { str::as_c_str(name, |sbuf| { unsafe { llvm::LLVMAddNamedMetadataOperand(cx.llmod, sbuf, val) @@ -104,16 +103,18 @@ fn add_named_metadata(cx: @crate_ctxt, name: ~str, val: ValueRef) { //////////////// -pub type debug_ctxt = { +pub struct DebugContext { llmetadata: metadata_cache, names: namegen, crate_file: ~str -}; +} -pub fn mk_ctxt(+crate: ~str, intr: @ident_interner) -> debug_ctxt { - {llmetadata: oldmap::HashMap(), - names: new_namegen(intr), - crate_file: crate} +pub fn mk_ctxt(+crate: ~str, intr: @ident_interner) -> DebugContext { + DebugContext { + llmetadata: oldmap::HashMap(), + names: new_namegen(intr), + crate_file: crate + } } fn update_cache(cache: metadata_cache, mdtag: int, val: debug_metadata) { @@ -125,34 +126,54 @@ fn update_cache(cache: metadata_cache, mdtag: int, val: debug_metadata) { cache.insert(mdtag, vec::append_one(existing, val)); } -type metadata = {node: ValueRef, data: T}; +struct Metadata { + node: ValueRef, + data: T +} -type file_md = {path: ~str}; -type compile_unit_md = {name: ~str}; -type subprogram_md = {id: ast::node_id}; -type local_var_md = {id: ast::node_id}; -type tydesc_md = {hash: uint}; -type block_md = {start: codemap::Loc, end: codemap::Loc}; -type argument_md = {id: ast::node_id}; -type retval_md = {id: ast::node_id}; +struct FileMetadata { + path: ~str +} +struct CompileUnitMetadata { + name: ~str +} +struct SubProgramMetadata { + id: ast::node_id +} +struct LocalVarMetadata { + id: ast::node_id +} +struct TyDescMetadata { + hash: uint +} +struct BlockMetadata { + start: codemap::Loc, + end: codemap::Loc +} +struct ArgumentMetadata { + id: ast::node_id +} +struct RetvalMetadata { + id: ast::node_id +} type metadata_cache = HashMap; enum debug_metadata { - file_metadata(@metadata), - compile_unit_metadata(@metadata), - subprogram_metadata(@metadata), - local_var_metadata(@metadata), - tydesc_metadata(@metadata), - block_metadata(@metadata), - argument_metadata(@metadata), - retval_metadata(@metadata), + file_metadata(@Metadata), + compile_unit_metadata(@Metadata), + subprogram_metadata(@Metadata), + local_var_metadata(@Metadata), + tydesc_metadata(@Metadata), + block_metadata(@Metadata), + argument_metadata(@Metadata), + retval_metadata(@Metadata), } -fn cast_safely(val: T) -> U { +fn cast_safely(val: T) -> U { unsafe { let val2 = val; - return cast::transmute(move val2); + return cast::transmute(val2); } } @@ -171,7 +192,7 @@ fn md_from_metadata(val: debug_metadata) -> T { } } -fn cached_metadata(cache: metadata_cache, +fn cached_metadata(cache: metadata_cache, mdtag: int, eq_fn: fn(md: T) -> bool) -> Option { @@ -189,12 +210,12 @@ fn cached_metadata(cache: metadata_cache, } } -fn create_compile_unit(cx: @crate_ctxt) -> @metadata { +fn create_compile_unit(cx: @CrateContext) -> @Metadata { unsafe { let cache = get_cache(cx); let crate_name = /*bad*/copy (/*bad*/copy cx.dbg_cx).get().crate_file; let tg = CompileUnitTag; - match cached_metadata::<@metadata>(cache, tg, + match cached_metadata::<@Metadata>(cache, tg, |md| md.data.name == crate_name) { option::Some(md) => return md, option::None => () @@ -205,7 +226,7 @@ fn create_compile_unit(cx: @crate_ctxt) -> @metadata { let unit_metadata = ~[lltag(tg), llunused(), lli32(DW_LANG_RUST), - llstr(copy crate_name), + llstr(crate_name), llstr(work_dir), llstr(env!("CFG_VERSION")), lli1(true), // deprecated: main compile unit @@ -215,14 +236,19 @@ fn create_compile_unit(cx: @crate_ctxt) -> @metadata { ]; let unit_node = llmdnode(unit_metadata); add_named_metadata(cx, ~"llvm.dbg.cu", unit_node); - let mdval = @{node: unit_node, data: {name: crate_name}}; + let mdval = @Metadata { + node: unit_node, + data: CompileUnitMetadata { + name: crate_name + } + }; update_cache(cache, tg, compile_unit_metadata(mdval)); return mdval; } } -fn get_cache(cx: @crate_ctxt) -> metadata_cache { +fn get_cache(cx: @CrateContext) -> metadata_cache { (/*bad*/copy cx.dbg_cx).get().llmetadata } @@ -235,10 +261,11 @@ fn get_file_path_and_dir(work_dir: &str, full_path: &str) -> (~str, ~str) { }, str::from_slice(work_dir)) } -fn create_file(cx: @crate_ctxt, +full_path: ~str) -> @metadata { +fn create_file(cx: @CrateContext, +full_path: ~str) + -> @Metadata { let cache = get_cache(cx);; let tg = FileDescriptorTag; - match cached_metadata::<@metadata>( + match cached_metadata::<@Metadata>( cache, tg, |md| md.data.path == full_path) { option::Some(md) => return md, option::None => () @@ -253,7 +280,12 @@ fn create_file(cx: @crate_ctxt, +full_path: ~str) -> @metadata { llstr(work_dir), unit_node]; let val = llmdnode(file_md); - let mdval = @{node: val, data: {path: full_path}}; + let mdval = @Metadata { + node: val, + data: FileMetadata { + path: full_path + } + }; update_cache(cache, tg, file_metadata(mdval)); return mdval; } @@ -262,7 +294,7 @@ fn line_from_span(cm: @codemap::CodeMap, sp: span) -> uint { cm.lookup_char_pos(sp.lo).line } -fn create_block(cx: block) -> @metadata { +fn create_block(cx: block) -> @Metadata { let cache = get_cache(cx.ccx()); let mut cx = cx; while cx.node_info.is_none() { @@ -277,7 +309,7 @@ fn create_block(cx: block) -> @metadata { let fname = /*bad*/copy start.file.name; let end = cx.sess().codemap.lookup_char_pos(sp.hi); let tg = LexicalBlockTag; - /*match cached_metadata::<@metadata>( + /*match cached_metadata::<@Metadata>( cache, tg, {|md| start == md.data.start && end == md.data.end}) { option::Some(md) { return md; } @@ -301,22 +333,28 @@ fn create_block(cx: block) -> @metadata { lli32(unique_id) ]; let val = llmdnode(lldata); - let mdval = @{node: val, data: {start: start, end: end}}; + let mdval = @Metadata { + node: val, + data: BlockMetadata { + start: start, + end: end + } + }; //update_cache(cache, tg, block_metadata(mdval)); return mdval; } -fn size_and_align_of(cx: @crate_ctxt, t: ty::t) -> (int, int) { +fn size_and_align_of(cx: @CrateContext, t: ty::t) -> (int, int) { let llty = type_of::type_of(cx, t); (machine::llsize_of_real(cx, llty) as int, machine::llalign_of_pref(cx, llty) as int) } -fn create_basic_type(cx: @crate_ctxt, t: ty::t, span: span) - -> @metadata { +fn create_basic_type(cx: @CrateContext, t: ty::t, span: span) + -> @Metadata { let cache = get_cache(cx); let tg = BasicTypeDescriptorTag; - match cached_metadata::<@metadata>( + match cached_metadata::<@Metadata>( cache, tg, |md| ty::type_id(t) == md.data.hash) { option::Some(md) => return md, option::None => () @@ -339,18 +377,23 @@ fn create_basic_type(cx: @crate_ctxt, t: ty::t, span: span) lli32(0), //XXX flags? lli32(encoding)]; let llnode = llmdnode(lldata); - let mdval = @{node: llnode, data: {hash: ty::type_id(t)}}; + let mdval = @Metadata { + node: llnode, + data: TyDescMetadata { + hash: ty::type_id(t) + } + }; update_cache(cache, tg, tydesc_metadata(mdval)); add_named_metadata(cx, ~"llvm.dbg.ty", llnode); return mdval; } -fn create_pointer_type(cx: @crate_ctxt, t: ty::t, span: span, - pointee: @metadata) - -> @metadata { +fn create_pointer_type(cx: @CrateContext, t: ty::t, span: span, + pointee: @Metadata) + -> @Metadata { let tg = PointerTypeTag; /*let cache = cx.llmetadata; - match cached_metadata::<@metadata>( + match cached_metadata::<@Metadata>( cache, tg, {|md| ty::hash_ty(t) == ty::hash_ty(md.data.hash)}) { option::Some(md) { return md; } option::None {} @@ -361,7 +404,12 @@ fn create_pointer_type(cx: @crate_ctxt, t: ty::t, span: span, //let cu_node = create_compile_unit(cx, fname); let llnode = create_derived_type(tg, file_node.node, ~"", 0, size * 8, align * 8, 0, pointee.node); - let mdval = @{node: llnode, data: {hash: ty::type_id(t)}}; + let mdval = @Metadata { + node: llnode, + data: TyDescMetadata { + hash: ty::type_id(t) + } + }; //update_cache(cache, tg, tydesc_metadata(mdval)); add_named_metadata(cx, ~"llvm.dbg.ty", llnode); return mdval; @@ -369,7 +417,7 @@ fn create_pointer_type(cx: @crate_ctxt, t: ty::t, span: span, struct StructCtxt { file: ValueRef, - name: ~str, + name: @~str, line: int, members: ~[ValueRef], total_size: int, @@ -378,17 +426,17 @@ struct StructCtxt { fn finish_structure(cx: @mut StructCtxt) -> ValueRef { return create_composite_type(StructureTypeTag, - /*bad*/copy cx.name, + *cx.name, cx.file, cx.line, cx.total_size, cx.align, 0, - option::None, - option::Some(/*bad*/copy cx.members)); + None, + Some(/*bad*/copy cx.members)); } -fn create_structure(file: @metadata, +name: ~str, line: int) +fn create_structure(file: @Metadata, name: @~str, line: int) -> @mut StructCtxt { let cx = @mut StructCtxt { file: file.node, @@ -401,7 +449,7 @@ fn create_structure(file: @metadata, +name: ~str, line: int) return cx; } -fn create_derived_type(type_tag: int, file: ValueRef, +name: ~str, line: int, +fn create_derived_type(type_tag: int, file: ValueRef, name: &str, line: int, size: int, align: int, offset: int, ty: ValueRef) -> ValueRef { let lldata = ~[lltag(type_tag), @@ -418,19 +466,19 @@ fn create_derived_type(type_tag: int, file: ValueRef, +name: ~str, line: int, } fn add_member(cx: @mut StructCtxt, - +name: ~str, + name: &str, line: int, size: int, align: int, ty: ValueRef) { cx.members.push(create_derived_type(MemberTag, cx.file, name, line, - size * 8, align * 8, cx.total_size, - ty)); + size * 8, align * 8, cx.total_size, + ty)); cx.total_size += size * 8; } -fn create_record(cx: @crate_ctxt, t: ty::t, fields: ~[ast::ty_field], - span: span) -> @metadata { +fn create_record(cx: @CrateContext, t: ty::t, fields: ~[ast::ty_field], + span: span) -> @Metadata { let fname = filename_from_span(cx, span); let file_node = create_file(cx, fname); let scx = create_structure(file_node, @@ -443,20 +491,25 @@ fn create_record(cx: @crate_ctxt, t: ty::t, fields: ~[ast::ty_field], let field_t = ty::get_field(cx.tcx, t, field.node.ident).mt.ty; let ty_md = create_ty(cx, field_t, field.node.mt.ty); let (size, align) = size_and_align_of(cx, field_t); - add_member(scx, cx.sess.str_of(field.node.ident), + add_member(scx, *cx.sess.str_of(field.node.ident), line_from_span(cx.sess.codemap, field.span) as int, size as int, align as int, ty_md.node); } - let mdval = @{node: finish_structure(scx), data:{hash: ty::type_id(t)}}; + let mdval = @Metadata { + node: finish_structure(scx), + data: TyDescMetadata { + hash: ty::type_id(t) + } + }; return mdval; } -fn create_boxed_type(cx: @crate_ctxt, outer: ty::t, _inner: ty::t, - span: span, boxed: @metadata) - -> @metadata { +fn create_boxed_type(cx: @CrateContext, outer: ty::t, _inner: ty::t, + span: span, boxed: @Metadata) + -> @Metadata { //let tg = StructureTypeTag; /*let cache = cx.llmetadata; - match cached_metadata::<@metadata>( + match cached_metadata::<@Metadata>( cache, tg, {|md| ty::hash_ty(outer) == ty::hash_ty(md.data.hash)}) { option::Some(md) { return md; } option::None {} @@ -466,20 +519,26 @@ fn create_boxed_type(cx: @crate_ctxt, outer: ty::t, _inner: ty::t, //let cu_node = create_compile_unit_metadata(cx, fname); let uint_t = ty::mk_uint(cx.tcx); let refcount_type = create_basic_type(cx, uint_t, span); - let scx = create_structure(file_node, ty_to_str(cx.tcx, outer), 0); + let scx = create_structure(file_node, + @/*bad*/ copy ty_to_str(cx.tcx, outer), 0); add_member(scx, ~"refcnt", 0, sys::size_of::() as int, sys::min_align_of::() as int, refcount_type.node); add_member(scx, ~"boxed", 0, 8, //XXX member_size_and_align(??) 8, //XXX just a guess boxed.node); let llnode = finish_structure(scx); - let mdval = @{node: llnode, data: {hash: ty::type_id(outer)}}; + let mdval = @Metadata { + node: llnode, + data: TyDescMetadata { + hash: ty::type_id(outer) + } + }; //update_cache(cache, tg, tydesc_metadata(mdval)); add_named_metadata(cx, ~"llvm.dbg.ty", llnode); return mdval; } -fn create_composite_type(type_tag: int, +name: ~str, file: ValueRef, +fn create_composite_type(type_tag: int, name: &str, file: ValueRef, line: int, size: int, align: int, offset: int, derived: Option, +members: Option<~[ValueRef]>) @@ -509,13 +568,14 @@ fn create_composite_type(type_tag: int, +name: ~str, file: ValueRef, return llmdnode(lldata); } -fn create_vec(cx: @crate_ctxt, vec_t: ty::t, elem_t: ty::t, +fn create_vec(cx: @CrateContext, vec_t: ty::t, elem_t: ty::t, vec_ty_span: codemap::span, elem_ty: @ast::Ty) - -> @metadata { + -> @Metadata { let fname = filename_from_span(cx, vec_ty_span); let file_node = create_file(cx, fname); let elem_ty_md = create_ty(cx, elem_t, elem_ty); - let scx = create_structure(file_node, ty_to_str(cx.tcx, vec_t), 0); + let scx = create_structure(file_node, + @/*bad*/ copy ty_to_str(cx.tcx, vec_t), 0); let size_t_type = create_basic_type(cx, ty::mk_uint(cx.tcx), vec_ty_span); add_member(scx, ~"fill", 0, sys::size_of::() as int, sys::min_align_of::() as int, size_t_type.node); @@ -525,18 +585,23 @@ fn create_vec(cx: @crate_ctxt, vec_t: ty::t, elem_t: ty::t, let (arr_size, arr_align) = size_and_align_of(cx, elem_t); let data_ptr = create_composite_type(ArrayTypeTag, ~"", file_node.node, 0, arr_size, arr_align, 0, - option::Some(elem_ty_md.node), - option::Some(~[subrange])); + Some(elem_ty_md.node), + Some(~[subrange])); add_member(scx, ~"data", 0, 0, // clang says the size should be 0 sys::min_align_of::() as int, data_ptr); let llnode = finish_structure(scx); - return @{node: llnode, data: {hash: ty::type_id(vec_t)}}; + @Metadata { + node: llnode, + data: TyDescMetadata { + hash: ty::type_id(vec_t) + } + } } -fn create_ty(_cx: @crate_ctxt, _t: ty::t, _ty: @ast::Ty) - -> @metadata { +fn create_ty(_cx: @CrateContext, _t: ty::t, _ty: @ast::Ty) + -> @Metadata { /*let cache = get_cache(cx); - match cached_metadata::<@metadata>( + match cached_metadata::<@Metadata>( cache, tg, {|md| t == md.data.hash}) { option::Some(md) { return md; } option::None {} @@ -555,7 +620,7 @@ fn create_ty(_cx: @crate_ctxt, _t: ty::t, _ty: @ast::Ty) fail!(); /* - fn t_to_ty(cx: crate_ctxt, t: ty::t, span: span) -> @ast::ty { + fn t_to_ty(cx: CrateContext, t: ty::t, span: span) -> @ast::ty { let ty = match ty::get(t).struct { ty::ty_nil { ast::ty_nil } ty::ty_bot { ast::ty_bot } @@ -637,11 +702,11 @@ fn create_ty(_cx: @crate_ctxt, _t: ty::t, _ty: @ast::Ty) */ } -fn filename_from_span(cx: @crate_ctxt, sp: codemap::span) -> ~str { +fn filename_from_span(cx: @CrateContext, sp: codemap::span) -> ~str { /*bad*/copy cx.sess.codemap.lookup_char_pos(sp.lo).file.name } -fn create_var(type_tag: int, context: ValueRef, +name: ~str, file: ValueRef, +fn create_var(type_tag: int, context: ValueRef, name: &str, file: ValueRef, line: int, ret_ty: ValueRef) -> ValueRef { let lldata = ~[lltag(type_tag), context, @@ -655,12 +720,12 @@ fn create_var(type_tag: int, context: ValueRef, +name: ~str, file: ValueRef, } pub fn create_local_var(bcx: block, local: @ast::local) - -> @metadata { + -> @Metadata { unsafe { let cx = bcx.ccx(); let cache = get_cache(cx); let tg = AutoVariableTag; - match cached_metadata::<@metadata>( + match cached_metadata::<@Metadata>( cache, tg, |md| md.data.id == local.node.id) { option::Some(md) => return md, option::None => () @@ -679,9 +744,14 @@ pub fn create_local_var(bcx: block, local: @ast::local) None => create_function(bcx.fcx).node, Some(_) => create_block(bcx).node }; - let mdnode = create_var(tg, context, cx.sess.str_of(name), + let mdnode = create_var(tg, context, *cx.sess.str_of(name), filemd.node, loc.line as int, tymd.node); - let mdval = @{node: mdnode, data: {id: local.node.id}}; + let mdval = @Metadata { + node: mdnode, + data: LocalVarMetadata { + id: local.node.id + } + }; update_cache(cache, AutoVariableTag, local_var_metadata(mdval)); let llptr = match bcx.fcx.lllocals.find(&local.node.id) { @@ -706,12 +776,12 @@ pub fn create_local_var(bcx: block, local: @ast::local) } pub fn create_arg(bcx: block, arg: ast::arg, sp: span) - -> Option<@metadata> { + -> Option<@Metadata> { unsafe { - let fcx = bcx.fcx, cx = fcx.ccx; + let fcx = bcx.fcx, cx = *fcx.ccx; let cache = get_cache(cx); let tg = ArgVariableTag; - match cached_metadata::<@metadata>( + match cached_metadata::<@Metadata>( cache, ArgVariableTag, |md| md.data.id == arg.id) { option::Some(md) => return Some(md), option::None => () @@ -728,12 +798,17 @@ pub fn create_arg(bcx: block, arg: ast::arg, sp: span) // XXX: This is wrong; it should work for multiple bindings. let mdnode = create_var(tg, context.node, - cx.sess.str_of(path.idents.last()), + *cx.sess.str_of(path.idents.last()), filemd.node, loc.line as int, tymd.node); - let mdval = @{node: mdnode, data: {id: arg.id}}; + let mdval = @Metadata { + node: mdnode, + data: ArgumentMetadata { + id: arg.id + } + }; update_cache(cache, tg, argument_metadata(mdval)); let llptr = match fcx.llargs.get(&arg.id) { @@ -769,8 +844,8 @@ pub fn update_source_pos(cx: block, s: span) { } } -pub fn create_function(fcx: fn_ctxt) -> @metadata { - let cx = fcx.ccx; +pub fn create_function(fcx: fn_ctxt) -> @Metadata { + let cx = *fcx.ccx; let dbg_cx = (/*bad*/copy cx.dbg_cx).get(); debug!("~~"); @@ -816,7 +891,7 @@ pub fn create_function(fcx: fn_ctxt) -> @metadata { log(debug, id); let cache = get_cache(cx); - match cached_metadata::<@metadata>( + match cached_metadata::<@Metadata>( cache, SubprogramTag, |md| md.data.id == id) { option::Some(md) => return md, option::None => () @@ -839,9 +914,9 @@ pub fn create_function(fcx: fn_ctxt) -> @metadata { let fn_metadata = ~[lltag(SubprogramTag), llunused(), file_node, - llstr(cx.sess.str_of(ident)), + llstr(*cx.sess.str_of(ident)), //XXX fully-qualified C++ name: - llstr(cx.sess.str_of(ident)), + llstr(*cx.sess.str_of(ident)), llstr(~""), //XXX MIPS name????? file_node, lli32(loc.line as int), @@ -860,7 +935,12 @@ pub fn create_function(fcx: fn_ctxt) -> @metadata { ]; let val = llmdnode(fn_metadata); add_named_metadata(cx, ~"llvm.dbg.sp", val); - let mdval = @{node: val, data: {id: id}}; + let mdval = @Metadata { + node: val, + data: SubProgramMetadata { + id: id + } + }; update_cache(cache, SubprogramTag, subprogram_metadata(mdval)); return mdval; diff --git a/src/librustc/middle/trans/expr.rs b/src/librustc/middle/trans/expr.rs index 6af6adbf68dca..a7b12d13d4e12 100644 --- a/src/librustc/middle/trans/expr.rs +++ b/src/librustc/middle/trans/expr.rs @@ -157,8 +157,8 @@ pub enum Dest { } impl Dest { - fn to_str(ccx: @crate_ctxt) -> ~str { - match self { + fn to_str(&self, ccx: @CrateContext) -> ~str { + match *self { SaveIn(v) => fmt!("SaveIn(%s)", val_str(ccx.tn, v)), Ignore => ~"Ignore" } @@ -409,16 +409,17 @@ fn trans_to_datum_unadjusted(bcx: block, expr: @ast::expr) -> DatumBlock { fn trans_rvalue_datum_unadjusted(bcx: block, expr: @ast::expr) -> DatumBlock { let _icx = bcx.insn_ctxt("trans_rvalue_datum_unadjusted"); - trace_span!(bcx, expr.span, shorten(bcx.expr_to_str(expr))); + trace_span!(bcx, expr.span, @shorten(bcx.expr_to_str(expr))); match expr.node { ast::expr_vstore(contents, ast::expr_vstore_box) | ast::expr_vstore(contents, ast::expr_vstore_mut_box) => { - return tvec::trans_uniq_or_managed_vstore(bcx, heap_shared, + return tvec::trans_uniq_or_managed_vstore(bcx, heap_managed, expr, contents); } ast::expr_vstore(contents, ast::expr_vstore_uniq) => { - return tvec::trans_uniq_or_managed_vstore(bcx, heap_exchange, + let heap = heap_for_unique(bcx, expr_ty(bcx, contents)); + return tvec::trans_uniq_or_managed_vstore(bcx, heap, expr, contents); } ast::expr_lit(lit) => { @@ -456,7 +457,7 @@ fn trans_rvalue_stmt_unadjusted(bcx: block, expr: @ast::expr) -> block { let mut bcx = bcx; let _icx = bcx.insn_ctxt("trans_rvalue_stmt"); - trace_span!(bcx, expr.span, shorten(bcx.expr_to_str(expr))); + trace_span!(bcx, expr.span, @shorten(bcx.expr_to_str(expr))); match expr.node { ast::expr_break(label_opt) => { @@ -491,11 +492,29 @@ fn trans_rvalue_stmt_unadjusted(bcx: block, expr: @ast::expr) -> block { ast::expr_swap(dst, src) => { let dst_datum = unpack_datum!(bcx, trans_lvalue(bcx, dst)); let src_datum = unpack_datum!(bcx, trans_lvalue(bcx, src)); - let scratch = scratch_datum(bcx, dst_datum.ty, false); - let bcx = dst_datum.move_to_datum(bcx, INIT, scratch); - let bcx = src_datum.move_to_datum(bcx, INIT, dst_datum); - return scratch.move_to_datum(bcx, INIT, src_datum); + // If the source and destination are the same, then don't swap. + // Avoids performing an overlapping memcpy + let dst_datum_ref = dst_datum.to_ref_llval(bcx); + let src_datum_ref = src_datum.to_ref_llval(bcx); + let cmp = ICmp(bcx, lib::llvm::IntEQ, + src_datum_ref, + dst_datum_ref); + + let swap_cx = base::sub_block(bcx, ~"swap"); + let next_cx = base::sub_block(bcx, ~"next"); + + CondBr(bcx, cmp, next_cx.llbb, swap_cx.llbb); + + let scratch = scratch_datum(swap_cx, dst_datum.ty, false); + + let swap_cx = dst_datum.move_to_datum(swap_cx, INIT, scratch); + let swap_cx = src_datum.move_to_datum(swap_cx, INIT, dst_datum); + let swap_cx = scratch.move_to_datum(swap_cx, INIT, src_datum); + + Br(swap_cx, next_cx.llbb); + + return next_cx; } ast::expr_assign_op(op, dst, src) => { return trans_assign_op(bcx, expr, op, dst, src); @@ -519,7 +538,7 @@ fn trans_rvalue_dps_unadjusted(bcx: block, expr: @ast::expr, let _icx = bcx.insn_ctxt("trans_rvalue_dps_unadjusted"); let tcx = bcx.tcx(); - trace_span!(bcx, expr.span, shorten(bcx.expr_to_str(expr))); + trace_span!(bcx, expr.span, @shorten(bcx.expr_to_str(expr))); match expr.node { ast::expr_paren(e) => { @@ -710,7 +729,7 @@ fn trans_lvalue_unadjusted(bcx: block, expr: @ast::expr) -> DatumBlock { debug!("trans_lvalue(expr=%s)", bcx.expr_to_str(expr)); let _indenter = indenter(); - trace_span!(bcx, expr.span, shorten(bcx.expr_to_str(expr))); + trace_span!(bcx, expr.span, @shorten(bcx.expr_to_str(expr))); let unrooted_datum = unpack_datum!(bcx, unrooted(bcx, expr)); @@ -926,10 +945,10 @@ pub fn trans_local_var(bcx: block, def: ast::def) -> Datum { } } ast::def_arg(nid, _, _) => { - take_local(bcx, bcx.fcx.llargs, nid) + take_local(bcx, *bcx.fcx.llargs, nid) } ast::def_local(nid, _) | ast::def_binding(nid, _) => { - take_local(bcx, bcx.fcx.lllocals, nid) + take_local(bcx, *bcx.fcx.lllocals, nid) } ast::def_self(nid, _) => { let self_info: ValSelfData = match bcx.fcx.llself { @@ -1254,10 +1273,12 @@ fn trans_unary_datum(bcx: block, immediate_rvalue_bcx(bcx, llneg, un_ty) } ast::box(_) => { - trans_boxed_expr(bcx, un_ty, sub_expr, sub_ty, heap_shared) + trans_boxed_expr(bcx, un_ty, sub_expr, sub_ty, + heap_managed) } ast::uniq(_) => { - trans_boxed_expr(bcx, un_ty, sub_expr, sub_ty, heap_exchange) + let heap = heap_for_unique(bcx, un_ty); + trans_boxed_expr(bcx, un_ty, sub_expr, sub_ty, heap) } ast::deref => { bcx.sess().bug(~"deref expressions should have been \ @@ -1272,7 +1293,7 @@ fn trans_unary_datum(bcx: block, contents_ty: ty::t, heap: heap) -> DatumBlock { let _icx = bcx.insn_ctxt("trans_boxed_expr"); - let {bcx, box: bx, body} = + let base::MallocResult { bcx, box: bx, body } = base::malloc_general(bcx, contents_ty, heap); add_clean_free(bcx, bx, heap); let bcx = trans_into(bcx, contents, SaveIn(body)); @@ -1565,34 +1586,34 @@ fn trans_imm_cast(bcx: block, expr: @ast::expr, let s_in = k_in == cast_integral && ty::type_is_signed(t_in); let newval = - match {in: k_in, out: k_out} { - {in: cast_integral, out: cast_integral} => { + match (k_in, k_out) { + (cast_integral, cast_integral) => { int_cast(bcx, ll_t_out, ll_t_in, llexpr, s_in) } - {in: cast_float, out: cast_float} => { + (cast_float, cast_float) => { float_cast(bcx, ll_t_out, ll_t_in, llexpr) } - {in: cast_integral, out: cast_float} => { + (cast_integral, cast_float) => { if s_in { SIToFP(bcx, llexpr, ll_t_out) } else { UIToFP(bcx, llexpr, ll_t_out) } } - {in: cast_float, out: cast_integral} => { + (cast_float, cast_integral) => { if ty::type_is_signed(t_out) { FPToSI(bcx, llexpr, ll_t_out) } else { FPToUI(bcx, llexpr, ll_t_out) } } - {in: cast_integral, out: cast_pointer} => { + (cast_integral, cast_pointer) => { IntToPtr(bcx, llexpr, ll_t_out) } - {in: cast_pointer, out: cast_integral} => { + (cast_pointer, cast_integral) => { PtrToInt(bcx, llexpr, ll_t_out) } - {in: cast_pointer, out: cast_pointer} => { + (cast_pointer, cast_pointer) => { PointerCast(bcx, llexpr, ll_t_out) } - {in: cast_enum, out: cast_integral} | - {in: cast_enum, out: cast_float} => { + (cast_enum, cast_integral) | + (cast_enum, cast_float) => { let bcx = bcx; let in_tid = match ty::get(t_in).sty { ty::ty_enum(did, _) => did, diff --git a/src/librustc/middle/trans/foreign.rs b/src/librustc/middle/trans/foreign.rs index 718f41de00ada..3d1d70abefda1 100644 --- a/src/librustc/middle/trans/foreign.rs +++ b/src/librustc/middle/trans/foreign.rs @@ -47,23 +47,23 @@ fn abi_info(arch: session::arch) -> cabi::ABIInfo { } } -pub fn link_name(ccx: @crate_ctxt, i: @ast::foreign_item) -> ~str { - match attr::first_attr_value_str_by_name(i.attrs, ~"link_name") { +pub fn link_name(ccx: @CrateContext, i: @ast::foreign_item) -> @~str { + match attr::first_attr_value_str_by_name(i.attrs, ~"link_name") { None => ccx.sess.str_of(i.ident), - option::Some(ref ln) => (/*bad*/copy *ln) + Some(ln) => ln, } } -type c_stack_tys = { +struct c_stack_tys { arg_tys: ~[TypeRef], ret_ty: TypeRef, ret_def: bool, bundle_ty: TypeRef, shim_fn_ty: TypeRef, fn_ty: cabi::FnType -}; +} -fn c_arg_and_ret_lltys(ccx: @crate_ctxt, +fn c_arg_and_ret_lltys(ccx: @CrateContext, id: ast::node_id) -> (~[TypeRef], TypeRef, ty::t) { match ty::get(ty::node_id_to_type(ccx.tcx, id)).sty { ty::ty_bare_fn(ref fn_ty) => { @@ -75,7 +75,7 @@ fn c_arg_and_ret_lltys(ccx: @crate_ctxt, } } -fn c_stack_tys(ccx: @crate_ctxt, +fn c_stack_tys(ccx: @CrateContext, id: ast::node_id) -> @c_stack_tys { let (llargtys, llretty, ret_ty) = c_arg_and_ret_lltys(ccx, id); // XXX: Bad copy. @@ -83,7 +83,7 @@ fn c_stack_tys(ccx: @crate_ctxt, let ret_def = !ty::type_is_bot(ret_ty) && !ty::type_is_nil(ret_ty); let fn_ty = abi_info(ccx.sess.targ_cfg.arch). compute_info(llargtys, llretty, ret_def); - return @{ + return @c_stack_tys { arg_tys: llargtys, ret_ty: llretty, ret_def: ret_def, @@ -99,7 +99,7 @@ type shim_arg_builder = fn(bcx: block, tys: @c_stack_tys, type shim_ret_builder = fn(bcx: block, tys: @c_stack_tys, llargbundle: ValueRef, llretval: ValueRef); -fn build_shim_fn_(ccx: @crate_ctxt, +fn build_shim_fn_(ccx: @CrateContext, +shim_name: ~str, llbasefn: ValueRef, tys: @c_stack_tys, @@ -136,7 +136,7 @@ type wrap_arg_builder = fn(bcx: block, tys: @c_stack_tys, type wrap_ret_builder = fn(bcx: block, tys: @c_stack_tys, llargbundle: ValueRef); -fn build_wrap_fn_(ccx: @crate_ctxt, +fn build_wrap_fn_(ccx: @CrateContext, tys: @c_stack_tys, llshimfn: ValueRef, llwrapfn: ValueRef, @@ -201,13 +201,13 @@ fn build_wrap_fn_(ccx: @crate_ctxt, // stack pointer appropriately to avoid a round of copies. (In fact, the shim // function itself is unnecessary). We used to do this, in fact, and will // perhaps do so in the future. -pub fn trans_foreign_mod(ccx: @crate_ctxt, +pub fn trans_foreign_mod(ccx: @CrateContext, foreign_mod: ast::foreign_mod, abi: ast::foreign_abi) { let _icx = ccx.insn_ctxt("foreign::trans_foreign_mod"); - fn build_shim_fn(ccx: @crate_ctxt, + fn build_shim_fn(ccx: @CrateContext, foreign_item: @ast::foreign_item, tys: @c_stack_tys, cc: lib::llvm::CallConv) -> ValueRef { @@ -228,29 +228,29 @@ pub fn trans_foreign_mod(ccx: @crate_ctxt, } let lname = link_name(ccx, foreign_item); - let llbasefn = base_fn(ccx, copy lname, tys, cc); + let llbasefn = base_fn(ccx, *lname, tys, cc); // Name the shim function let shim_name = lname + ~"__c_stack_shim"; return build_shim_fn_(ccx, shim_name, llbasefn, tys, cc, build_args, build_ret); } - fn base_fn(ccx: @crate_ctxt, +lname: ~str, tys: @c_stack_tys, + fn base_fn(ccx: @CrateContext, lname: &str, tys: @c_stack_tys, cc: lib::llvm::CallConv) -> ValueRef { // Declare the "prototype" for the base function F: do tys.fn_ty.decl_fn |fnty| { - decl_fn(ccx.llmod, /*bad*/copy lname, cc, fnty) + decl_fn(ccx.llmod, lname, cc, fnty) } } // FIXME (#2535): this is very shaky and probably gets ABIs wrong all // over the place - fn build_direct_fn(ccx: @crate_ctxt, decl: ValueRef, + fn build_direct_fn(ccx: @CrateContext, decl: ValueRef, item: @ast::foreign_item, tys: @c_stack_tys, cc: lib::llvm::CallConv) { let fcx = new_fn_ctxt(ccx, ~[], decl, None); let bcx = top_scope_block(fcx, None), lltop = bcx.llbb; - let llbasefn = base_fn(ccx, link_name(ccx, item), tys, cc); + let llbasefn = base_fn(ccx, *link_name(ccx, item), tys, cc); let ty = ty::lookup_item_type(ccx.tcx, ast_util::local_def(item.id)).ty; let args = vec::from_fn(ty::ty_fn_args(ty).len(), |i| { @@ -264,7 +264,7 @@ pub fn trans_foreign_mod(ccx: @crate_ctxt, finish_fn(fcx, lltop); } - fn build_wrap_fn(ccx: @crate_ctxt, + fn build_wrap_fn(ccx: @CrateContext, tys: @c_stack_tys, llshimfn: ValueRef, llwrapfn: ValueRef) { @@ -328,19 +328,19 @@ pub fn trans_foreign_mod(ccx: @crate_ctxt, } } -pub fn trans_intrinsic(ccx: @crate_ctxt, +pub fn trans_intrinsic(ccx: @CrateContext, decl: ValueRef, item: @ast::foreign_item, +path: ast_map::path, - +substs: param_substs, + substs: @param_substs, ref_id: Option) { - debug!("trans_intrinsic(item.ident=%s)", ccx.sess.str_of(item.ident)); + debug!("trans_intrinsic(item.ident=%s)", *ccx.sess.str_of(item.ident)); // XXX: Bad copy. let fcx = new_fn_ctxt_w_id(ccx, path, decl, item.id, None, Some(copy substs), Some(item.span)); let mut bcx = top_scope_block(fcx, None), lltop = bcx.llbb; - match ccx.sess.str_of(item.ident) { + match *ccx.sess.str_of(item.ident) { ~"atomic_cxchg" => { let old = AtomicCmpXchg(bcx, get_param(decl, first_real_arg), @@ -838,7 +838,7 @@ pub fn trans_intrinsic(ccx: @crate_ctxt, finish_fn(fcx, lltop); } -pub fn trans_foreign_fn(ccx: @crate_ctxt, +pub fn trans_foreign_fn(ccx: @CrateContext, +path: ast_map::path, decl: &ast::fn_decl, body: &ast::blk, @@ -846,7 +846,7 @@ pub fn trans_foreign_fn(ccx: @crate_ctxt, id: ast::node_id) { let _icx = ccx.insn_ctxt("foreign::build_foreign_fn"); - fn build_rust_fn(ccx: @crate_ctxt, +path: ast_map::path, + fn build_rust_fn(ccx: @CrateContext, +path: ast_map::path, decl: &ast::fn_decl, body: &ast::blk, id: ast::node_id) -> ValueRef { let _icx = ccx.insn_ctxt("foreign::foreign::build_rust_fn"); @@ -862,7 +862,7 @@ pub fn trans_foreign_fn(ccx: @crate_ctxt, return llfndecl; } - fn build_shim_fn(ccx: @crate_ctxt, +path: ast_map::path, + fn build_shim_fn(ccx: @CrateContext, +path: ast_map::path, llrustfn: ValueRef, tys: @c_stack_tys) -> ValueRef { let _icx = ccx.insn_ctxt("foreign::foreign::build_shim_fn"); @@ -899,7 +899,7 @@ pub fn trans_foreign_fn(ccx: @crate_ctxt, build_args, build_ret); } - fn build_wrap_fn(ccx: @crate_ctxt, llshimfn: ValueRef, + fn build_wrap_fn(ccx: @CrateContext, llshimfn: ValueRef, llwrapfn: ValueRef, tys: @c_stack_tys) { let _icx = ccx.insn_ctxt("foreign::foreign::build_wrap_fn"); @@ -932,7 +932,7 @@ pub fn trans_foreign_fn(ccx: @crate_ctxt, build_wrap_fn(ccx, llshimfn, llwrapfn, tys) } -pub fn register_foreign_fn(ccx: @crate_ctxt, +pub fn register_foreign_fn(ccx: @CrateContext, sp: span, +path: ast_map::path, node_id: ast::node_id, @@ -950,7 +950,7 @@ pub fn register_foreign_fn(ccx: @crate_ctxt, } } -fn abi_of_foreign_fn(ccx: @crate_ctxt, i: @ast::foreign_item) +fn abi_of_foreign_fn(ccx: @CrateContext, i: @ast::foreign_item) -> ast::foreign_abi { match attr::first_attr_value_str_by_name(i.attrs, ~"abi") { None => match ccx.tcx.items.get(&i.id) { diff --git a/src/librustc/middle/trans/glue.rs b/src/librustc/middle/trans/glue.rs index 08d22a4fbf0e2..cd3a14b69e71d 100644 --- a/src/librustc/middle/trans/glue.rs +++ b/src/librustc/middle/trans/glue.rs @@ -37,8 +37,8 @@ pub fn trans_free(cx: block, v: ValueRef) -> block { expr::Ignore) } -pub fn trans_unique_free(cx: block, v: ValueRef) -> block { - let _icx = cx.insn_ctxt("trans_unique_free"); +pub fn trans_exchange_free(cx: block, v: ValueRef) -> block { + let _icx = cx.insn_ctxt("trans_exchange_free"); callee::trans_rtcall_or_lang_call( cx, cx.tcx().lang_items.exchange_free_fn(), @@ -142,7 +142,7 @@ pub fn free_ty_immediate(bcx: block, v: ValueRef, t: ty::t) -> block { } } -pub fn lazily_emit_all_tydesc_glue(ccx: @crate_ctxt, +pub fn lazily_emit_all_tydesc_glue(ccx: @CrateContext, static_ti: @mut tydesc_info) { lazily_emit_tydesc_glue(ccx, abi::tydesc_field_take_glue, static_ti); lazily_emit_tydesc_glue(ccx, abi::tydesc_field_drop_glue, static_ti); @@ -204,7 +204,7 @@ pub fn simplified_glue_type(tcx: ty::ctxt, field: uint, t: ty::t) -> ty::t { return t; } -pub pure fn cast_glue(ccx: @crate_ctxt, ti: @mut tydesc_info, v: ValueRef) +pub pure fn cast_glue(ccx: @CrateContext, ti: @mut tydesc_info, v: ValueRef) -> ValueRef { unsafe { let llfnty = type_of_glue_fn(ccx, ti.ty); @@ -212,7 +212,7 @@ pub pure fn cast_glue(ccx: @crate_ctxt, ti: @mut tydesc_info, v: ValueRef) } } -pub fn lazily_emit_simplified_tydesc_glue(ccx: @crate_ctxt, +pub fn lazily_emit_simplified_tydesc_glue(ccx: @CrateContext, field: uint, ti: @mut tydesc_info) -> bool { let _icx = ccx.insn_ctxt("lazily_emit_simplified_tydesc_glue"); @@ -239,7 +239,7 @@ pub fn lazily_emit_simplified_tydesc_glue(ccx: @crate_ctxt, } -pub fn lazily_emit_tydesc_glue(ccx: @crate_ctxt, +pub fn lazily_emit_tydesc_glue(ccx: @CrateContext, field: uint, ti: @mut tydesc_info) { let _icx = ccx.insn_ctxt("lazily_emit_tydesc_glue"); @@ -636,7 +636,7 @@ pub fn incr_refcnt_of_boxed(cx: block, box_ptr: ValueRef) { // Chooses the addrspace for newly declared types. -pub fn declare_tydesc_addrspace(ccx: @crate_ctxt, t: ty::t) -> addrspace { +pub fn declare_tydesc_addrspace(ccx: @CrateContext, t: ty::t) -> addrspace { if !ty::type_needs_drop(ccx.tcx, t) { return default_addrspace; } else if ty::type_is_immediate(t) { @@ -650,11 +650,11 @@ pub fn declare_tydesc_addrspace(ccx: @crate_ctxt, t: ty::t) -> addrspace { } // Generates the declaration for (but doesn't emit) a type descriptor. -pub fn declare_tydesc(ccx: @crate_ctxt, t: ty::t) -> @mut tydesc_info { +pub fn declare_tydesc(ccx: @CrateContext, t: ty::t) -> @mut tydesc_info { let _icx = ccx.insn_ctxt("declare_tydesc"); // If emit_tydescs already ran, then we shouldn't be creating any new // tydescs. - assert !ccx.finished_tydescs; + assert !*ccx.finished_tydescs; let llty = type_of(ccx, t); @@ -698,7 +698,7 @@ pub fn declare_tydesc(ccx: @crate_ctxt, t: ty::t) -> @mut tydesc_info { pub type glue_helper = fn@(block, ValueRef, ty::t); -pub fn declare_generic_glue(ccx: @crate_ctxt, t: ty::t, llfnty: TypeRef, +pub fn declare_generic_glue(ccx: @CrateContext, t: ty::t, llfnty: TypeRef, +name: ~str) -> ValueRef { let _icx = ccx.insn_ctxt("declare_generic_glue"); let name = name; @@ -717,7 +717,7 @@ pub fn declare_generic_glue(ccx: @crate_ctxt, t: ty::t, llfnty: TypeRef, return llfn; } -pub fn make_generic_glue_inner(ccx: @crate_ctxt, +pub fn make_generic_glue_inner(ccx: @CrateContext, t: ty::t, llfn: ValueRef, helper: glue_helper) @@ -742,7 +742,7 @@ pub fn make_generic_glue_inner(ccx: @crate_ctxt, return llfn; } -pub fn make_generic_glue(ccx: @crate_ctxt, t: ty::t, llfn: ValueRef, +pub fn make_generic_glue(ccx: @CrateContext, t: ty::t, llfn: ValueRef, helper: glue_helper, name: ~str) -> ValueRef { let _icx = ccx.insn_ctxt("make_generic_glue"); @@ -758,10 +758,10 @@ pub fn make_generic_glue(ccx: @crate_ctxt, t: ty::t, llfn: ValueRef, return llval; } -pub fn emit_tydescs(ccx: @crate_ctxt) { +pub fn emit_tydescs(ccx: @CrateContext) { let _icx = ccx.insn_ctxt("emit_tydescs"); // As of this point, allow no more tydescs to be created. - ccx.finished_tydescs = true; + *ccx.finished_tydescs = true; for ccx.tydescs.each_value |&val| { let glue_fn_ty = T_ptr(T_generic_glue_fn(ccx)); let ti = val; diff --git a/src/librustc/middle/trans/inline.rs b/src/librustc/middle/trans/inline.rs index c094db4ecca1f..43369aa9d755e 100644 --- a/src/librustc/middle/trans/inline.rs +++ b/src/librustc/middle/trans/inline.rs @@ -27,7 +27,7 @@ use syntax::ast_util::local_def; // `translate` will be true if this function is allowed to translate the // item and false otherwise. Currently, this parameter is set to false when // translating default methods. -pub fn maybe_instantiate_inline(ccx: @crate_ctxt, fn_id: ast::def_id, +pub fn maybe_instantiate_inline(ccx: @CrateContext, fn_id: ast::def_id, translate: bool) -> ast::def_id { let _icx = ccx.insn_ctxt("maybe_instantiate_inline"); @@ -86,8 +86,11 @@ pub fn maybe_instantiate_inline(ccx: @crate_ctxt, fn_id: ast::def_id, csearch::found(ast::ii_method(impl_did, mth)) => { ccx.stats.n_inlines += 1; ccx.external.insert(fn_id, Some(mth.id)); - let {bounds: impl_bnds, region_param: _, ty: _} = - ty::lookup_item_type(ccx.tcx, impl_did); + let ty::ty_param_bounds_and_ty { + bounds: impl_bnds, + region_param: _, + ty: _ + } = ty::lookup_item_type(ccx.tcx, impl_did); if translate && (*impl_bnds).len() + mth.tps.len() == 0u { let llfn = get_item_val(ccx, mth.id); let path = vec::append( diff --git a/src/librustc/middle/trans/machine.rs b/src/librustc/middle/trans/machine.rs index 75e494f7bfcd9..bfada859bc2c9 100644 --- a/src/librustc/middle/trans/machine.rs +++ b/src/librustc/middle/trans/machine.rs @@ -13,60 +13,8 @@ use middle::trans::common::*; use middle::trans::type_of; -use middle::ty::field; use middle::ty; - -use syntax::parse::token::special_idents; - -// Creates a simpler, size-equivalent type. The resulting type is guaranteed -// to have (a) the same size as the type that was passed in; (b) to be non- -// recursive. This is done by replacing all boxes in a type with boxed unit -// types. -// This should reduce all pointers to some simple pointer type, to -// ensure that we don't recurse endlessly when computing the size of a -// nominal type that has pointers to itself in it. -pub fn simplify_type(tcx: ty::ctxt, typ: ty::t) -> ty::t { - fn nilptr(tcx: ty::ctxt) -> ty::t { - ty::mk_ptr(tcx, ty::mt {ty: ty::mk_nil(tcx), mutbl: ast::m_imm}) - } - fn simplifier(tcx: ty::ctxt, typ: ty::t) -> ty::t { - match ty::get(typ).sty { - ty::ty_box(_) | ty::ty_opaque_box | ty::ty_uniq(_) | - ty::ty_evec(_, ty::vstore_uniq) | ty::ty_evec(_, ty::vstore_box) | - ty::ty_estr(ty::vstore_uniq) | ty::ty_estr(ty::vstore_box) | - ty::ty_ptr(_) | ty::ty_rptr(*) => nilptr(tcx), - - ty::ty_bare_fn(*) | // FIXME(#4804) Bare fn repr - ty::ty_closure(*) => ty::mk_tup(tcx, ~[nilptr(tcx), nilptr(tcx)]), - - ty::ty_evec(_, ty::vstore_slice(_)) | - ty::ty_estr(ty::vstore_slice(_)) => { - ty::mk_tup(tcx, ~[nilptr(tcx), ty::mk_int(tcx)]) - } - // Reduce a class type to a record type in which all the fields are - // simplified - ty::ty_struct(did, ref substs) => { - let simpl_fields = (if ty::ty_dtor(tcx, did).is_present() { - // remember the drop flag - ~[field { - ident: special_idents::dtor, - mt: ty::mt {ty: ty::mk_u8(tcx), mutbl: ast::m_mutbl} - }] } - else { ~[] }) + - do ty::lookup_struct_fields(tcx, did).map |f| { - let t = ty::lookup_field_type(tcx, did, f.id, substs); - field { - ident: f.ident, - mt: ty::mt {ty: simplify_type(tcx, t), mutbl: ast::m_const - }} - }; - ty::mk_rec(tcx, simpl_fields) - } - _ => typ - } - } - ty::fold_ty(tcx, typ, |t| simplifier(tcx, t)) -} +use util::ppaux::ty_to_str; // ______________________________________________________________________ // compute sizeof / alignof @@ -85,7 +33,7 @@ pub type tag_metrics = { }; // Returns the number of bytes clobbered by a Store to this type. -pub fn llsize_of_store(cx: @crate_ctxt, t: TypeRef) -> uint { +pub fn llsize_of_store(cx: @CrateContext, t: TypeRef) -> uint { unsafe { return llvm::LLVMStoreSizeOfType(cx.td.lltd, t) as uint; } @@ -93,7 +41,7 @@ pub fn llsize_of_store(cx: @crate_ctxt, t: TypeRef) -> uint { // Returns the number of bytes between successive elements of type T in an // array of T. This is the "ABI" size. It includes any ABI-mandated padding. -pub fn llsize_of_alloc(cx: @crate_ctxt, t: TypeRef) -> uint { +pub fn llsize_of_alloc(cx: @CrateContext, t: TypeRef) -> uint { unsafe { return llvm::LLVMABISizeOfType(cx.td.lltd, t) as uint; } @@ -107,7 +55,7 @@ pub fn llsize_of_alloc(cx: @crate_ctxt, t: TypeRef) -> uint { // that LLVM *does* distinguish between e.g. a 1-bit value and an 8-bit value // at the codegen level! In general you should prefer `llbitsize_of_real` // below. -pub fn llsize_of_real(cx: @crate_ctxt, t: TypeRef) -> uint { +pub fn llsize_of_real(cx: @CrateContext, t: TypeRef) -> uint { unsafe { let nbits = llvm::LLVMSizeOfTypeInBits(cx.td.lltd, t) as uint; if nbits & 7u != 0u { @@ -120,14 +68,14 @@ pub fn llsize_of_real(cx: @crate_ctxt, t: TypeRef) -> uint { } /// Returns the "real" size of the type in bits. -pub fn llbitsize_of_real(cx: @crate_ctxt, t: TypeRef) -> uint { +pub fn llbitsize_of_real(cx: @CrateContext, t: TypeRef) -> uint { unsafe { llvm::LLVMSizeOfTypeInBits(cx.td.lltd, t) as uint } } /// Returns the size of the type as an LLVM constant integer value. -pub fn llsize_of(cx: @crate_ctxt, t: TypeRef) -> ValueRef { +pub fn llsize_of(cx: @CrateContext, t: TypeRef) -> ValueRef { // Once upon a time, this called LLVMSizeOf, which does a // getelementptr(1) on a null pointer and casts to an int, in // order to obtain the type size as a value without requiring the @@ -141,7 +89,7 @@ pub fn llsize_of(cx: @crate_ctxt, t: TypeRef) -> ValueRef { // Returns the "default" size of t (see above), or 1 if the size would // be zero. This is important for things like vectors that expect // space to be consumed. -pub fn nonzero_llsize_of(cx: @crate_ctxt, t: TypeRef) -> ValueRef { +pub fn nonzero_llsize_of(cx: @CrateContext, t: TypeRef) -> ValueRef { if llbitsize_of_real(cx, t) == 0 { unsafe { llvm::LLVMConstInt(cx.int_type, 1, False) } } else { @@ -153,7 +101,7 @@ pub fn nonzero_llsize_of(cx: @crate_ctxt, t: TypeRef) -> ValueRef { // The preffered alignment may be larger than the alignment used when // packing the type into structs. This will be used for things like // allocations inside a stack frame, which LLVM has a free hand in. -pub fn llalign_of_pref(cx: @crate_ctxt, t: TypeRef) -> uint { +pub fn llalign_of_pref(cx: @CrateContext, t: TypeRef) -> uint { unsafe { return llvm::LLVMPreferredAlignmentOfType(cx.td.lltd, t) as uint; } @@ -162,7 +110,7 @@ pub fn llalign_of_pref(cx: @crate_ctxt, t: TypeRef) -> uint { // Returns the minimum alignment of a type required by the plattform. // This is the alignment that will be used for struct fields, arrays, // and similar ABI-mandated things. -pub fn llalign_of_min(cx: @crate_ctxt, t: TypeRef) -> uint { +pub fn llalign_of_min(cx: @CrateContext, t: TypeRef) -> uint { unsafe { return llvm::LLVMABIAlignmentOfType(cx.td.lltd, t) as uint; } @@ -171,7 +119,7 @@ pub fn llalign_of_min(cx: @crate_ctxt, t: TypeRef) -> uint { // Returns the "default" alignment of t, which is calculated by casting // null to a record containing a single-bit followed by a t value, then // doing gep(0,1) to get at the trailing (and presumably padded) t cell. -pub fn llalign_of(cx: @crate_ctxt, t: TypeRef) -> ValueRef { +pub fn llalign_of(cx: @CrateContext, t: TypeRef) -> ValueRef { unsafe { return llvm::LLVMConstIntCast( lib::llvm::llvm::LLVMAlignOf(t), cx.int_type, False); @@ -179,28 +127,41 @@ pub fn llalign_of(cx: @crate_ctxt, t: TypeRef) -> ValueRef { } // Computes the size of the data part of an enum. -pub fn static_size_of_enum(cx: @crate_ctxt, t: ty::t) -> uint { - if cx.enum_sizes.contains_key(&t) { return cx.enum_sizes.get(&t); } +pub fn static_size_of_enum(cx: @CrateContext, t: ty::t) -> uint { + if cx.enum_sizes.contains_key(&t) { + return cx.enum_sizes.get(&t); + } + + debug!("static_size_of_enum %s", ty_to_str(cx.tcx, t)); + match ty::get(t).sty { - ty::ty_enum(tid, ref substs) => { - // Compute max(variant sizes). - let mut max_size = 0u; - let variants = ty::enum_variants(cx.tcx, tid); - for vec::each(*variants) |variant| { - let tup_ty = simplify_type( - cx.tcx, - ty::mk_tup(cx.tcx, /*bad*/copy variant.args)); - // Perform any type parameter substitutions. - let tup_ty = ty::subst(cx.tcx, substs, tup_ty); - // Here we possibly do a recursive call. - let this_size = - llsize_of_real(cx, type_of::type_of(cx, tup_ty)); - if max_size < this_size { max_size = this_size; } + ty::ty_enum(tid, ref substs) => { + // Compute max(variant sizes). + let mut max_size = 0; + let variants = ty::enum_variants(cx.tcx, tid); + for variants.each |variant| { + if variant.args.len() == 0 { + loop; + } + + let lltypes = variant.args.map(|&variant_arg| { + let substituted = ty::subst(cx.tcx, substs, variant_arg); + type_of::sizing_type_of(cx, substituted) + }); + + debug!("static_size_of_enum: variant %s type %s", + *cx.tcx.sess.str_of(variant.name), + ty_str(cx.tn, T_struct(lltypes))); + + let this_size = llsize_of_real(cx, T_struct(lltypes)); + if max_size < this_size { + max_size = this_size; + } + } + cx.enum_sizes.insert(t, max_size); + return max_size; } - cx.enum_sizes.insert(t, max_size); - return max_size; - } - _ => cx.sess.bug(~"static_size_of_enum called on non-enum") + _ => cx.sess.bug(~"static_size_of_enum called on non-enum") } } diff --git a/src/librustc/middle/trans/meth.rs b/src/librustc/middle/trans/meth.rs index a79a24ba4606f..02ea29f915d69 100644 --- a/src/librustc/middle/trans/meth.rs +++ b/src/librustc/middle/trans/meth.rs @@ -50,7 +50,7 @@ for non-monomorphized methods only. Other methods will be generated once they are invoked with specific type parameters, see `trans::base::lval_static_fn()` or `trans::base::monomorphic_fn()`. */ -pub fn trans_impl(ccx: @crate_ctxt, +path: path, name: ast::ident, +pub fn trans_impl(ccx: @CrateContext, +path: path, name: ast::ident, methods: ~[@ast::method], tps: ~[ast::ty_param], self_ty: Option, id: ast::node_id) { let _icx = ccx.insn_ctxt("impl::trans_impl"); @@ -66,7 +66,7 @@ pub fn trans_impl(ccx: @crate_ctxt, +path: path, name: ast::ident, match self_ty { None => param_substs_opt = None, Some(self_ty) => { - param_substs_opt = Some(param_substs { + param_substs_opt = Some(@param_substs { tys: ~[], vtables: None, bounds: @~[], @@ -96,10 +96,10 @@ Translates a (possibly monomorphized) method body. - `llfn`: the LLVM ValueRef for the method - `impl_id`: the node ID of the impl this method is inside */ -pub fn trans_method(ccx: @crate_ctxt, +pub fn trans_method(ccx: @CrateContext, +path: path, method: &ast::method, - +param_substs: Option, + param_substs: Option<@param_substs>, base_self_ty: Option, llfn: ValueRef, impl_id: ast::def_id) { @@ -118,7 +118,7 @@ pub fn trans_method(ccx: @crate_ctxt, } let self_ty = match param_substs { None => self_ty, - Some(param_substs {tys: ref tys, _}) => { + Some(@param_substs {tys: ref tys, _}) => { ty::subst_tps(ccx.tcx, *tys, None, self_ty) } }; @@ -247,7 +247,7 @@ pub fn trans_method_callee(bcx: block, bound_num: b }) => { match bcx.fcx.param_substs { - Some(ref substs) => { + Some(substs) => { let vtbl = find_vtable(bcx.tcx(), substs, p, b); trans_monomorphized_callee(bcx, callee_id, self, mentry, trait_id, off, vtbl) @@ -322,7 +322,7 @@ pub fn trans_static_method_callee(bcx: block, } }; debug!("trans_static_method_callee: method_id=%?, callee_id=%?, \ - name=%s", method_id, callee_id, ccx.sess.str_of(mname)); + name=%s", method_id, callee_id, *ccx.sess.str_of(mname)); let vtbls = resolve_vtables_in_fn_ctxt( bcx.fcx, ccx.maps.vtable_map.get(&callee_id)); @@ -359,7 +359,7 @@ pub fn method_from_methods(ms: ~[@ast::method], name: ast::ident) ms.find(|m| m.ident == name).map(|m| local_def(m.id)) } -pub fn method_with_name(ccx: @crate_ctxt, impl_id: ast::def_id, +pub fn method_with_name(ccx: @CrateContext, impl_id: ast::def_id, name: ast::ident) -> ast::def_id { if impl_id.crate == ast::local_crate { match ccx.tcx.items.get(&impl_id.node) { @@ -376,7 +376,7 @@ pub fn method_with_name(ccx: @crate_ctxt, impl_id: ast::def_id, } } -pub fn method_with_name_or_default(ccx: @crate_ctxt, impl_id: ast::def_id, +pub fn method_with_name_or_default(ccx: @CrateContext, impl_id: ast::def_id, name: ast::ident) -> ast::def_id { if impl_id.crate == ast::local_crate { match ccx.tcx.items.get(&impl_id.node) { @@ -410,7 +410,7 @@ pub fn method_with_name_or_default(ccx: @crate_ctxt, impl_id: ast::def_id, } } -pub fn method_ty_param_count(ccx: @crate_ctxt, m_id: ast::def_id, +pub fn method_ty_param_count(ccx: @CrateContext, m_id: ast::def_id, i_id: ast::def_id) -> uint { debug!("method_ty_param_count: m_id: %?, i_id: %?", m_id, i_id); if m_id.crate == ast::local_crate { @@ -559,9 +559,10 @@ pub fn combine_impl_and_methods_origins(bcx: block, // rcvr + method bounds. let ccx = bcx.ccx(), tcx = bcx.tcx(); let n_m_tps = method_ty_param_count(ccx, mth_did, impl_did); - let {bounds: r_m_bounds, _} = ty::lookup_item_type(tcx, mth_did); + let ty::ty_param_bounds_and_ty {bounds: r_m_bounds, _} + = ty::lookup_item_type(tcx, mth_did); let n_r_m_tps = r_m_bounds.len(); // rcvr + method tps - let m_boundss = vec::view(*r_m_bounds, n_r_m_tps - n_m_tps, n_r_m_tps); + let m_boundss = vec::slice(*r_m_bounds, n_r_m_tps - n_m_tps, n_r_m_tps); // Flatten out to find the number of vtables the method expects. let m_vtables = ty::count_traits_and_supertraits(tcx, m_boundss); @@ -745,7 +746,7 @@ pub fn trans_trait_callee_from_llval(bcx: block, }; } -pub fn vtable_id(ccx: @crate_ctxt, +pub fn vtable_id(ccx: @CrateContext, +origin: typeck::vtable_origin) -> mono_id { match origin { @@ -774,7 +775,7 @@ pub fn vtable_id(ccx: @crate_ctxt, } } -pub fn get_vtable(ccx: @crate_ctxt, +pub fn get_vtable(ccx: @CrateContext, +origin: typeck::vtable_origin) -> ValueRef { // XXX: Bad copy. @@ -790,14 +791,14 @@ pub fn get_vtable(ccx: @crate_ctxt, } } -pub fn make_vtable(ccx: @crate_ctxt, ptrs: ~[ValueRef]) -> ValueRef { +pub fn make_vtable(ccx: @CrateContext, ptrs: ~[ValueRef]) -> ValueRef { unsafe { let _icx = ccx.insn_ctxt("impl::make_vtable"); let tbl = C_struct(ptrs); - let vt_gvar = - str::as_c_str(ccx.sess.str_of((ccx.names)(~"vtable")), |buf| { + let vtable = ccx.sess.str_of((ccx.names)(~"vtable")); + let vt_gvar = do str::as_c_str(*vtable) |buf| { llvm::LLVMAddGlobal(ccx.llmod, val_ty(tbl), buf) - }); + }; llvm::LLVMSetInitializer(vt_gvar, tbl); llvm::LLVMSetGlobalConstant(vt_gvar, lib::llvm::True); lib::llvm::SetLinkage(vt_gvar, lib::llvm::InternalLinkage); @@ -805,7 +806,7 @@ pub fn make_vtable(ccx: @crate_ctxt, ptrs: ~[ValueRef]) -> ValueRef { } } -pub fn make_impl_vtable(ccx: @crate_ctxt, +pub fn make_impl_vtable(ccx: @CrateContext, impl_id: ast::def_id, substs: ~[ty::t], vtables: typeck::vtable_res) @@ -825,11 +826,11 @@ pub fn make_impl_vtable(ccx: @crate_ctxt, ty::mk_bare_fn(tcx, copy im.fty)); if (*im.tps).len() > 0u || ty::type_has_self(fty) { debug!("(making impl vtable) method has self or type params: %s", - tcx.sess.str_of(im.ident)); + *tcx.sess.str_of(im.ident)); C_null(T_ptr(T_nil())) } else { debug!("(making impl vtable) adding method to vtable: %s", - tcx.sess.str_of(im.ident)); + *tcx.sess.str_of(im.ident)); let mut m_id = method_with_name(ccx, impl_id, im.ident); if has_tps { // If the method is in another crate, need to make an inlined @@ -838,8 +839,9 @@ pub fn make_impl_vtable(ccx: @crate_ctxt, // XXX: Set impl ID here? m_id = inline::maybe_instantiate_inline(ccx, m_id, true); } - monomorphize::monomorphic_fn(ccx, m_id, substs, - Some(vtables), None, None).val + let (val, _) = monomorphize::monomorphic_fn(ccx, m_id, substs, + Some(vtables), None, None); + val } else if m_id.crate == ast::local_crate { get_item_val(ccx, m_id.node) } else { @@ -873,10 +875,10 @@ pub fn trans_trait_cast(bcx: block, let mut llboxdest = GEPi(bcx, lldest, [0u, 1u]); if bcx.tcx().legacy_boxed_traits.contains_key(&id) { // Allocate an @ box and store the value into it - let {bcx: new_bcx, box: llbox, body: body} = + let MallocResult {bcx: new_bcx, box: llbox, body: body} = malloc_boxed(bcx, v_ty); bcx = new_bcx; - add_clean_free(bcx, llbox, heap_shared); + add_clean_free(bcx, llbox, heap_managed); bcx = expr::trans_into(bcx, val, SaveIn(body)); revoke_clean(bcx, llbox); diff --git a/src/librustc/middle/trans/monomorphize.rs b/src/librustc/middle/trans/monomorphize.rs index b09a41f2b7f06..9be316b30223a 100644 --- a/src/librustc/middle/trans/monomorphize.rs +++ b/src/librustc/middle/trans/monomorphize.rs @@ -36,13 +36,13 @@ use syntax::ast_map::{path, path_mod, path_name}; use syntax::ast_util::local_def; use syntax::parse::token::special_idents; -pub fn monomorphic_fn(ccx: @crate_ctxt, +pub fn monomorphic_fn(ccx: @CrateContext, fn_id: ast::def_id, real_substs: ~[ty::t], vtables: Option, impl_did_opt: Option, ref_id: Option) -> - {val: ValueRef, must_cast: bool} { + (ValueRef, bool) { let _icx = ccx.insn_ctxt("monomorphic_fn"); let mut must_cast = false; let substs = vec::map(real_substs, |t| { @@ -73,7 +73,7 @@ pub fn monomorphic_fn(ccx: @crate_ctxt, Some(val) => { debug!("leaving monomorphic fn %s", ty::item_path_str(ccx.tcx, fn_id)); - return {val: val, must_cast: must_cast}; + return (val, must_cast); } None => () } @@ -94,8 +94,7 @@ pub fn monomorphic_fn(ccx: @crate_ctxt, => (pt, i.ident, i.span), ast_map::node_foreign_item(*) => { // Foreign externs don't have to be monomorphized. - return {val: get_item_val(ccx, fn_id.node), - must_cast: true}; + return (get_item_val(ccx, fn_id.node), true); } ast_map::node_dtor(_, dtor, _, pt) => (pt, special_idents::dtor, dtor.span), @@ -138,16 +137,16 @@ pub fn monomorphic_fn(ccx: @crate_ctxt, let depth = option::get_or_default(ccx.monomorphizing.find(&fn_id), 0u); // Random cut-off -- code that needs to instantiate the same function - // recursively more than ten times can probably safely be assumed to be + // recursively more than thirty times can probably safely be assumed to be // causing an infinite expansion. - if depth > 10 { + if depth > 30 { ccx.sess.span_fatal( span, ~"overly deep expansion of inlined function"); } ccx.monomorphizing.insert(fn_id, depth + 1); let pt = vec::append(/*bad*/copy *pt, - ~[path_name((ccx.names)(ccx.sess.str_of(name)))]); + ~[path_name((ccx.names)(*ccx.sess.str_of(name)))]); let s = mangle_exported_name(ccx, /*bad*/copy pt, mono_ty); let mk_lldecl = || { @@ -156,7 +155,7 @@ pub fn monomorphic_fn(ccx: @crate_ctxt, lldecl }; - let psubsts = Some(param_substs { + let psubsts = Some(@param_substs { tys: substs, vtables: vtables, bounds: tpt.bounds, @@ -261,7 +260,7 @@ pub fn monomorphic_fn(ccx: @crate_ctxt, ccx.monomorphizing.insert(fn_id, depth); debug!("leaving monomorphic fn %s", ty::item_path_str(ccx.tcx, fn_id)); - {val: lldecl, must_cast: must_cast} + (lldecl, must_cast) } pub fn normalize_for_monomorphization(tcx: ty::ctxt, @@ -319,7 +318,7 @@ pub fn normalize_for_monomorphization(tcx: ty::ctxt, } } -pub fn make_mono_id(ccx: @crate_ctxt, item: ast::def_id, substs: ~[ty::t], +pub fn make_mono_id(ccx: @CrateContext, item: ast::def_id, substs: ~[ty::t], vtables: Option, impl_did_opt: Option, param_uses: Option<~[type_use::type_uses]>) -> mono_id { diff --git a/src/librustc/middle/trans/reflect.rs b/src/librustc/middle/trans/reflect.rs index 83fcc17583703..1fa97325313b6 100644 --- a/src/librustc/middle/trans/reflect.rs +++ b/src/librustc/middle/trans/reflect.rs @@ -45,7 +45,7 @@ pub impl Reflector { C_int(self.bcx.ccx(), i) } - fn c_slice(&mut self, +s: ~str) -> ValueRef { + fn c_slice(&mut self, s: @~str) -> ValueRef { // We're careful to not use first class aggregates here because that // will kick us off fast isel. (Issue #4352.) let bcx = self.bcx; diff --git a/src/librustc/middle/trans/shape.rs b/src/librustc/middle/trans/shape.rs index 0a64d5c637e4e..72e2369111d65 100644 --- a/src/librustc/middle/trans/shape.rs +++ b/src/librustc/middle/trans/shape.rs @@ -40,7 +40,7 @@ pub struct Ctxt { pad2: u32 } -pub fn mk_global(ccx: @crate_ctxt, +pub fn mk_global(ccx: @CrateContext, name: ~str, llval: ValueRef, internal: bool) diff --git a/src/librustc/middle/trans/tvec.rs b/src/librustc/middle/trans/tvec.rs index e103ae1559325..df89647321ab4 100644 --- a/src/librustc/middle/trans/tvec.rs +++ b/src/librustc/middle/trans/tvec.rs @@ -81,15 +81,17 @@ pub fn alloc_raw(bcx: block, unit_ty: ty::t, let vecbodyty = ty::mk_mut_unboxed_vec(bcx.tcx(), unit_ty); let vecsize = Add(bcx, alloc, llsize_of(ccx, ccx.opaque_vec_type)); - let {bcx, box: bx, body} = + let MallocResult {bcx, box: bx, body} = base::malloc_general_dyn(bcx, vecbodyty, heap, vecsize); Store(bcx, fill, GEPi(bcx, body, [0u, abi::vec_elt_fill])); Store(bcx, alloc, GEPi(bcx, body, [0u, abi::vec_elt_alloc])); + base::maybe_set_managed_unique_rc(bcx, bx, heap); return rslt(bcx, bx); } + pub fn alloc_uniq_raw(bcx: block, unit_ty: ty::t, fill: ValueRef, alloc: ValueRef) -> Result { - alloc_raw(bcx, unit_ty, fill, alloc, heap_exchange) + alloc_raw(bcx, unit_ty, fill, alloc, heap_for_unique(bcx, unit_ty)) } pub fn alloc_vec(bcx: block, @@ -144,7 +146,7 @@ pub struct VecTypes { } pub impl VecTypes { - fn to_str(ccx: @crate_ctxt) -> ~str { + fn to_str(&self, ccx: @CrateContext) -> ~str { fmt!("VecTypes {vec_ty=%s, unit_ty=%s, llunit_ty=%s, llunit_size=%s}", ty_to_str(ccx.tcx, self.vec_ty), ty_to_str(ccx.tcx, self.unit_ty), @@ -263,7 +265,7 @@ pub fn trans_lit_str(bcx: block, unsafe { let bytes = str_lit.len() + 1; // count null-terminator too let llbytes = C_uint(bcx.ccx(), bytes); - let llcstr = C_cstr(bcx.ccx(), /*bad*/copy *str_lit); + let llcstr = C_cstr(bcx.ccx(), str_lit); let llcstr = llvm::LLVMConstPointerCast(llcstr, T_ptr(T_i8())); Store(bcx, @@ -299,7 +301,7 @@ pub fn trans_uniq_or_managed_vstore(bcx: block, ast::expr_lit(@codemap::spanned { node: ast::lit_str(s), _ }) => { - let llptrval = C_cstr(bcx.ccx(), copy *s); + let llptrval = C_cstr(bcx.ccx(), s); let llptrval = PointerCast(bcx, llptrval, T_ptr(T_i8())); let llsizeval = C_uint(bcx.ccx(), s.len()); let typ = ty::mk_estr(bcx.tcx(), ty::vstore_uniq); @@ -317,13 +319,14 @@ pub fn trans_uniq_or_managed_vstore(bcx: block, _ => {} } } - heap_shared => {} + heap_managed | heap_managed_unique => {} } let vt = vec_types_from_expr(bcx, vstore_expr); let count = elements_required(bcx, content_expr); let Result {bcx, val} = alloc_vec(bcx, vt.unit_ty, count, heap); + add_clean_free(bcx, val, heap); let dataptr = get_dataptr(bcx, get_bodyptr(bcx, val)); @@ -362,7 +365,7 @@ pub fn write_content(bcx: block, SaveIn(lldest) => { let bytes = s.len() + 1; // copy null-terminator too let llbytes = C_uint(bcx.ccx(), bytes); - let llcstr = C_cstr(bcx.ccx(), /*bad*/copy *s); + let llcstr = C_cstr(bcx.ccx(), s); base::call_memcpy(bcx, lldest, llcstr, llbytes); return bcx; } diff --git a/src/librustc/middle/trans/type_of.rs b/src/librustc/middle/trans/type_of.rs index 972f702c18a81..8275db8cdb292 100644 --- a/src/librustc/middle/trans/type_of.rs +++ b/src/librustc/middle/trans/type_of.rs @@ -20,7 +20,7 @@ use util::ppaux; use std::oldmap::HashMap; use syntax::ast; -pub fn type_of_explicit_arg(ccx: @crate_ctxt, arg: ty::arg) -> TypeRef { +pub fn type_of_explicit_arg(ccx: @CrateContext, arg: ty::arg) -> TypeRef { let llty = type_of(ccx, arg.ty); match ty::resolved_mode(ccx.tcx, arg.mode) { ast::by_val => llty, @@ -35,12 +35,12 @@ pub fn type_of_explicit_arg(ccx: @crate_ctxt, arg: ty::arg) -> TypeRef { } } -pub fn type_of_explicit_args(ccx: @crate_ctxt, +pub fn type_of_explicit_args(ccx: @CrateContext, inputs: &[ty::arg]) -> ~[TypeRef] { inputs.map(|arg| type_of_explicit_arg(ccx, *arg)) } -pub fn type_of_fn(cx: @crate_ctxt, inputs: &[ty::arg], +pub fn type_of_fn(cx: @CrateContext, inputs: &[ty::arg], output: ty::t) -> TypeRef { unsafe { let mut atys: ~[TypeRef] = ~[]; @@ -58,7 +58,7 @@ pub fn type_of_fn(cx: @crate_ctxt, inputs: &[ty::arg], } // Given a function type and a count of ty params, construct an llvm type -pub fn type_of_fn_from_ty(cx: @crate_ctxt, fty: ty::t) -> TypeRef { +pub fn type_of_fn_from_ty(cx: @CrateContext, fty: ty::t) -> TypeRef { match ty::get(fty).sty { ty::ty_closure(ref f) => type_of_fn(cx, f.sig.inputs, f.sig.output), ty::ty_bare_fn(ref f) => type_of_fn(cx, f.sig.inputs, f.sig.output), @@ -68,7 +68,7 @@ pub fn type_of_fn_from_ty(cx: @crate_ctxt, fty: ty::t) -> TypeRef { } } -pub fn type_of_non_gc_box(cx: @crate_ctxt, t: ty::t) -> TypeRef { +pub fn type_of_non_gc_box(cx: @CrateContext, t: ty::t) -> TypeRef { assert !ty::type_needs_infer(t); let t_norm = ty::normalize_ty(cx.tcx, t); @@ -89,7 +89,96 @@ pub fn type_of_non_gc_box(cx: @crate_ctxt, t: ty::t) -> TypeRef { } } -pub fn type_of(cx: @crate_ctxt, t: ty::t) -> TypeRef { +// A "sizing type" is an LLVM type, the size and alignment of which are +// guaranteed to be equivalent to what you would get out of `type_of()`. It's +// useful because: +// +// (1) It may be cheaper to compute the sizing type than the full type if all +// you're interested in is the size and/or alignment; +// +// (2) It won't make any recursive calls to determine the structure of the +// type behind pointers. This can help prevent infinite loops for +// recursive types. For example, `static_size_of_enum()` relies on this +// behavior. + +pub fn sizing_type_of(cx: @CrateContext, t: ty::t) -> TypeRef { + if cx.llsizingtypes.contains_key(&t) { + return cx.llsizingtypes.get(&t); + } + + let llsizingty = match ty::get(t).sty { + ty::ty_nil | ty::ty_bot => T_nil(), + ty::ty_bool => T_bool(), + ty::ty_int(t) => T_int_ty(cx, t), + ty::ty_uint(t) => T_uint_ty(cx, t), + ty::ty_float(t) => T_float_ty(cx, t), + + ty::ty_estr(ty::vstore_uniq) | + ty::ty_estr(ty::vstore_box) | + ty::ty_evec(_, ty::vstore_uniq) | + ty::ty_evec(_, ty::vstore_box) | + ty::ty_box(*) | + ty::ty_opaque_box | + ty::ty_uniq(*) | + ty::ty_ptr(*) | + ty::ty_rptr(*) | + ty::ty_type | + ty::ty_opaque_closure_ptr(*) => T_ptr(T_i8()), + + ty::ty_estr(ty::vstore_slice(*)) | + ty::ty_evec(_, ty::vstore_slice(*)) => { + T_struct(~[T_ptr(T_i8()), T_ptr(T_i8())]) + } + + // FIXME(#4804) Bare fn repr + ty::ty_bare_fn(*) => T_struct(~[T_ptr(T_i8()), T_ptr(T_i8())]), + ty::ty_closure(*) => T_struct(~[T_ptr(T_i8()), T_ptr(T_i8())]), + ty::ty_trait(_, _, vstore) => T_opaque_trait(cx, vstore), + + ty::ty_estr(ty::vstore_fixed(size)) => T_array(T_i8(), size), + ty::ty_evec(mt, ty::vstore_fixed(size)) => { + T_array(sizing_type_of(cx, mt.ty), size) + } + + ty::ty_unboxed_vec(mt) => T_vec(cx, sizing_type_of(cx, mt.ty)), + + ty::ty_tup(ref elems) => { + T_struct(elems.map(|&t| sizing_type_of(cx, t))) + } + + ty::ty_rec(ref fields) => { + T_struct(fields.map(|f| sizing_type_of(cx, f.mt.ty))) + } + + ty::ty_struct(def_id, ref substs) => { + let fields = ty::lookup_struct_fields(cx.tcx, def_id); + let lltype = T_struct(fields.map(|field| { + let field_type = ty::lookup_field_type(cx.tcx, + def_id, + field.id, + substs); + sizing_type_of(cx, field_type) + })); + if ty::ty_dtor(cx.tcx, def_id).is_present() { + T_struct(~[lltype, T_i8()]) + } else { + lltype + } + } + + ty::ty_enum(def_id, _) => T_struct(enum_body_types(cx, def_id, t)), + + ty::ty_self | ty::ty_infer(*) | ty::ty_param(*) | ty::ty_err(*) => { + cx.tcx.sess.bug(~"fictitious type in sizing_type_of()") + } + }; + + cx.llsizingtypes.insert(t, llsizingty); + llsizingty +} + +// NB: If you update this, be sure to update `sizing_type_of()` as well. +pub fn type_of(cx: @CrateContext, t: ty::t) -> TypeRef { debug!("type_of %?: %?", t, ty::get(t)); // Check the cache. @@ -236,29 +325,38 @@ pub fn type_of(cx: @crate_ctxt, t: ty::t) -> TypeRef { return llty; } -pub fn fill_type_of_enum(cx: @crate_ctxt, did: ast::def_id, t: ty::t, - llty: TypeRef) { - - debug!("type_of_enum %?: %?", t, ty::get(t)); - - let lltys = { - let univar = ty::enum_is_univariant(cx.tcx, did); +pub fn enum_body_types(cx: @CrateContext, did: ast::def_id, t: ty::t) + -> ~[TypeRef] { + let univar = ty::enum_is_univariant(cx.tcx, did); + if !univar { let size = machine::static_size_of_enum(cx, t); - if !univar { - ~[T_enum_discrim(cx), T_array(T_i8(), size)] - } - else { - ~[T_array(T_i8(), size)] + ~[T_enum_discrim(cx), T_array(T_i8(), size)] + } + else { + // Use the actual fields, so we get the alignment right. + match ty::get(t).sty { + ty::ty_enum(_, ref substs) => { + do ty::enum_variants(cx.tcx, did)[0].args.map |&field_ty| { + sizing_type_of(cx, ty::subst(cx.tcx, substs, field_ty)) + } + } + _ => cx.sess.bug(~"enum is not an enum") } - }; + } +} - common::set_struct_body(llty, lltys); +pub fn fill_type_of_enum(cx: @CrateContext, + did: ast::def_id, + t: ty::t, + llty: TypeRef) { + debug!("type_of_enum %?: %?", t, ty::get(t)); + common::set_struct_body(llty, enum_body_types(cx, did, t)); } // Want refinements! (Or case classes, I guess pub enum named_ty { a_struct, an_enum } -pub fn llvm_type_name(cx: @crate_ctxt, +pub fn llvm_type_name(cx: @CrateContext, what: named_ty, did: ast::def_id, tps: ~[ty::t]) -> ~str { @@ -278,7 +376,7 @@ pub fn llvm_type_name(cx: @crate_ctxt, ); } -pub fn type_of_dtor(ccx: @crate_ctxt, self_ty: ty::t) -> TypeRef { +pub fn type_of_dtor(ccx: @CrateContext, self_ty: ty::t) -> TypeRef { unsafe { T_fn(~[T_ptr(type_of(ccx, ty::mk_nil(ccx.tcx))), // output pointer T_ptr(type_of(ccx, self_ty))], // self arg @@ -286,14 +384,14 @@ pub fn type_of_dtor(ccx: @crate_ctxt, self_ty: ty::t) -> TypeRef { } } -pub fn type_of_rooted(ccx: @crate_ctxt, t: ty::t) -> TypeRef { +pub fn type_of_rooted(ccx: @CrateContext, t: ty::t) -> TypeRef { let addrspace = base::get_tydesc(ccx, t).addrspace; debug!("type_of_rooted %s in addrspace %u", ty_to_str(ccx.tcx, t), addrspace as uint); return T_root(type_of(ccx, t), addrspace); } -pub fn type_of_glue_fn(ccx: @crate_ctxt, t: ty::t) -> TypeRef { +pub fn type_of_glue_fn(ccx: @CrateContext, t: ty::t) -> TypeRef { let tydescpp = T_ptr(T_ptr(ccx.tydesc_type)); let llty = T_ptr(type_of(ccx, t)); return T_fn(~[T_ptr(T_nil()), T_ptr(T_nil()), tydescpp, llty], diff --git a/src/librustc/middle/trans/type_use.rs b/src/librustc/middle/trans/type_use.rs index af570e1f25909..3013f928b75da 100644 --- a/src/librustc/middle/trans/type_use.rs +++ b/src/librustc/middle/trans/type_use.rs @@ -49,9 +49,12 @@ 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 type ctx = {ccx: @crate_ctxt, uses: ~[mut type_uses]}; +pub struct Context { + ccx: @CrateContext, + uses: ~[mut type_uses] +} -pub fn type_uses_for(ccx: @crate_ctxt, fn_id: def_id, n_tps: uint) +pub fn type_uses_for(ccx: @CrateContext, fn_id: def_id, n_tps: uint) -> ~[type_uses] { match ccx.type_use_cache.find(&fn_id) { Some(uses) => return uses, @@ -67,7 +70,10 @@ pub fn type_uses_for(ccx: @crate_ctxt, fn_id: def_id, n_tps: uint) // Conservatively assume full use for recursive loops ccx.type_use_cache.insert(fn_id, vec::from_elem(n_tps, 3u)); - let cx = {ccx: ccx, uses: vec::cast_to_mut(vec::from_elem(n_tps, 0u))}; + let cx = Context { + ccx: ccx, + uses: vec::cast_to_mut(vec::from_elem(n_tps, 0u)) + }; match ty::get(ty::lookup_item_type(cx.ccx.tcx, fn_id).ty).sty { ty::ty_bare_fn(ty::BareFnTy {sig: ref sig, _}) | ty::ty_closure(ty::ClosureTy {sig: ref sig, _}) => { @@ -112,7 +118,7 @@ pub fn type_uses_for(ccx: @crate_ctxt, fn_id: def_id, n_tps: uint) _ }, abi, _) => { if abi == foreign_abi_rust_intrinsic { - let flags = match cx.ccx.sess.str_of(i.ident) { + let flags = match *cx.ccx.sess.str_of(i.ident) { ~"size_of" | ~"pref_align_of" | ~"min_align_of" | ~"init" | ~"reinterpret_cast" | ~"move_val" | ~"move_val_init" => use_repr, @@ -175,7 +181,7 @@ pub fn type_uses_for(ccx: @crate_ctxt, fn_id: def_id, n_tps: uint) uses } -pub fn type_needs(cx: ctx, use_: uint, ty: ty::t) { +pub fn type_needs(cx: Context, use_: uint, ty: ty::t) { // Optimization -- don't descend type if all params already have this use for vec::each_mut(cx.uses) |u| { if *u & use_ != use_ { @@ -185,7 +191,7 @@ pub fn type_needs(cx: ctx, use_: uint, ty: ty::t) { } } -pub fn type_needs_inner(cx: ctx, +pub fn type_needs_inner(cx: Context, use_: uint, ty: ty::t, enums_seen: @List) { @@ -226,11 +232,11 @@ pub fn type_needs_inner(cx: ctx, } } -pub fn node_type_needs(cx: ctx, use_: uint, id: node_id) { +pub fn node_type_needs(cx: Context, use_: uint, id: node_id) { type_needs(cx, use_, ty::node_id_to_type(cx.ccx.tcx, id)); } -pub fn mark_for_method_call(cx: ctx, e_id: node_id, callee_id: node_id) { +pub fn mark_for_method_call(cx: Context, e_id: node_id, callee_id: node_id) { do option::iter(&cx.ccx.maps.method_map.find(&e_id)) |mth| { match mth.origin { typeck::method_static(did) => { @@ -253,7 +259,7 @@ pub fn mark_for_method_call(cx: ctx, e_id: node_id, callee_id: node_id) { } } -pub fn mark_for_expr(cx: ctx, e: @expr) { +pub fn mark_for_expr(cx: Context, e: @expr) { match e.node { expr_vstore(_, _) | expr_vec(_, _) | @@ -353,7 +359,7 @@ pub fn mark_for_expr(cx: ctx, e: @expr) { } } -pub fn handle_body(cx: ctx, body: blk) { +pub fn handle_body(cx: Context, body: blk) { let v = visit::mk_vt(@visit::Visitor { visit_expr: |e, cx, v| { visit::visit_expr(e, cx, v); diff --git a/src/librustc/middle/trans/uniq.rs b/src/librustc/middle/trans/uniq.rs index 194a9c4ea09bf..aa02cc4bf5d53 100644 --- a/src/librustc/middle/trans/uniq.rs +++ b/src/librustc/middle/trans/uniq.rs @@ -30,7 +30,11 @@ pub fn make_free_glue(bcx: block, vptrptr: ValueRef, box_ty: ty::t) let body_datum = box_datum.box_body(bcx); let bcx = glue::drop_ty(bcx, body_datum.to_ref_llval(bcx), body_datum.ty); - glue::trans_unique_free(bcx, box_datum.val) + if ty::type_contents(bcx.tcx(), box_ty).contains_managed() { + glue::trans_free(bcx, box_datum.val) + } else { + glue::trans_exchange_free(bcx, box_datum.val) + } } } @@ -42,8 +46,11 @@ pub fn duplicate(bcx: block, src_box: ValueRef, src_ty: ty::t) -> Result { let body_datum = src_datum.box_body(bcx); // Malloc space in exchange heap and copy src into it - let {bcx: bcx, box: dst_box, body: dst_body} = - malloc_unique(bcx, body_datum.ty); + let MallocResult { + bcx: bcx, + box: dst_box, + body: dst_body + } = malloc_unique(bcx, body_datum.ty); body_datum.copy_to(bcx, datum::INIT, dst_body); // Copy the type descriptor diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs index f7fb5b771aa74..239e86623cabd 100644 --- a/src/librustc/middle/ty.rs +++ b/src/librustc/middle/ty.rs @@ -70,14 +70,14 @@ pub struct field { pub type param_bounds = @~[param_bound]; -pub type method = { +pub struct method { ident: ast::ident, tps: @~[param_bounds], fty: BareFnTy, self_ty: ast::self_ty_, vis: ast::visibility, def_id: ast::def_id -}; +} pub struct mt { ty: t, @@ -230,10 +230,9 @@ pub type ctxt = @ctxt_; struct ctxt_ { diag: syntax::diagnostic::span_handler, interner: HashMap, - mut next_id: uint, + next_id: @mut uint, vecs_implicitly_copyable: bool, legacy_modes: bool, - legacy_records: bool, cstore: @mut metadata::cstore::CStore, sess: session::Session, def_map: resolve::DefMap, @@ -261,7 +260,7 @@ struct ctxt_ { short_names_cache: HashMap, needs_drop_cache: HashMap, needs_unwind_cleanup_cache: HashMap, - mut tc_cache: LinearMap, + tc_cache: @mut LinearMap, ast_ty_to_ty_cache: HashMap, enum_var_cache: HashMap, trait_method_cache: HashMap, @@ -303,10 +302,14 @@ enum tbox_flag { needs_subst = 1 | 2 | 8 } -type t_box = @{sty: sty, - id: uint, - flags: uint, - o_def_id: Option}; +type t_box = @t_box_; + +struct t_box_ { + sty: sty, + id: uint, + flags: uint, + o_def_id: Option +} // To reduce refcounting cost, we're representing types as unsafe pointers // throughout the compiler. These are simply casted t_box values. Use ty::get @@ -320,7 +323,7 @@ pub pure fn get(t: t) -> t_box { unsafe { let t2 = cast::reinterpret_cast::(&t); let t3 = t2; - cast::forget(move t2); + cast::forget(t2); t3 } } @@ -654,49 +657,49 @@ impl to_bytes::IterBytes for param_bound { } pub trait Vid { - pure fn to_uint() -> uint; + pure fn to_uint(&self) -> uint; } -pub impl TyVid: Vid { - pure fn to_uint() -> uint { *self } +pub impl Vid for TyVid { + pure fn to_uint(&self) -> uint { **self } } -pub impl TyVid: ToStr { +pub impl ToStr for TyVid { pure fn to_str(&self) -> ~str { fmt!("", self.to_uint()) } } -pub impl IntVid: Vid { - pure fn to_uint() -> uint { *self } +pub impl Vid for IntVid { + pure fn to_uint(&self) -> uint { **self } } -pub impl IntVid: ToStr { +pub impl ToStr for IntVid { pure fn to_str(&self) -> ~str { fmt!("", self.to_uint()) } } -pub impl FloatVid: Vid { - pure fn to_uint() -> uint { *self } +pub impl Vid for FloatVid { + pure fn to_uint(&self) -> uint { **self } } -pub impl FloatVid: ToStr { +pub impl ToStr for FloatVid { pure fn to_str(&self) -> ~str { fmt!("", self.to_uint()) } } -pub impl RegionVid: Vid { - pure fn to_uint() -> uint { *self } +pub impl Vid for RegionVid { + pure fn to_uint(&self) -> uint { **self } } -pub impl RegionVid: ToStr { +pub impl ToStr for RegionVid { pure fn to_str(&self) -> ~str { fmt!("%?", self) } } -pub impl FnSig : ToStr { +pub impl ToStr for FnSig { pure fn to_str(&self) -> ~str { // grr, without tcx not much we can do. return ~"(...)"; } } -pub impl InferTy: ToStr { +pub impl ToStr for InferTy { pure fn to_str(&self) -> ~str { match *self { TyVar(ref v) => v.to_str(), @@ -706,7 +709,7 @@ pub impl InferTy: ToStr { } } -pub impl IntVarValue : ToStr { +pub impl ToStr for IntVarValue { pure fn to_str(&self) -> ~str { match *self { IntType(ref v) => v.to_str(), @@ -715,25 +718,25 @@ pub impl IntVarValue : ToStr { } } -pub impl TyVid : to_bytes::IterBytes { +pub impl to_bytes::IterBytes for TyVid { pure fn iter_bytes(&self, +lsb0: bool, f: to_bytes::Cb) { self.to_uint().iter_bytes(lsb0, f) } } -pub impl IntVid : to_bytes::IterBytes { +pub impl to_bytes::IterBytes for IntVid { pure fn iter_bytes(&self, +lsb0: bool, f: to_bytes::Cb) { self.to_uint().iter_bytes(lsb0, f) } } -pub impl FloatVid : to_bytes::IterBytes { +pub impl to_bytes::IterBytes for FloatVid { pure fn iter_bytes(&self, +lsb0: bool, f: to_bytes::Cb) { self.to_uint().iter_bytes(lsb0, f) } } -pub impl RegionVid : to_bytes::IterBytes { +pub impl to_bytes::IterBytes for RegionVid { pure fn iter_bytes(&self, +lsb0: bool, f: to_bytes::Cb) { self.to_uint().iter_bytes(lsb0, f) } @@ -749,11 +752,16 @@ pub impl RegionVid : to_bytes::IterBytes { /// /// - `ty`: the base type. May have reference to the (unsubstituted) bound /// region `&self` or to (unsubstituted) ty_param types -pub type ty_param_bounds_and_ty = {bounds: @~[param_bounds], - region_param: Option, - ty: t}; +pub struct ty_param_bounds_and_ty { + bounds: @~[param_bounds], + region_param: Option, + ty: t +} -pub type ty_param_substs_and_ty = {substs: ty::substs, ty: ty::t}; +pub struct ty_param_substs_and_ty { + substs: ty::substs, + ty: ty::t +} type type_cache = HashMap; @@ -766,7 +774,7 @@ fn mk_rcache() -> creader_cache { return oldmap::HashMap(); } -pub fn new_ty_hash() -> oldmap::HashMap { +pub fn new_ty_hash() -> oldmap::HashMap { oldmap::HashMap() } @@ -780,16 +788,10 @@ pub fn mk_ctxt(s: session::Session, crate: @ast::crate) -> ctxt { let mut legacy_modes = false; - let mut legacy_records = false; for crate.node.attrs.each |attribute| { match attribute.node.value.node { - ast::meta_word(ref w) if (*w) == ~"legacy_modes" => { + ast::meta_word(w) if *w == ~"legacy_modes" => { legacy_modes = true; - if legacy_records { break; } - } - ast::meta_word(ref w) if (*w) == ~"legacy_records" => { - legacy_records = true; - if legacy_modes { break; } } _ => {} } @@ -802,10 +804,9 @@ pub fn mk_ctxt(s: session::Session, @ctxt_ { diag: s.diagnostic(), interner: interner, - mut next_id: 0u, + next_id: @mut 0, vecs_implicitly_copyable: vecs_implicitly_copyable, legacy_modes: legacy_modes, - legacy_records: legacy_records, cstore: s.cstore, sess: s, def_map: dm, @@ -822,7 +823,7 @@ pub fn mk_ctxt(s: session::Session, short_names_cache: new_ty_hash(), needs_drop_cache: new_ty_hash(), needs_unwind_cleanup_cache: new_ty_hash(), - tc_cache: LinearMap::new(), + tc_cache: @mut LinearMap::new(), ast_ty_to_ty_cache: HashMap(), enum_var_cache: HashMap(), trait_method_cache: HashMap(), @@ -830,7 +831,7 @@ pub fn mk_ctxt(s: session::Session, inferred_modes: HashMap(), adjustments: HashMap(), normalized_cache: new_ty_hash(), - lang_items: move lang_items, + lang_items: lang_items, legacy_boxed_traits: HashMap(), provided_methods: HashMap(), provided_method_sources: HashMap(), @@ -909,12 +910,20 @@ fn mk_t_with_id(cx: ctxt, +st: sty, o_def_id: Option) -> t { } } - let t = @{sty: move st, id: cx.next_id, flags: flags, o_def_id: o_def_id}; + let t = @t_box_ { + sty: st, + id: *cx.next_id, + flags: flags, + o_def_id: o_def_id + }; + let key = intern_key { + sty: to_unsafe_ptr(&t.sty), + o_def_id: o_def_id + }; - let key = intern_key {sty: to_unsafe_ptr(&t.sty), o_def_id: o_def_id}; - cx.interner.insert(move key, t); + cx.interner.insert(key, t); - cx.next_id += 1u; + *cx.next_id += 1; unsafe { cast::reinterpret_cast(&t) } } @@ -1178,7 +1187,7 @@ pub fn fold_sig(sig: &FnSig, fldop: fn(t) -> t) -> FnSig { }; FnSig { - inputs: move args, + inputs: args, output: fldop(sig.output) } } @@ -1562,10 +1571,11 @@ pub pure fn type_is_vec(ty: t) -> bool { pub pure fn type_is_unique(ty: t) -> bool { match get(ty).sty { - ty_uniq(_) => return true, - ty_evec(_, vstore_uniq) => true, - ty_estr(vstore_uniq) => true, - _ => return false + ty_uniq(_) | + ty_evec(_, vstore_uniq) | + ty_estr(vstore_uniq) | + ty_opaque_closure_ptr(ast::OwnedSigil) => true, + _ => return false } } @@ -1790,6 +1800,10 @@ pub impl TypeContents { TC_MANAGED + TC_BORROWED_POINTER } + fn contains_managed(&self) -> bool { + self.intersects(TC_MANAGED) + } + fn is_const(&self, cx: ctxt) -> bool { !self.intersects(TypeContents::nonconst(cx)) } @@ -2074,11 +2088,19 @@ pub fn type_contents(cx: ctxt, ty: t) -> TypeContents { TC_ALL } - ty_trait(_, _, vstore_fixed(_)) | - ty_type | - ty_opaque_closure_ptr(_) | - ty_opaque_box | - ty_unboxed_vec(_) | + ty_opaque_box => TC_MANAGED, + ty_unboxed_vec(mt) => tc_mt(cx, mt, cache), + ty_opaque_closure_ptr(sigil) => { + match sigil { + ast::BorrowedSigil => TC_BORROWED_POINTER, + ast::ManagedSigil => TC_MANAGED, + ast::OwnedSigil => TC_OWNED_CLOSURE + } + } + + ty_type => TC_NONE, + ty_trait(_, _, vstore_fixed(_)) => TC_NONE, + ty_err => { cx.sess.bug(~"Asked to compute contents of fictitious type"); } @@ -2220,8 +2242,11 @@ pub fn type_contents(cx: ctxt, ty: t) -> TypeContents { ty_infer(_) => { cx.sess.bug(~"Asked to compute kind of a type variable"); } - ty_type | ty_opaque_closure_ptr(_) - | ty_opaque_box | ty_unboxed_vec(_) | ty_err => { + ty_type => 1, + ty_opaque_closure_ptr(_) => 1, + ty_opaque_box => 1, + ty_unboxed_vec(_) => 10, + ty_err => { cx.sess.bug(~"Asked to compute kind of fictitious type"); } } @@ -2823,7 +2848,7 @@ pub pure fn ty_fn_ret(fty: t) -> t { } } -fn is_fn_ty(fty: t) -> bool { +pub fn is_fn_ty(fty: t) -> bool { match get(fty).sty { ty_bare_fn(_) => true, ty_closure(_) => true, @@ -3010,11 +3035,18 @@ pub fn expr_ty_adjusted(cx: ctxt, expr: @ast::expr) -> t { } } +pub struct ParamsTy { + params: ~[t], + ty: t +} + pub fn expr_ty_params_and_ty(cx: ctxt, expr: @ast::expr) - -> {params: ~[t], ty: t} { - return {params: node_id_to_type_params(cx, expr.id), - ty: node_id_to_type(cx, expr.id)}; + -> ParamsTy { + ParamsTy { + params: node_id_to_type_params(cx, expr.id), + ty: node_id_to_type(cx, expr.id) + } } pub fn expr_has_ty_params(cx: ctxt, expr: @ast::expr) -> bool { @@ -3110,7 +3142,7 @@ pub fn expr_kind(tcx: ctxt, ast::def_local(*) | ast::def_self(*) => LvalueExpr, - move def => { + def => { tcx.sess.span_bug(expr.span, fmt!( "Uncategorized def for expr %?: %?", expr.id, def)); @@ -3226,7 +3258,7 @@ pub fn field_idx_strict(tcx: ty::ctxt, id: ast::ident, fields: &[field]) for fields.each |f| { if f.ident == id { return i; } i += 1u; } tcx.sess.bug(fmt!( "No field named `%s` found in the list of fields `%?`", - tcx.sess.str_of(id), + *tcx.sess.str_of(id), fields.map(|f| tcx.sess.str_of(f.ident)))); } @@ -3235,7 +3267,7 @@ pub fn get_field(tcx: ctxt, rec_ty: t, id: ast::ident) -> field { Some(f) => f, // Do we only call this when we know the field is legit? None => fail!(fmt!("get_field: ty doesn't have a field %s", - tcx.sess.str_of(id))) + *tcx.sess.str_of(id))) } } @@ -3302,7 +3334,7 @@ pub fn occurs_check(tcx: ctxt, sp: span, vid: TyVid, rt: t) { // Maintains a little union-set tree for inferred modes. `canon()` returns // the current head value for `m0`. -fn canon(tbl: HashMap>, +fn canon(tbl: HashMap>, +m0: ast::inferable) -> ast::inferable { match m0 { ast::infer(id) => match tbl.find(&id) { @@ -3465,8 +3497,8 @@ pub fn type_err_to_str(cx: ctxt, err: &type_err) -> ~str { terr_record_fields(values) => { fmt!("expected a record with field `%s` but found one with field \ `%s`", - cx.sess.str_of(values.expected), - cx.sess.str_of(values.found)) + *cx.sess.str_of(values.expected), + *cx.sess.str_of(values.found)) } terr_arg_count => ~"incorrect number of function parameters", terr_mode_mismatch(values) => { @@ -3500,7 +3532,7 @@ pub fn type_err_to_str(cx: ctxt, err: &type_err) -> ~str { vstore_to_str(cx, (*values).found)) } terr_in_field(err, fname) => { - fmt!("in field `%s`, %s", cx.sess.str_of(fname), + fmt!("in field `%s`, %s", *cx.sess.str_of(fname), type_err_to_str(cx, err)) } terr_sorts(values) => { @@ -3609,7 +3641,10 @@ pub fn trait_supertraits(cx: ctxt, ty_trait(def_id, ref substs, _) => { result.push(InstantiatedTraitRef { def_id: def_id, - tpt: { substs: (/*bad*/copy *substs), ty: *trait_type } + tpt: ty_param_substs_and_ty { + substs: (/*bad*/copy *substs), + ty: *trait_type + } }); } _ => cx.sess.bug(~"trait_supertraits: trait ref wasn't a trait") @@ -3617,7 +3652,7 @@ pub fn trait_supertraits(cx: ctxt, } // Unwrap and return the result. - return @dvec::unwrap(move result); + return @dvec::unwrap(result); } pub fn trait_methods(cx: ctxt, id: ast::def_id) -> @~[method] { diff --git a/src/librustc/middle/typeck/astconv.rs b/src/librustc/middle/typeck/astconv.rs index 3ee604426c9f7..9269752b8ecf4 100644 --- a/src/librustc/middle/typeck/astconv.rs +++ b/src/librustc/middle/typeck/astconv.rs @@ -94,7 +94,7 @@ pub fn get_region_reporting_err(tcx: ty::ctxt, } } -pub fn ast_region_to_region( +pub fn ast_region_to_region( self: @mut AC, rscope: RS, span: span, @@ -110,15 +110,18 @@ pub fn ast_region_to_region( get_region_reporting_err(self.tcx(), span, res) } -pub fn ast_path_to_substs_and_ty( +pub fn ast_path_to_substs_and_ty( self: @mut AC, rscope: RS, did: ast::def_id, path: @ast::path) -> ty_param_substs_and_ty { let tcx = self.tcx(); - let {bounds: decl_bounds, region_param: decl_rp, ty: decl_ty} = - self.get_item_ty(did); + let ty::ty_param_bounds_and_ty { + bounds: decl_bounds, + region_param: decl_rp, + ty: decl_ty + } = self.get_item_ty(did); debug!("ast_path_to_substs_and_ty: did=%? decl_rp=%?", did, decl_rp); @@ -159,10 +162,11 @@ pub fn ast_path_to_substs_and_ty( let substs = substs {self_r:self_r, self_ty:None, tps:tps}; let ty = ty::subst(tcx, &substs, decl_ty); - {substs: substs, ty: ty} + + ty_param_substs_and_ty { substs: substs, ty: ty } } -pub fn ast_path_to_ty( +pub fn ast_path_to_ty( self: @mut AC, rscope: RS, did: ast::def_id, @@ -172,11 +176,14 @@ pub fn ast_path_to_ty( // Look up the polytype of the item and then substitute the provided types // for any type/region parameters. let tcx = self.tcx(); - let {substs: substs, ty: ty} = - ast_path_to_substs_and_ty(self, rscope, did, path); + let ty::ty_param_substs_and_ty { + substs: substs, + ty: ty + } = ast_path_to_substs_and_ty(self, rscope, did, path); write_ty_to_tcx(tcx, path_id, ty); write_substs_to_tcx(tcx, path_id, /*bad*/copy substs.tps); - return {substs: substs, ty: ty}; + + ty_param_substs_and_ty { substs: substs, ty: ty } } pub const NO_REGIONS: uint = 1; @@ -185,10 +192,10 @@ pub const 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 // corresponding to a definition ID: -pub fn ast_ty_to_ty( +pub fn ast_ty_to_ty( self: @mut AC, rscope: RS, &&ast_ty: @ast::Ty) -> ty::t { - fn ast_mt_to_mt( + fn ast_mt_to_mt( self: @mut AC, rscope: RS, mt: ast::mt) -> ty::mt { ty::mt {ty: ast_ty_to_ty(self, rscope, mt.ty), mutbl: mt.mutbl} @@ -197,7 +204,7 @@ pub fn ast_ty_to_ty( // Handle @, ~, and & being able to mean estrs and evecs. // If a_seq_ty is a str or a vec, make it an estr/evec. // Also handle function sigils and first-class trait types. - fn mk_pointer( + fn mk_pointer( self: @mut AC, rscope: RS, a_seq_ty: ast::mt, @@ -413,7 +420,7 @@ pub fn ast_ty_to_ty( return typ; } -pub fn ty_of_arg( +pub fn ty_of_arg( self: @mut AC, rscope: RS, a: ast::arg, @@ -461,7 +468,7 @@ pub fn ty_of_arg( arg {mode: mode, ty: ty} } -pub fn ty_of_bare_fn( +pub fn ty_of_bare_fn( self: @mut AC, rscope: RS, purity: ast::purity, @@ -487,7 +494,7 @@ pub fn ty_of_bare_fn( } } -pub fn ty_of_closure( +pub fn ty_of_closure( self: @mut AC, rscope: RS, sigil: ast::Sigil, diff --git a/src/librustc/middle/typeck/check/_match.rs b/src/librustc/middle/typeck/check/_match.rs index 95bed1140500d..82f9828db3fb3 100644 --- a/src/librustc/middle/typeck/check/_match.rs +++ b/src/librustc/middle/typeck/check/_match.rs @@ -92,11 +92,11 @@ pub fn check_pat_variant(pcx: pat_ctxt, pat: @ast::pat, path: @ast::path, match structure_of(pcx.fcx, pat.span, expected) { ty::ty_enum(_, ref expected_substs) => { // Lookup the enum and variant def ids: - let v_def = lookup_def(pcx.fcx, path.span, pat.id); - let v_def_ids = ast_util::variant_def_ids(v_def); + let v_def = lookup_def(pcx.fcx, pat.span, pat.id); + let (enm, var) = ast_util::variant_def_ids(v_def); // Assign the pattern the type of the *enum*, not the variant. - let enum_tpt = ty::lookup_item_type(tcx, v_def_ids.enm); + let enum_tpt = ty::lookup_item_type(tcx, enm); instantiate_path(pcx.fcx, path, enum_tpt, pat.span, pat.id, pcx.block_region); @@ -108,9 +108,8 @@ pub fn check_pat_variant(pcx: pat_ctxt, pat: @ast::pat, path: @ast::path, // Get the expected types of the arguments. arg_types = { let vinfo = - ty::enum_variant_with_id( - tcx, v_def_ids.enm, v_def_ids.var); - let var_tpt = ty::lookup_item_type(tcx, v_def_ids.var); + ty::enum_variant_with_id(tcx, enm, var); + let var_tpt = ty::lookup_item_type(tcx, var); vinfo.args.map(|t| { if var_tpt.bounds.len() == expected_substs.tps.len() { ty::subst(tcx, expected_substs, *t) @@ -125,8 +124,18 @@ pub fn check_pat_variant(pcx: pat_ctxt, pat: @ast::pat, path: @ast::path, kind_name = "variant"; } ty::ty_struct(struct_def_id, ref expected_substs) => { + // Lookup the struct ctor def id + let s_def = lookup_def(pcx.fcx, pat.span, pat.id); + let s_def_id = ast_util::def_id_of_def(s_def); + // Assign the pattern the type of the struct. - let struct_tpt = ty::lookup_item_type(tcx, struct_def_id); + let ctor_tpt = ty::lookup_item_type(tcx, s_def_id); + let struct_tpt = if ty::is_fn_ty(ctor_tpt.ty) { + ty::ty_param_bounds_and_ty {ty: ty::ty_fn_ret(ctor_tpt.ty), + ..ctor_tpt} + } else { + ctor_tpt + }; instantiate_path(pcx.fcx, path, struct_tpt, pat.span, pat.id, pcx.block_region); @@ -231,7 +240,7 @@ pub fn check_struct_pat_fields(pcx: pat_ctxt, tcx.sess.span_err(span, fmt!("struct `%s` does not have a field named `%s`", name, - tcx.sess.str_of(field.ident))); + *tcx.sess.str_of(field.ident))); } } } @@ -244,7 +253,7 @@ pub fn check_struct_pat_fields(pcx: pat_ctxt, } tcx.sess.span_err(span, fmt!("pattern does not mention field `%s`", - tcx.sess.str_of(field.ident))); + *tcx.sess.str_of(field.ident))); } } } @@ -362,6 +371,7 @@ pub fn check_pat(pcx: pat_ctxt, pat: @ast::pat, expected: ty::t) { 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); + demand::suptype(fcx, pat.span, expected, const_tpt.ty); fcx.write_ty(pat.id, const_tpt.ty); } ast::pat_ident(bm, name, sub) if pat_is_binding(tcx.def_map, pat) => { @@ -435,7 +445,7 @@ pub fn check_pat(pcx: pat_ctxt, pat: @ast::pat, expected: ty::t) { tcx.sess.span_fatal(pat.span, fmt!("mismatched types: did not \ expect a record with a field `%s`", - tcx.sess.str_of(f.ident))); + *tcx.sess.str_of(f.ident))); } } } diff --git a/src/librustc/middle/typeck/check/method.rs b/src/librustc/middle/typeck/check/method.rs index eca368e5d7673..34b650aa180df 100644 --- a/src/librustc/middle/typeck/check/method.rs +++ b/src/librustc/middle/typeck/check/method.rs @@ -139,7 +139,7 @@ pub fn lookup( let mme = lcx.do_lookup(self_ty); debug!("method lookup for %s yielded %?", expr_repr(fcx.tcx(), expr), mme); - return move mme; + return mme; } pub struct LookupContext { @@ -204,26 +204,26 @@ pub impl LookupContext { check::DontDerefArgs => { match self.search_for_autoderefd_method(self_ty, autoderefs) { - Some(move mme) => { return Some(mme); } + Some(mme) => { return Some(mme); } None => {} } match self.search_for_autoptrd_method(self_ty, autoderefs) { - Some(move mme) => { return Some(move mme); } + Some(mme) => { return Some(mme); } None => {} } } check::DoDerefArgs => { match self.search_for_autoptrd_method(self_ty, autoderefs) { - Some(move mme) => { return Some(move mme); } + Some(mme) => { return Some(mme); } None => {} } match self.search_for_autoderefd_method(self_ty, autoderefs) { - Some(move mme) => { return Some(mme); } + Some(mme) => { return Some(mme); } None => {} } } @@ -438,10 +438,9 @@ pub impl LookupContext { let trait_methods = ty::trait_methods(tcx, init_trait_id); let pos = { - // FIXME #3453 can't use trait_methods.position - match vec::position(*trait_methods, - |m| (m.self_ty != ast::sty_static && - m.ident == self.m_name)) + match trait_methods.position(|m| { + m.self_ty != ast::sty_static && + m.ident == self.m_name }) { Some(pos) => pos, None => { @@ -457,7 +456,7 @@ pub impl LookupContext { self.create_rcvr_ty_and_substs_for_method( method.self_ty, rcvr_ty, - move init_substs, + init_substs, TransformTypeNormally); let cand = Candidate { @@ -525,12 +524,12 @@ pub impl LookupContext { let (rcvr_ty, rcvr_substs) = self.create_rcvr_ty_and_substs_for_method(method.self_ty, self_ty, - move rcvr_substs, + rcvr_substs, TransformTypeForObject); self.inherent_candidates.push(Candidate { rcvr_ty: rcvr_ty, - rcvr_substs: move rcvr_substs, + rcvr_substs: rcvr_substs, explicit_self: method.self_ty, num_method_tps: method.tps.len(), self_mode: get_mode_from_self_type(method.self_ty), @@ -585,7 +584,7 @@ pub impl LookupContext { self.create_rcvr_ty_and_substs_for_method( method_self_ty, self_ty, - move rcvr_substs, + rcvr_substs, TransformTypeNormally); let origin = if trait_did == did { method_self(trait_did, index) @@ -595,7 +594,7 @@ pub impl LookupContext { }; self.inherent_candidates.push(Candidate { rcvr_ty: rcvr_ty, - rcvr_substs: move rcvr_substs, + rcvr_substs: rcvr_substs, explicit_self: method_self_ty, num_method_tps: method_num_tps, self_mode: get_mode_from_self_type(method_self_ty), @@ -624,9 +623,7 @@ pub impl LookupContext { } let idx = { - // FIXME #3453 can't use impl_info.methods.position - match vec::position(impl_info.methods, - |m| m.ident == self.m_name) { + match impl_info.methods.position(|m| m.ident == self.m_name) { Some(idx) => idx, None => { return; } // No method with the right name. } @@ -641,19 +638,21 @@ pub impl LookupContext { ccx: self.fcx.ccx, infcx: self.fcx.infcx() }; - let {substs: impl_substs, ty: impl_ty} = - impl_self_ty(&vcx, location_info, impl_info.did); + let ty::ty_param_substs_and_ty { + substs: impl_substs, + ty: impl_ty + } = impl_self_ty(&vcx, location_info, impl_info.did); let (impl_ty, impl_substs) = self.create_rcvr_ty_and_substs_for_method( method.self_type, impl_ty, - move impl_substs, + impl_substs, TransformTypeNormally); candidates.push(Candidate { rcvr_ty: impl_ty, - rcvr_substs: move impl_substs, + rcvr_substs: impl_substs, explicit_self: method.self_type, num_method_tps: method.n_tps, self_mode: get_mode_from_self_type(method.self_type), @@ -693,7 +692,7 @@ pub impl LookupContext { candidates.push(Candidate { rcvr_ty: impl_ty, - rcvr_substs: move impl_substs, + rcvr_substs: impl_substs, explicit_self: provided_method_info.method_info.self_type, num_method_tps: provided_method_info.method_info.n_tps, self_mode: get_mode_from_self_type( @@ -722,10 +721,10 @@ pub impl LookupContext { match self_decl { sty_static | sty_value | sty_by_ref | sty_box(_) | sty_uniq(_) => { - move self_substs + self_substs } sty_region(_) if self_substs.self_r.is_some() => { - move self_substs + self_substs } sty_region(_) => { substs { @@ -761,7 +760,7 @@ pub impl LookupContext { self.consider_reborrow(self_ty, autoderefs); match self.search_for_method(self_ty) { None => None, - Some(move mme) => { + Some(mme) => { debug!("(searching for autoderef'd method) writing \ adjustment (%u) to %d", autoderefs, @@ -945,7 +944,7 @@ pub impl LookupContext { let autoref_ty = mk_autoref_ty(*mutbl, region); match self.search_for_method(autoref_ty) { None => {} - Some(move mme) => { + Some(mme) => { self.fcx.write_adjustment( self.self_expr.id, @ty::AutoAdjustment { @@ -977,8 +976,8 @@ pub impl LookupContext { debug!("searching inherent candidates"); match self.consider_candidates(self_ty, &self.inherent_candidates) { None => {} - Some(move mme) => { - return Some(move mme); + Some(mme) => { + return Some(mme); } } @@ -987,8 +986,8 @@ pub impl LookupContext { None => { return None; } - Some(move mme) => { - return Some(move mme); + Some(mme) => { + return Some(mme); } } } diff --git a/src/librustc/middle/typeck/check/mod.rs b/src/librustc/middle/typeck/check/mod.rs index a8439c3c45964..e63e46ace3d05 100644 --- a/src/librustc/middle/typeck/check/mod.rs +++ b/src/librustc/middle/typeck/check/mod.rs @@ -137,12 +137,12 @@ pub mod regionck; pub mod demand; pub mod method; -pub type self_info = { +pub struct SelfInfo { self_ty: ty::t, self_id: ast::node_id, def_id: ast::def_id, explicit_self: ast::self_ty -}; +} /// Fields that are part of a `FnCtxt` which are inherited by /// closures defined within the function. For example: @@ -171,7 +171,7 @@ pub struct FnCtxt { // Refers to whichever `self` is in scope, even this FnCtxt is // for a nested closure that captures `self` - self_info: Option, + self_info: Option, ret_ty: ty::t, // Used by loop bodies that return from the outer function indirect_ret_ty: Option, @@ -246,7 +246,7 @@ pub fn check_bare_fn(ccx: @mut CrateCtxt, decl: &ast::fn_decl, body: ast::blk, id: ast::node_id, - self_info: Option) { + self_info: Option) { let fty = ty::node_id_to_type(ccx.tcx, id); match ty::get(fty).sty { ty::ty_bare_fn(ref fn_ty) => { @@ -259,7 +259,7 @@ pub fn check_bare_fn(ccx: @mut CrateCtxt, } pub fn check_fn(ccx: @mut CrateCtxt, - +self_info: Option, + +self_info: Option, purity: ast::purity, sigil: Option, fn_sig: &ty::FnSig, @@ -277,7 +277,7 @@ pub fn check_fn(ccx: @mut CrateCtxt, // types with free ones. The free region references will be bound // the node_id of the body block. - let {isr, self_info, fn_sig} = { + let (isr, self_info, fn_sig) = { let old_isr = option::map_default(&old_fcx, @Nil, |fcx| fcx.in_scope_regions); replace_bound_regions_in_fn_sig(tcx, old_isr, self_info, fn_sig, @@ -326,7 +326,7 @@ pub fn check_fn(ccx: @mut CrateCtxt, } }; - // Update the self_info to contain an accurate self type (taking + // Update the SelfInfo to contain an accurate self type (taking // into account explicit self). let self_info = do self_info.chain_ref |self_info| { // If the self type is sty_static, we don't have a self ty. @@ -341,7 +341,7 @@ pub fn check_fn(ccx: @mut CrateCtxt, self_info.self_ty, self_info.explicit_self.node, TransformTypeNormally); - Some({self_ty: ty,.. *self_info}) + Some(SelfInfo { self_ty: ty,.. *self_info }) } }; @@ -383,7 +383,7 @@ pub fn check_fn(ccx: @mut CrateCtxt, decl: &ast::fn_decl, body: ast::blk, arg_tys: &[ty::t], - self_info: Option) { + self_info: Option) { let tcx = fcx.ccx.tcx; let assign = fn@(nid: ast::node_id, ty_opt: Option) { @@ -450,7 +450,7 @@ pub fn check_fn(ccx: @mut CrateCtxt, if pat_util::pat_is_binding(fcx.ccx.tcx.def_map, p) => { assign(p.id, None); debug!("Pattern binding %s is assigned to %s", - tcx.sess.str_of(path.idents[0]), + *tcx.sess.str_of(path.idents[0]), fcx.infcx().ty_to_str( fcx.inh.locals.get(&p.id))); } @@ -491,10 +491,12 @@ pub fn check_method(ccx: @mut CrateCtxt, method: @ast::method, self_ty: ty::t, self_impl_def_id: ast::def_id) { - let self_info = {self_ty: self_ty, - self_id: method.self_id, - def_id: self_impl_def_id, - explicit_self: method.self_ty }; + let self_info = SelfInfo { + self_ty: self_ty, + self_id: method.self_id, + def_id: self_impl_def_id, + explicit_self: method.self_ty + }; check_bare_fn(ccx, &method.decl, method.body, method.id, Some(self_info)); } @@ -508,7 +510,7 @@ pub fn check_no_duplicate_fields(tcx: ty::ctxt, Some(orig_sp) => { tcx.sess.span_err(sp, fmt!("Duplicate field \ name %s in record type declaration", - tcx.sess.str_of(id))); + *tcx.sess.str_of(id))); tcx.sess.span_note(orig_sp, ~"First declaration of \ this field occurred here"); break; @@ -528,12 +530,15 @@ pub fn check_struct(ccx: @mut CrateCtxt, let self_ty = ty::node_id_to_type(tcx, id); do struct_def.dtor.iter() |dtor| { - let class_t = { self_ty: self_ty, - self_id: dtor.node.self_id, - def_id: local_def(id), - explicit_self: - spanned { node: ast::sty_by_ref, - span: codemap::dummy_sp() } }; + let class_t = SelfInfo { + self_ty: self_ty, + self_id: dtor.node.self_id, + def_id: local_def(id), + explicit_self: spanned { + node: ast::sty_by_ref, + span: codemap::dummy_sp() + } + }; // typecheck the dtor let dtor_dec = ast_util::dtor_dec(); check_bare_fn(ccx, &dtor_dec, @@ -565,7 +570,7 @@ pub fn check_item(ccx: @mut CrateCtxt, it: @ast::item) { ast::item_impl(_, _, ty, ms) => { let rp = ccx.tcx.region_paramd_items.find(&it.id); debug!("item_impl %s with id %d rp %?", - ccx.tcx.sess.str_of(it.ident), it.id, rp); + *ccx.tcx.sess.str_of(it.ident), it.id, rp); let self_ty = ccx.to_ty(rscope::type_rscope(rp), ty); for ms.each |m| { check_method(ccx, *m, self_ty, local_def(it.id)); @@ -620,7 +625,7 @@ pub fn check_item(ccx: @mut CrateCtxt, it: @ast::item) { } } -pub impl FnCtxt: AstConv { +pub impl AstConv for FnCtxt { fn tcx(@mut self) -> ty::ctxt { self.ccx.tcx } fn ccx(@mut self) -> @mut CrateCtxt { self.ccx } @@ -654,20 +659,20 @@ pub impl FnCtxt { } } -pub impl @mut FnCtxt: region_scope { - pure fn anon_region(span: span) -> Result { +pub impl region_scope for @mut FnCtxt { + pure fn anon_region(&self, span: span) -> Result { // XXX: Unsafe to work around purity unsafe { result::Ok(self.infcx().next_region_var_nb(span)) } } - pure fn self_region(_span: span) -> Result { + pure fn self_region(&self, _span: span) -> Result { // XXX: Unsafe to work around purity unsafe { self.search_in_scope_regions(ty::br_self) } } - pure fn named_region(_span: span, id: ast::ident) + pure fn named_region(&self, _span: span, id: ast::ident) -> Result { // XXX: Unsafe to work around purity unsafe { @@ -870,7 +875,7 @@ pub impl FnCtxt { self.region_lb = lb; let v = f(); self.region_lb = old_region_lb; - move v + v } fn region_var_if_parameterized(@mut self, @@ -1050,16 +1055,15 @@ pub fn impl_self_ty(vcx: &VtableContext, -> ty_param_substs_and_ty { let tcx = vcx.tcx(); - let {n_tps, region_param, raw_ty} = if did.crate == ast::local_crate { + let (n_tps, region_param, raw_ty) = if did.crate == ast::local_crate { let region_param = tcx.region_paramd_items.find(&did.node); match tcx.items.find(&did.node) { Some(ast_map::node_item(@ast::item { node: ast::item_impl(ref ts, _, st, _), _ }, _)) => { - {n_tps: ts.len(), - region_param: region_param, - raw_ty: vcx.ccx.to_ty(rscope::type_rscope(region_param), st)} + (ts.len(), region_param, + vcx.ccx.to_ty(rscope::type_rscope(region_param), st)) } Some(ast_map::node_item(@ast::item { node: ast::item_struct(_, ref ts), @@ -1070,23 +1074,20 @@ pub fn impl_self_ty(vcx: &VtableContext, (doing a no-op subst for the ty params; in the next step, we substitute in fresh vars for them) */ - {n_tps: ts.len(), - region_param: region_param, - raw_ty: ty::mk_struct(tcx, local_def(class_id), + (ts.len(), region_param, + ty::mk_struct(tcx, local_def(class_id), substs { self_r: rscope::bound_self_region(region_param), self_ty: None, tps: ty::ty_params_to_tys(tcx, /*bad*/copy *ts) - })} + })) } _ => { tcx.sess.bug(~"impl_self_ty: unbound item or item that \ doesn't have a self_ty"); } } } else { let ity = ty::lookup_item_type(tcx, did); - {n_tps: vec::len(*ity.bounds), - region_param: ity.region_param, - raw_ty: ity.ty} + (vec::len(*ity.bounds), ity.region_param, ity.ty) }; let self_r = if region_param.is_some() { @@ -1099,7 +1100,8 @@ pub fn impl_self_ty(vcx: &VtableContext, let substs = substs { self_r: self_r, self_ty: None, tps: tps }; let substd_ty = ty::subst(tcx, &substs, raw_ty); - {substs: substs, ty: substd_ty} + + ty_param_substs_and_ty { substs: substs, ty: substd_ty } } // Only for fields! Returns for methods> @@ -1163,7 +1165,7 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt, let ret_ty = match structure_of(fcx, sp, in_fty) { ty::ty_bare_fn(ty::BareFnTy {sig: ref sig, _}) | ty::ty_closure(ty::ClosureTy {sig: ref sig, _}) => { - let {fn_sig: sig, _} = + let (_, _, sig) = replace_bound_regions_in_fn_sig( tcx, @Nil, None, sig, |_br| fcx.infcx().next_region_var( @@ -1198,7 +1200,7 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt, tcx.sess.span_err(sp, msg); - vec::from_fn(expected_arg_count, |_| ty::mk_err(tcx)) + vec::from_fn(supplied_arg_count, |_| ty::mk_err(tcx)) }; sig.output @@ -1370,7 +1372,7 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt, fmt!("type `%s` does not implement any method in scope \ named `%s`", actual, - fcx.ccx.tcx.sess.str_of(method_name)) + *fcx.ccx.tcx.sess.str_of(method_name)) }, expr_t, None); @@ -1588,7 +1590,7 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt, // through the `unpack` function. It there is no expected type or // resolution is not possible (e.g., no constraints yet present), just // returns `none`. - fn unpack_expected(fcx: @mut FnCtxt, + fn unpack_expected(fcx: @mut FnCtxt, expected: Option, unpack: fn(&ty::sty) -> Option) -> Option { @@ -1628,7 +1630,7 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt, match expected_sty { Some(ty::ty_closure(ref cenv)) => { let id = expr.id; - let {fn_sig: sig, _} = + let (_, _, sig) = replace_bound_regions_in_fn_sig( tcx, @Nil, None, &cenv.sig, |br| ty::re_bound(ty::br_cap_avoid(id, @br))); @@ -1752,7 +1754,7 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt, |actual| { fmt!("attempted access of field `%s` on type `%s`, but \ no field or method with that name was found", - tcx.sess.str_of(field), actual) + *tcx.sess.str_of(field), actual) }, expr_t, None); // Add error type for the result @@ -1790,13 +1792,13 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt, tcx.sess.span_err( field.span, fmt!("structure has no field named `%s`", - tcx.sess.str_of(field.node.ident))); + *tcx.sess.str_of(field.node.ident))); } Some((_, true)) => { tcx.sess.span_err( field.span, fmt!("field `%s` specified more than once", - tcx.sess.str_of(field.node.ident))); + *tcx.sess.str_of(field.node.ident))); } Some((field_id, false)) => { let expected_field_type = @@ -1824,7 +1826,7 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt, let (_, seen) = class_field_map.get(&name); if !seen { missing_fields.push( - ~"`" + tcx.sess.str_of(name) + ~"`"); + ~"`" + *tcx.sess.str_of(name) + ~"`"); } } @@ -2543,7 +2545,7 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt, if !found { tcx.sess.span_err(f.span, ~"unknown field in record update: " + - tcx.sess.str_of(f.node.ident)); + *tcx.sess.str_of(f.node.ident)); fcx.write_ty(id, ty::mk_err(tcx)); return true; } @@ -2929,7 +2931,7 @@ pub fn ty_param_bounds_and_ty_for_def(fcx: @mut FnCtxt, } ast::def_fn(_, ast::extern_fn) => { // extern functions are just u8 pointers - return { + return ty_param_bounds_and_ty { bounds: @~[], region_param: None, ty: ty::mk_ptr( @@ -3151,7 +3153,7 @@ pub fn check_bounds_are_used(ccx: @mut CrateCtxt, if !*b { ccx.tcx.sess.span_err( span, fmt!("type parameter `%s` is unused", - ccx.tcx.sess.str_of(tps[i].ident))); + *ccx.tcx.sess.str_of(tps[i].ident))); } } } @@ -3164,7 +3166,7 @@ pub fn check_intrinsic_type(ccx: @mut CrateCtxt, it: @ast::foreign_item) { arg {mode: ast::expl(m), ty: ty} } let tcx = ccx.tcx; - let (n_tps, inputs, output) = match ccx.tcx.sess.str_of(it.ident) { + let (n_tps, inputs, output) = match *ccx.tcx.sess.str_of(it.ident) { ~"size_of" | ~"pref_align_of" | ~"min_align_of" => (1u, ~[], ty::mk_uint(ccx.tcx)), ~"init" => (1u, ~[], param(ccx, 0u)), diff --git a/src/librustc/middle/typeck/check/regionmanip.rs b/src/librustc/middle/typeck/check/regionmanip.rs index f0956df545c41..841365652ff29 100644 --- a/src/librustc/middle/typeck/check/regionmanip.rs +++ b/src/librustc/middle/typeck/check/regionmanip.rs @@ -13,7 +13,7 @@ use core::prelude::*; use middle::ty; -use middle::typeck::check::self_info; +use middle::typeck::check::SelfInfo; use middle::typeck::isr_alist; use util::common::indenter; use util::ppaux::region_to_str; @@ -29,19 +29,20 @@ use syntax::print::pprust::{expr_to_str}; pub fn replace_bound_regions_in_fn_sig( tcx: ty::ctxt, isr: isr_alist, - self_info: Option, + self_info: Option, fn_sig: &ty::FnSig, mapf: fn(ty::bound_region) -> ty::Region) -> - {isr: isr_alist, self_info: Option, fn_sig: ty::FnSig} { + (isr_alist, Option, ty::FnSig) { // Take self_info apart; the self_ty part is the only one we want // to update here. let self_ty = self_info.map(|s| s.self_ty); - let rebuild_self_info = |t| self_info.map(|s| {self_ty: t, ..*s}); + let rebuild_self_info = |t| self_info.map(|s| SelfInfo{self_ty: t, ..*s}); let mut all_tys = ty::tys_in_fn_sig(fn_sig); match self_info { - Some({explicit_self: codemap::spanned { node: ast::sty_region(m), + Some(SelfInfo { + explicit_self: codemap::spanned { node: ast::sty_region(m), _}, _}) => { let region = ty::re_bound(ty::br_self); let ty = ty::mk_rptr(tcx, region, @@ -76,14 +77,12 @@ pub fn replace_bound_regions_in_fn_sig( ppaux::fn_sig_to_str(tcx, &new_fn_sig)); // Glue updated self_ty back together with its original def_id. - let new_self_info: Option = match t_self { + let new_self_info: Option = match t_self { None => None, Some(t) => rebuild_self_info(t) }; - return {isr: isr, - self_info: new_self_info, - fn_sig: new_fn_sig}; + return (isr, new_self_info, new_fn_sig); // Takes `isr`, a (possibly empty) mapping from in-scope region // names ("isr"s) to their corresponding regions; `tys`, a list of diff --git a/src/librustc/middle/typeck/check/vtable.rs b/src/librustc/middle/typeck/check/vtable.rs index c2a7292c48dc6..e6b837fa9492a 100644 --- a/src/librustc/middle/typeck/check/vtable.rs +++ b/src/librustc/middle/typeck/check/vtable.rs @@ -315,8 +315,10 @@ pub fn lookup_vtable(vcx: &VtableContext, // of the thing that we're trying to cast // to some_trait. If not, then we try the next // impl. - let {substs: substs, ty: for_ty} = - impl_self_ty(vcx, location_info, im.did); + let ty::ty_param_substs_and_ty { + substs: substs, + ty: for_ty + } = impl_self_ty(vcx, location_info, im.did); match infer::mk_subty(vcx.infcx, false, location_info.span, diff --git a/src/librustc/middle/typeck/check/writeback.rs b/src/librustc/middle/typeck/check/writeback.rs index 1b27619938146..a16dab4bdeaef 100644 --- a/src/librustc/middle/typeck/check/writeback.rs +++ b/src/librustc/middle/typeck/check/writeback.rs @@ -17,7 +17,7 @@ use core::prelude::*; use middle::pat_util; use middle::ty::arg; use middle::ty; -use middle::typeck::check::{FnCtxt, self_info}; +use middle::typeck::check::{FnCtxt, SelfInfo}; use middle::typeck::infer::{force_all, resolve_all, resolve_region}; use middle::typeck::infer::{resolve_type}; use middle::typeck::infer; @@ -261,7 +261,7 @@ pub fn resolve_type_vars_in_expr(fcx: @mut FnCtxt, e: @ast::expr) -> bool { pub fn resolve_type_vars_in_fn(fcx: @mut FnCtxt, decl: &ast::fn_decl, blk: ast::blk, - self_info: Option) -> bool { + self_info: Option) -> bool { let wbcx = @mut WbCtxt { fcx: fcx, success: true }; let visit = mk_visitor(); (visit.visit_block)(blk, wbcx, visit); @@ -275,6 +275,10 @@ pub fn resolve_type_vars_in_fn(fcx: @mut FnCtxt, |_bm, pat_id, span, _path| { resolve_type_vars_for_node(wbcx, span, pat_id); } + // Privacy needs the type for the whole pattern, not just each binding + if !pat_util::pat_is_binding(fcx.tcx().def_map, arg.pat) { + resolve_type_vars_for_node(wbcx, arg.pat.span, arg.pat.id); + } } return wbcx.success; } diff --git a/src/librustc/middle/typeck/coherence.rs b/src/librustc/middle/typeck/coherence.rs index 64ac5a9ae820e..29738f2826661 100644 --- a/src/librustc/middle/typeck/coherence.rs +++ b/src/librustc/middle/typeck/coherence.rs @@ -145,7 +145,7 @@ pub fn get_base_type_def_id(inference_context: @mut InferCtxt, pub fn method_to_MethodInfo(ast_method: @method) -> @MethodInfo { - @{ + @MethodInfo { did: local_def(ast_method.id), n_tps: ast_method.tps.len(), ident: ast_method.ident, @@ -197,6 +197,7 @@ pub struct CoherenceChecker { } pub impl CoherenceChecker { + // IMPLICIT SELF WARNING: fix this! fn check_coherence(crate: @crate) { // Check implementations and traits. This populates the tables // containing the inherent methods and extension methods. It also @@ -204,7 +205,7 @@ pub impl CoherenceChecker { visit_crate(*crate, (), mk_simple_visitor(@SimpleVisitor { visit_item: |item| { debug!("(checking coherence) item '%s'", - self.crate_context.tcx.sess.str_of(item.ident)); + *self.crate_context.tcx.sess.str_of(item.ident)); match item.node { item_impl(_, opt_trait, _, _) => { @@ -235,7 +236,8 @@ pub impl CoherenceChecker { self.populate_destructor_table(); } - fn check_implementation(item: @item, associated_traits: ~[@trait_ref]) { + fn check_implementation(&self, + item: @item, associated_traits: ~[@trait_ref]) { let self_type = self.crate_context.tcx.tcache.get( &local_def(item.id)); @@ -245,7 +247,7 @@ pub impl CoherenceChecker { if associated_traits.len() == 0 { debug!("(checking implementation) no associated traits for item \ '%s'", - self.crate_context.tcx.sess.str_of(item.ident)); + *self.crate_context.tcx.sess.str_of(item.ident)); match get_base_type_def_id(self.inference_context, item.span, @@ -274,7 +276,7 @@ pub impl CoherenceChecker { ast_map::node_id_to_str( self.crate_context.tcx.items, trait_did.node, self.crate_context.tcx.sess.parse_sess.interner), - self.crate_context.tcx.sess.str_of(item.ident)); + *self.crate_context.tcx.sess.str_of(item.ident)); self.instantiate_default_methods(item.id, trait_did); @@ -302,7 +304,8 @@ pub impl CoherenceChecker { let implementation; match implementation_opt { None => { - implementation = self.create_impl_from_item(item); + implementation = + self.create_impl_from_item(item); } Some(copy existing_implementation) => { implementation = existing_implementation; @@ -321,7 +324,7 @@ pub impl CoherenceChecker { // Creates default method IDs and performs type substitutions for an impl // and trait pair. Then, for each provided method in the trait, inserts a // `ProvidedMethodInfo` instance into the `provided_method_sources` map. - fn instantiate_default_methods(impl_id: ast::node_id, + fn instantiate_default_methods(&self, impl_id: ast::node_id, trait_did: ast::def_id) { for self.each_provided_trait_method(trait_did) |trait_method| { // Synthesize an ID. @@ -330,7 +333,8 @@ pub impl CoherenceChecker { let new_did = local_def(new_id); // XXX: Perform substitutions. - let new_polytype = ty::lookup_item_type(tcx, trait_method.def_id); + let new_polytype = ty::lookup_item_type(tcx, + trait_method.def_id); tcx.tcache.insert(new_did, new_polytype); // Pair the new synthesized ID up with the @@ -345,7 +349,7 @@ pub impl CoherenceChecker { let provided_method_info = @ProvidedMethodInfo { - method_info: @{ + method_info: @MethodInfo { did: new_did, n_tps: trait_method.tps.len(), ident: trait_method.ident, @@ -362,7 +366,7 @@ pub impl CoherenceChecker { // method to that entry. debug!("(checking implementation) adding method `%s` \ to entry for existing trait", - self.crate_context.tcx.sess.str_of( + *self.crate_context.tcx.sess.str_of( provided_method_info.method_info.ident)); mis.push(provided_method_info); } @@ -370,7 +374,7 @@ pub impl CoherenceChecker { // If the trait doesn't have an entry yet, create one. debug!("(checking implementation) creating new entry \ for method `%s`", - self.crate_context.tcx.sess.str_of( + *self.crate_context.tcx.sess.str_of( provided_method_info.method_info.ident)); let method_infos = @DVec(); method_infos.push(provided_method_info); @@ -380,7 +384,8 @@ pub impl CoherenceChecker { } } - fn add_inherent_method(base_def_id: def_id, implementation: @Impl) { + fn add_inherent_method(&self, + base_def_id: def_id, implementation: @Impl) { let implementation_list; match self.crate_context.coherence_info.inherent_methods .find(&base_def_id) { @@ -397,7 +402,7 @@ pub impl CoherenceChecker { implementation_list.push(implementation); } - fn add_trait_method(trait_id: def_id, implementation: @Impl) { + fn add_trait_method(&self, trait_id: def_id, implementation: @Impl) { let implementation_list; match self.crate_context.coherence_info.extension_methods .find(&trait_id) { @@ -414,7 +419,7 @@ pub impl CoherenceChecker { implementation_list.push(implementation); } - fn check_implementation_coherence() { + fn check_implementation_coherence(&self) { let coherence_info = &mut self.crate_context.coherence_info; let extension_methods = &coherence_info.extension_methods; @@ -423,7 +428,7 @@ pub impl CoherenceChecker { } } - fn check_implementation_coherence_of(trait_def_id: def_id) { + fn check_implementation_coherence_of(&self, trait_def_id: def_id) { // Unify pairs of polytypes. do self.iter_impls_of_trait(trait_def_id) |a| { @@ -459,7 +464,8 @@ pub impl CoherenceChecker { // Adds an impl of trait trait_t for self type self_t; that impl // is the_impl - fn add_impl_for_trait(trait_t: def_id, self_t: t, the_impl: @Impl) { + fn add_impl_for_trait(&self, + trait_t: def_id, self_t: t, the_impl: @Impl) { debug!("Adding impl %? of %? for %s", the_impl.did, trait_t, ty_to_str(self.crate_context.tcx, self_t)); @@ -475,7 +481,7 @@ pub impl CoherenceChecker { } } - fn iter_impls_of_trait(trait_def_id: def_id, + fn iter_impls_of_trait(&self, trait_def_id: def_id, f: &fn(@Impl)) { let coherence_info = &mut self.crate_context.coherence_info; @@ -491,7 +497,7 @@ pub impl CoherenceChecker { } } - fn each_provided_trait_method( + fn each_provided_trait_method(&self, trait_did: ast::def_id, f: &fn(x: &ty::method) -> bool) { // Make a list of all the names of the provided methods. @@ -511,7 +517,7 @@ pub impl CoherenceChecker { } } - fn polytypes_unify(polytype_a: ty_param_bounds_and_ty, + fn polytypes_unify(&self, polytype_a: ty_param_bounds_and_ty, polytype_b: ty_param_bounds_and_ty) -> bool { let universally_quantified_a = @@ -527,7 +533,7 @@ pub impl CoherenceChecker { // Converts a polytype to a monotype by replacing all parameters with // type variables. Returns the monotype and the type variables created. - fn universally_quantify_polytype(polytype: ty_param_bounds_and_ty) + fn universally_quantify_polytype(&self, polytype: ty_param_bounds_and_ty) -> UniversalQuantificationResult { // NDM--this span is bogus. let self_region = @@ -553,12 +559,13 @@ pub impl CoherenceChecker { UniversalQuantificationResult { monotype: monotype, - type_variables: move type_parameters, + type_variables: type_parameters, bounds: polytype.bounds } } - fn can_unify_universally_quantified(a: &a/UniversalQuantificationResult, + fn can_unify_universally_quantified(&self, + a: &a/UniversalQuantificationResult, b: &a/UniversalQuantificationResult) -> bool { let mut might_unify = true; @@ -610,12 +617,13 @@ pub impl CoherenceChecker { might_unify } - fn get_self_type_for_implementation(implementation: @Impl) + fn get_self_type_for_implementation(&self, implementation: @Impl) -> ty_param_bounds_and_ty { return self.crate_context.tcx.tcache.get(&implementation.did); } // Privileged scope checking + // IMPLICIT SELF WARNING: fix this! fn check_privileged_scopes(crate: @crate) { visit_crate(*crate, (), mk_vt(@Visitor { visit_item: |item, _context, visitor| { @@ -699,7 +707,7 @@ pub impl CoherenceChecker { })); } - fn trait_ref_to_trait_def_id(trait_ref: @trait_ref) -> def_id { + fn trait_ref_to_trait_def_id(&self, trait_ref: @trait_ref) -> def_id { let def_map = self.crate_context.tcx.def_map; let trait_def = def_map.get(&trait_ref.ref_id); let trait_id = def_id_of_def(trait_def); @@ -708,7 +716,7 @@ pub impl CoherenceChecker { // This check doesn't really have anything to do with coherence. It's // here for historical reasons - fn please_check_that_trait_methods_are_implemented( + fn please_check_that_trait_methods_are_implemented(&self, all_methods: &mut ~[@MethodInfo], trait_did: def_id, trait_ref_span: span) { @@ -730,19 +738,19 @@ pub impl CoherenceChecker { tcx.sess.span_err(trait_ref_span, fmt!("missing method `%s`", - tcx.sess.str_of(method.ident))); + *tcx.sess.str_of(method.ident))); } } // Converts an implementation in the AST to an Impl structure. - fn create_impl_from_item(item: @item) -> @Impl { + fn create_impl_from_item(&self, item: @item) -> @Impl { fn add_provided_methods(all_methods: &mut ~[@MethodInfo], all_provided_methods: ~[@ProvidedMethodInfo], sess: driver::session::Session) { for all_provided_methods.each |provided_method| { debug!( "(creating impl) adding provided method `%s` to impl", - sess.str_of(provided_method.method_info.ident)); + *sess.str_of(provided_method.method_info.ident)); vec::push(&mut *all_methods, provided_method.method_info); } } @@ -792,7 +800,7 @@ pub impl CoherenceChecker { } } - return @{ + return @Impl { did: local_def(item.id), ident: item.ident, methods: methods @@ -806,7 +814,7 @@ pub impl CoherenceChecker { } } - fn span_of_impl(implementation: @Impl) -> span { + fn span_of_impl(&self, implementation: @Impl) -> span { assert implementation.did.crate == local_crate; match self.crate_context.tcx.items.find(&implementation.did.node) { Some(node_item(item, _)) => { @@ -822,7 +830,7 @@ pub impl CoherenceChecker { // External crate handling - fn add_impls_for_module(impls_seen: HashMap, + fn add_impls_for_module(&self, impls_seen: HashMap, crate_store: @mut CStore, module_def_id: def_id) { let implementations = get_impls_for_mod(crate_store, @@ -863,7 +871,7 @@ pub impl CoherenceChecker { session.bug(fmt!( "no base type for external impl \ with no trait: %s (type %s)!", - session.str_of(implementation.ident), + *session.str_of(implementation.ident), ty_to_str(self.crate_context.tcx,self_type.ty))); } Some(_) => { @@ -907,7 +915,8 @@ pub impl CoherenceChecker { } } - fn add_default_methods_for_external_trait(trait_def_id: ast::def_id) { + fn add_default_methods_for_external_trait(&self, + trait_def_id: ast::def_id) { let tcx = self.crate_context.tcx; let pmm = tcx.provided_methods; @@ -925,7 +934,7 @@ pub impl CoherenceChecker { let provided_method_info = @ProvidedMethodInfo { - method_info: @{ + method_info: @MethodInfo { did: new_did, n_tps: trait_method_info.ty.tps.len(), ident: trait_method_info.ty.ident, @@ -942,7 +951,7 @@ pub impl CoherenceChecker { // Adds implementations and traits from external crates to the coherence // info. - fn add_external_crates() { + fn add_external_crates(&self) { let impls_seen = HashMap(); let crate_store = self.crate_context.tcx.sess.cstore; @@ -983,7 +992,7 @@ pub impl CoherenceChecker { // Destructors // - fn populate_destructor_table() { + fn populate_destructor_table(&self) { let coherence_info = &mut self.crate_context.coherence_info; let tcx = self.crate_context.tcx; let drop_trait = tcx.lang_items.drop_trait(); diff --git a/src/librustc/middle/typeck/collect.rs b/src/librustc/middle/typeck/collect.rs index 2a42e75f53d47..96c76b52181c1 100644 --- a/src/librustc/middle/typeck/collect.rs +++ b/src/librustc/middle/typeck/collect.rs @@ -34,7 +34,7 @@ use core::prelude::*; use metadata::csearch; use middle::ty::{InstantiatedTraitRef, arg}; -use middle::ty::{substs, ty_param_substs_and_ty}; +use middle::ty::{substs, ty_param_bounds_and_ty, ty_param_substs_and_ty}; use middle::ty; use middle::typeck::astconv::{AstConv, ty_of_arg}; use middle::typeck::astconv::{ast_ty_to_ty}; @@ -115,13 +115,13 @@ pub fn collect_item_types(ccx: @mut CrateCtxt, crate: @ast::crate) { } pub impl @mut CrateCtxt { - fn to_ty(rs: RS, ast_ty: @ast::Ty) + fn to_ty(rs: RS, ast_ty: @ast::Ty) -> ty::t { ast_ty_to_ty(self, rs, ast_ty) } } -pub impl CrateCtxt: AstConv { +pub impl AstConv for CrateCtxt { fn tcx(@mut self) -> ty::ctxt { self.tcx } fn ccx(@mut self) -> @mut CrateCtxt { self } @@ -174,9 +174,11 @@ pub fn get_enum_variant_types(ccx: @mut CrateCtxt, } ast::struct_variant_kind(struct_def) => { - let tpt = {bounds: ty_param_bounds(ccx, ty_params), - region_param: rp, - ty: enum_ty}; + let tpt = ty_param_bounds_and_ty { + bounds: ty_param_bounds(ccx, ty_params), + region_param: rp, + ty: enum_ty + }; convert_struct(ccx, rp, @@ -203,9 +205,11 @@ pub fn get_enum_variant_types(ccx: @mut CrateCtxt, match result_ty { None => {} Some(result_ty) => { - let tpt = {bounds: ty_param_bounds(ccx, ty_params), - region_param: rp, - ty: result_ty}; + let tpt = ty_param_bounds_and_ty { + bounds: ty_param_bounds(ccx, ty_params), + region_param: rp, + ty: result_ty + }; tcx.tcache.insert(local_def(variant.node.id), tpt); write_ty_to_tcx(tcx, variant.node.id, result_ty); } @@ -261,9 +265,10 @@ pub fn ensure_trait_methods(ccx: @mut CrateCtxt, let bounds = @(*trait_bounds + ~[@~[ty::bound_trait(trait_ty)]] + *m.tps); ccx.tcx.tcache.insert(local_def(am.id), - {bounds: bounds, - region_param: rp, - ty: ty}); + ty_param_bounds_and_ty { + bounds: bounds, + region_param: rp, + ty: ty}); } @@ -320,7 +325,7 @@ pub fn ensure_supertraits(ccx: @mut CrateCtxt, instantiated.push(InstantiatedTraitRef { def_id: did, tpt: tpt }); } tcx.supertraits.insert(local_def(id), - @dvec::unwrap(move instantiated)); + @dvec::unwrap(instantiated)); } /** @@ -357,20 +362,20 @@ pub fn compare_impl_method(tcx: ty::ctxt, tcx.sess.span_fatal(cm.span, fmt!("method `%s` is declared as \ static in its impl, but not in \ - its trait", tcx.sess.str_of(impl_m.ident))); + its trait", *tcx.sess.str_of(impl_m.ident))); } else if trait_m.self_ty == ast::sty_static { tcx.sess.span_fatal(cm.span, fmt!("method `%s` is declared as \ static in its trait, but not in \ - its impl", tcx.sess.str_of(impl_m.ident))); + its impl", *tcx.sess.str_of(impl_m.ident))); } else { tcx.sess.span_err( cm.span, fmt!("method `%s`'s self type does \ not match the trait method's \ - self type", tcx.sess.str_of(impl_m.ident))); + self type", *tcx.sess.str_of(impl_m.ident))); } } @@ -379,7 +384,7 @@ pub fn compare_impl_method(tcx: ty::ctxt, cm.span, fmt!("method `%s` has %u type %s, but its trait \ declaration has %u type %s", - tcx.sess.str_of(trait_m.ident), impl_m.tps.len(), + *tcx.sess.str_of(trait_m.ident), impl_m.tps.len(), pluralize(impl_m.tps.len(), ~"parameter"), trait_m.tps.len(), pluralize(trait_m.tps.len(), ~"parameter"))); @@ -391,7 +396,7 @@ pub fn compare_impl_method(tcx: ty::ctxt, cm.span, fmt!("method `%s` has %u parameters \ but the trait has %u", - tcx.sess.str_of(trait_m.ident), + *tcx.sess.str_of(trait_m.ident), vec::len(impl_m.fty.sig.inputs), vec::len(trait_m.fty.sig.inputs))); return; @@ -412,7 +417,7 @@ pub fn compare_impl_method(tcx: ty::ctxt, fmt!("in method `%s`, \ type parameter %u has %u %s, but the same type \ parameter in its trait declaration has %u %s", - tcx.sess.str_of(trait_m.ident), + *tcx.sess.str_of(trait_m.ident), i, impl_param_bounds.len(), pluralize(impl_param_bounds.len(), ~"bound"), trait_param_bounds.len(), @@ -466,7 +471,7 @@ pub fn compare_impl_method(tcx: ty::ctxt, tcx.sess.span_err( cm.span, fmt!("method `%s` has an incompatible type: %s", - tcx.sess.str_of(trait_m.ident), + *tcx.sess.str_of(trait_m.ident), ty::type_err_to_str(tcx, terr))); ty::note_and_explain_type_err(tcx, terr); } @@ -526,7 +531,7 @@ pub fn check_methods_against_trait(ccx: @mut CrateCtxt, tcx.sess.span_err( impl_m.span, fmt!("method `%s` is not a member of trait `%s`", - tcx.sess.str_of(impl_m.mty.ident), + *tcx.sess.str_of(impl_m.mty.ident), path_to_str(a_trait_ty.path, tcx.sess.intr()))); } } @@ -541,9 +546,11 @@ pub fn convert_field(ccx: @mut CrateCtxt, write_ty_to_tcx(ccx.tcx, v.node.id, tt); /* add the field to the tcache */ ccx.tcx.tcache.insert(local_def(v.node.id), - {bounds: bounds, - region_param: rp, - ty: tt}); + ty::ty_param_bounds_and_ty { + bounds: bounds, + region_param: rp, + ty: tt + }); } pub struct ConvertedMethod { @@ -569,9 +576,11 @@ pub fn convert_methods(ccx: @mut CrateCtxt, // n.b.: the type of a method is parameterized by both // the tps on the receiver and those on the method itself - {bounds: @(vec::append(/*bad*/copy *rcvr_bounds, *bounds)), - region_param: rp, - ty: fty}); + ty_param_bounds_and_ty { + bounds: @(vec::append(/*bad*/copy *rcvr_bounds, *bounds)), + region_param: rp, + ty: fty + }); write_ty_to_tcx(tcx, m.id, fty); ConvertedMethod {mty: mty, id: m.id, span: m.span, body_id: m.body.node.id} @@ -596,7 +605,7 @@ pub fn convert(ccx: @mut CrateCtxt, it: @ast::item) { let tcx = ccx.tcx; let rp = tcx.region_paramd_items.find(&it.id); debug!("convert: item %s with id %d rp %?", - tcx.sess.str_of(it.ident), it.id, rp); + *tcx.sess.str_of(it.ident), it.id, rp); match /*bad*/copy it.node { // These don't define types. ast::item_foreign_mod(_) | ast::item_mod(_) => {} @@ -615,9 +624,10 @@ pub fn convert(ccx: @mut CrateCtxt, it: @ast::item) { let selfty = ccx.to_ty(type_rscope(rp), selfty); write_ty_to_tcx(tcx, it.id, selfty); tcx.tcache.insert(local_def(it.id), - {bounds: i_bounds, - region_param: rp, - ty: selfty}); + ty_param_bounds_and_ty { + bounds: i_bounds, + region_param: rp, + ty: selfty}); // XXX: Bad copy of `ms` below. let cms = convert_methods(ccx, /*bad*/copy *ms, rp, i_bounds); @@ -636,7 +646,7 @@ pub fn convert(ccx: @mut CrateCtxt, it: @ast::item) { let (_, provided_methods) = split_trait_methods(/*bad*/copy *trait_methods); - let {bounds, _} = mk_substs(ccx, /*bad*/copy *tps, rp); + let (bounds, _) = mk_substs(ccx, /*bad*/copy *tps, rp); let _ = convert_methods(ccx, provided_methods, rp, bounds); } ast::item_struct(struct_def, tps) => { @@ -682,16 +692,17 @@ pub fn convert_struct(ccx: @mut CrateCtxt, ast_util::dtor_dec())); write_ty_to_tcx(tcx, dtor.node.id, t_dtor); tcx.tcache.insert(local_def(dtor.node.id), - {bounds: tpt.bounds, - region_param: rp, - ty: t_dtor}); + ty_param_bounds_and_ty { + bounds: tpt.bounds, + region_param: rp, + ty: t_dtor}); }; // Write the type of each of the members for struct_def.fields.each |f| { convert_field(ccx, rp, tpt.bounds, *f); } - let {bounds: _, substs: substs} = mk_substs(ccx, tps, rp); + let (_, substs) = mk_substs(ccx, tps, rp); let selfty = ty::mk_struct(tcx, local_def(id), substs); // If this struct is enum-like or tuple-like, create the type of its @@ -711,7 +722,7 @@ pub fn convert_struct(ccx: @mut CrateCtxt, &local_def(field.node.id)).ty); let ctor_fn_ty = ty::mk_ctor_fn(tcx, inputs, selfty); write_ty_to_tcx(tcx, ctor_id, ctor_fn_ty); - tcx.tcache.insert(local_def(ctor_id), { + tcx.tcache.insert(local_def(ctor_id), ty_param_bounds_and_ty { bounds: tpt.bounds, region_param: tpt.region_param, ty: ctor_fn_ty @@ -733,27 +744,31 @@ pub fn convert_foreign(ccx: @mut CrateCtxt, i: @ast::foreign_item) { pub fn ty_of_method(ccx: @mut CrateCtxt, m: @ast::method, rp: Option) -> ty::method { - {ident: m.ident, - tps: ty_param_bounds(ccx, m.tps), - fty: astconv::ty_of_bare_fn(ccx, type_rscope(rp), m.purity, - ast::RustAbi, m.decl), - self_ty: m.self_ty.node, - vis: m.vis, - def_id: local_def(m.id)} + ty::method { + ident: m.ident, + tps: ty_param_bounds(ccx, m.tps), + fty: astconv::ty_of_bare_fn(ccx, type_rscope(rp), m.purity, + ast::RustAbi, m.decl), + self_ty: m.self_ty.node, + vis: m.vis, + def_id: local_def(m.id) + } } pub fn ty_of_ty_method(self: @mut CrateCtxt, m: ast::ty_method, rp: Option, id: ast::def_id) -> ty::method { - {ident: m.ident, - tps: ty_param_bounds(self, m.tps), - fty: astconv::ty_of_bare_fn(self, type_rscope(rp), m.purity, - ast::RustAbi, m.decl), - // assume public, because this is only invoked on trait methods - self_ty: m.self_ty.node, - vis: ast::public, - def_id: id} + ty::method { + ident: m.ident, + tps: ty_param_bounds(self, m.tps), + fty: astconv::ty_of_bare_fn(self, type_rscope(rp), m.purity, + ast::RustAbi, m.decl), + // assume public, because this is only invoked on trait methods + self_ty: m.self_ty.node, + vis: ast::public, + def_id: id + } } /* @@ -805,11 +820,13 @@ pub fn ty_of_item(ccx: @mut CrateCtxt, it: @ast::item) let bounds = ty_param_bounds(ccx, tps); let tofd = astconv::ty_of_bare_fn(ccx, empty_rscope, purity, ast::RustAbi, decl); - let tpt = {bounds: bounds, - region_param: None, - ty: ty::mk_bare_fn(ccx.tcx, tofd)}; + let tpt = ty_param_bounds_and_ty { + bounds: bounds, + region_param: None, + ty: ty::mk_bare_fn(ccx.tcx, tofd) + }; debug!("type of %s (id %d) is %s", - tcx.sess.str_of(it.ident), + *tcx.sess.str_of(it.ident), it.id, ppaux::ty_to_str(tcx, tpt.ty)); ccx.tcx.tcache.insert(local_def(it.id), tpt); @@ -833,9 +850,11 @@ pub fn ty_of_item(ccx: @mut CrateCtxt, it: @ast::item) ty::mk_with_id(tcx, t0, def_id) } }; - {bounds: ty_param_bounds(ccx, tps), - region_param: rp, - ty: ty} + ty_param_bounds_and_ty { + bounds: ty_param_bounds(ccx, tps), + region_param: rp, + ty: ty + } }; tcx.tcache.insert(local_def(it.id), tpt); @@ -843,29 +862,35 @@ pub fn ty_of_item(ccx: @mut CrateCtxt, it: @ast::item) } ast::item_enum(_, tps) => { // Create a new generic polytype. - let {bounds: bounds, substs: substs} = mk_substs(ccx, tps, rp); + let (bounds, substs) = mk_substs(ccx, tps, rp); let t = ty::mk_enum(tcx, local_def(it.id), substs); - let tpt = {bounds: bounds, - region_param: rp, - ty: t}; + let tpt = ty_param_bounds_and_ty { + bounds: bounds, + region_param: rp, + ty: t + }; tcx.tcache.insert(local_def(it.id), tpt); return tpt; } ast::item_trait(tps, _, _) => { - let {bounds: bounds, substs: substs} = mk_substs(ccx, tps, rp); + let (bounds, substs) = mk_substs(ccx, tps, rp); let t = ty::mk_trait(tcx, local_def(it.id), substs, ty::vstore_box); - let tpt = {bounds: bounds, - region_param: rp, - ty: t}; + let tpt = ty_param_bounds_and_ty { + bounds: bounds, + region_param: rp, + ty: t + }; tcx.tcache.insert(local_def(it.id), tpt); return tpt; } ast::item_struct(_, tps) => { - let {bounds: bounds, substs: substs} = mk_substs(ccx, tps, rp); + let (bounds, substs) = mk_substs(ccx, tps, rp); let t = ty::mk_struct(tcx, local_def(it.id), substs); - let tpt = {bounds: bounds, - region_param: rp, - ty: t}; + let tpt = ty_param_bounds_and_ty { + bounds: bounds, + region_param: rp, + ty: t + }; tcx.tcache.insert(local_def(it.id), tpt); return tpt; } @@ -883,7 +908,7 @@ pub fn ty_of_foreign_item(ccx: @mut CrateCtxt, it: @ast::foreign_item) } ast::foreign_item_const(t) => { let rb = in_binding_rscope(empty_rscope); - return { + return ty::ty_param_bounds_and_ty { bounds: @~[], region_param: None, ty: ast_ty_to_ty(ccx, rb, t) @@ -964,32 +989,33 @@ pub fn ty_of_foreign_fn_decl(ccx: @mut CrateCtxt, purity: ast::unsafe_fn, sig: ty::FnSig {inputs: input_tys, output: output_ty} }); - let tpt = {bounds: bounds, region_param: None, ty: t_fn}; + let tpt = ty_param_bounds_and_ty { + bounds: bounds, + region_param: None, + ty: t_fn + }; ccx.tcx.tcache.insert(def_id, tpt); return tpt; } pub fn mk_ty_params(ccx: @mut CrateCtxt, atps: ~[ast::ty_param]) - -> {bounds: @~[ty::param_bounds], params: ~[ty::t]} { + -> (@~[ty::param_bounds], ~[ty::t]) { let mut i = 0u; let bounds = ty_param_bounds(ccx, atps); - {bounds: bounds, - params: vec::map(atps, |atp| { + (bounds, + vec::map(atps, |atp| { let t = ty::mk_param(ccx.tcx, i, local_def(atp.id)); i += 1u; t - })} + })) } pub fn mk_substs(ccx: @mut CrateCtxt, +atps: ~[ast::ty_param], rp: Option) - -> {bounds: @~[ty::param_bounds], substs: ty::substs} { - let {bounds, params} = mk_ty_params(ccx, atps); + -> (@~[ty::param_bounds], ty::substs) { + let (bounds, params) = mk_ty_params(ccx, atps); let self_r = rscope::bound_self_region(rp); - { - bounds: bounds, - substs: substs { self_r: self_r, self_ty: None, tps: params } - } + (bounds, substs { self_r: self_r, self_ty: None, tps: params }) } diff --git a/src/librustc/middle/typeck/infer/combine.rs b/src/librustc/middle/typeck/infer/combine.rs index 54b5867bfa239..1c6b1507629c5 100644 --- a/src/librustc/middle/typeck/infer/combine.rs +++ b/src/librustc/middle/typeck/infer/combine.rs @@ -78,37 +78,38 @@ pub fn macros() { } pub trait Combine { - fn infcx() -> @mut InferCtxt; - fn tag() -> ~str; - fn a_is_expected() -> bool; - fn span() -> span; - - fn sub() -> Sub; - fn lub() -> Lub; - fn glb() -> Glb; - - fn mts(a: ty::mt, b: ty::mt) -> cres; - fn contratys(a: ty::t, b: ty::t) -> cres; - fn tys(a: ty::t, b: ty::t) -> cres; - fn tps(as_: &[ty::t], bs: &[ty::t]) -> cres<~[ty::t]>; - fn self_tys(a: Option, b: Option) -> cres>; - fn substs(did: ast::def_id, as_: &ty::substs, + fn infcx(&self) -> @mut InferCtxt; + fn tag(&self) -> ~str; + fn a_is_expected(&self) -> bool; + fn span(&self) -> span; + + fn sub(&self) -> Sub; + fn lub(&self) -> Lub; + fn glb(&self) -> Glb; + + fn mts(&self, a: ty::mt, b: ty::mt) -> cres; + fn contratys(&self, a: ty::t, b: ty::t) -> cres; + fn tys(&self, a: ty::t, b: ty::t) -> cres; + fn tps(&self, as_: &[ty::t], bs: &[ty::t]) -> cres<~[ty::t]>; + fn self_tys(&self, a: Option, b: Option) + -> cres>; + fn substs(&self, did: ast::def_id, as_: &ty::substs, bs: &ty::substs) -> cres; - fn bare_fn_tys(a: &ty::BareFnTy, + fn bare_fn_tys(&self, a: &ty::BareFnTy, b: &ty::BareFnTy) -> cres; - fn closure_tys(a: &ty::ClosureTy, + fn closure_tys(&self, a: &ty::ClosureTy, b: &ty::ClosureTy) -> cres; - fn fn_sigs(a: &ty::FnSig, b: &ty::FnSig) -> cres; - fn flds(a: ty::field, b: ty::field) -> cres; - fn modes(a: ast::mode, b: ast::mode) -> cres; - fn args(a: ty::arg, b: ty::arg) -> cres; - fn sigils(p1: ast::Sigil, p2: ast::Sigil) -> cres; - fn purities(a: purity, b: purity) -> cres; - fn abis(a: ast::Abi, b: ast::Abi) -> cres; - fn oncenesses(a: Onceness, b: Onceness) -> cres; - fn contraregions(a: ty::Region, b: ty::Region) -> cres; - fn regions(a: ty::Region, b: ty::Region) -> cres; - fn vstores(vk: ty::terr_vstore_kind, + fn fn_sigs(&self, a: &ty::FnSig, b: &ty::FnSig) -> cres; + fn flds(&self, a: ty::field, b: ty::field) -> cres; + fn modes(&self, a: ast::mode, b: ast::mode) -> cres; + fn args(&self, a: ty::arg, b: ty::arg) -> cres; + fn sigils(&self, p1: ast::Sigil, p2: ast::Sigil) -> cres; + fn purities(&self, a: purity, b: purity) -> cres; + fn abis(&self, a: ast::Abi, b: ast::Abi) -> cres; + fn oncenesses(&self, a: Onceness, b: Onceness) -> cres; + fn contraregions(&self, a: ty::Region, b: ty::Region) -> cres; + fn regions(&self, a: ty::Region, b: ty::Region) -> cres; + fn vstores(&self, vk: ty::terr_vstore_kind, a: ty::vstore, b: ty::vstore) -> cres; } @@ -121,9 +122,9 @@ pub struct CombineFields { pub fn expected_found( self: &C, +a: T, +b: T) -> ty::expected_found { if self.a_is_expected() { - ty::expected_found {expected: move a, found: move b} + ty::expected_found {expected: a, found: b} } else { - ty::expected_found {expected: move b, found: move a} + ty::expected_found {expected: b, found: a} } } @@ -290,7 +291,7 @@ pub fn super_self_tys( } } -pub fn super_sigils( +pub fn super_sigils( self: &C, p1: ast::Sigil, p2: ast::Sigil) -> cres { if p1 == p2 { Ok(p1) diff --git a/src/librustc/middle/typeck/infer/glb.rs b/src/librustc/middle/typeck/infer/glb.rs index 9778ac670c849..5008791723eee 100644 --- a/src/librustc/middle/typeck/infer/glb.rs +++ b/src/librustc/middle/typeck/infer/glb.rs @@ -27,17 +27,17 @@ use std::list; pub enum Glb = CombineFields; // "greatest lower bound" (common subtype) -pub impl Glb: Combine { - fn infcx() -> @mut InferCtxt { self.infcx } - fn tag() -> ~str { ~"glb" } - fn a_is_expected() -> bool { self.a_is_expected } - fn span() -> span { self.span } +pub impl Combine for Glb { + fn infcx(&self) -> @mut InferCtxt { self.infcx } + fn tag(&self) -> ~str { ~"glb" } + fn a_is_expected(&self) -> bool { self.a_is_expected } + fn span(&self) -> span { self.span } - fn sub() -> Sub { Sub(*self) } - fn lub() -> Lub { Lub(*self) } - fn glb() -> Glb { Glb(*self) } + fn sub(&self) -> Sub { Sub(**self) } + fn lub(&self) -> Lub { Lub(**self) } + fn glb(&self) -> Glb { Glb(**self) } - fn mts(a: ty::mt, b: ty::mt) -> cres { + fn mts(&self, a: ty::mt, b: ty::mt) -> cres { let tcx = self.infcx.tcx; debug!("%s.mts(%s, %s)", @@ -49,17 +49,17 @@ pub impl Glb: Combine { // If one side or both is mut, then the GLB must use // the precise type from the mut side. (m_mutbl, m_const) => { - Sub(*self).tys(a.ty, b.ty).chain(|_t| { + Sub(**self).tys(a.ty, b.ty).chain(|_t| { Ok(ty::mt {ty: a.ty, mutbl: m_mutbl}) }) } (m_const, m_mutbl) => { - Sub(*self).tys(b.ty, a.ty).chain(|_t| { + Sub(**self).tys(b.ty, a.ty).chain(|_t| { Ok(ty::mt {ty: b.ty, mutbl: m_mutbl}) }) } (m_mutbl, m_mutbl) => { - eq_tys(&self, a.ty, b.ty).then(|| { + eq_tys(self, a.ty, b.ty).then(|| { Ok(ty::mt {ty: a.ty, mutbl: m_mutbl}) }) } @@ -90,11 +90,11 @@ pub impl Glb: Combine { } } - fn contratys(a: ty::t, b: ty::t) -> cres { - Lub(*self).tys(a, b) + fn contratys(&self, a: ty::t, b: ty::t) -> cres { + Lub(**self).tys(a, b) } - fn purities(a: purity, b: purity) -> cres { + fn purities(&self, a: purity, b: purity) -> cres { match (a, b) { (pure_fn, _) | (_, pure_fn) => Ok(pure_fn), (extern_fn, _) | (_, extern_fn) => Ok(extern_fn), @@ -103,14 +103,14 @@ pub impl Glb: Combine { } } - fn oncenesses(a: Onceness, b: Onceness) -> cres { + fn oncenesses(&self, a: Onceness, b: Onceness) -> cres { match (a, b) { (Many, _) | (_, Many) => Ok(Many), (Once, Once) => Ok(Once) } } - fn regions(a: ty::Region, b: ty::Region) -> cres { + fn regions(&self, a: ty::Region, b: ty::Region) -> cres { debug!("%s.regions(%?, %?)", self.tag(), a.inf_str(self.infcx), @@ -121,34 +121,35 @@ pub impl Glb: Combine { } } - fn contraregions(a: ty::Region, b: ty::Region) -> cres { - Lub(*self).regions(a, b) + fn contraregions(&self, a: ty::Region, b: ty::Region) + -> cres { + Lub(**self).regions(a, b) } - fn tys(a: ty::t, b: ty::t) -> cres { - super_lattice_tys(&self, a, b) + fn tys(&self, a: ty::t, b: ty::t) -> cres { + super_lattice_tys(self, a, b) } // Traits please (FIXME: #2794): - fn flds(a: ty::field, b: ty::field) -> cres { - super_flds(&self, a, b) + fn flds(&self, a: ty::field, b: ty::field) -> cres { + super_flds(self, a, b) } - fn vstores(vk: ty::terr_vstore_kind, + fn vstores(&self, vk: ty::terr_vstore_kind, a: ty::vstore, b: ty::vstore) -> cres { - super_vstores(&self, vk, a, b) + super_vstores(self, vk, a, b) } - fn modes(a: ast::mode, b: ast::mode) -> cres { - super_modes(&self, a, b) + fn modes(&self, a: ast::mode, b: ast::mode) -> cres { + super_modes(self, a, b) } - fn args(a: ty::arg, b: ty::arg) -> cres { - super_args(&self, a, b) + fn args(&self, a: ty::arg, b: ty::arg) -> cres { + super_args(self, a, b) } - fn fn_sigs(a: &ty::FnSig, b: &ty::FnSig) -> cres { + fn fn_sigs(&self, a: &ty::FnSig, b: &ty::FnSig) -> cres { // Note: this is a subtle algorithm. For a full explanation, // please see the large comment in `region_inference.rs`. @@ -166,14 +167,14 @@ pub impl Glb: Combine { let (a_with_fresh, a_isr) = self.infcx.replace_bound_regions_with_fresh_regions( self.span, a); - let a_vars = var_ids(&self, a_isr); + let a_vars = var_ids(self, a_isr); let (b_with_fresh, b_isr) = self.infcx.replace_bound_regions_with_fresh_regions( self.span, b); - let b_vars = var_ids(&self, b_isr); + let b_vars = var_ids(self, b_isr); // Collect constraints. - let sig0 = if_ok!(super_fn_sigs(&self, &a_with_fresh, &b_with_fresh)); + let sig0 = if_ok!(super_fn_sigs(self, &a_with_fresh, &b_with_fresh)); debug!("sig0 = %s", sig0.inf_str(self.infcx)); // Generalize the regions appearing in fn_ty0 if possible @@ -182,11 +183,11 @@ pub impl Glb: Combine { let sig1 = self.infcx.fold_regions_in_sig( &sig0, - |r, _in_fn| generalize_region(&self, snapshot, + |r, _in_fn| generalize_region(self, snapshot, new_vars, a_isr, a_vars, b_vars, r)); debug!("sig1 = %s", sig1.inf_str(self.infcx)); - return Ok(move sig1); + return Ok(sig1); fn generalize_region(self: &Glb, snapshot: uint, @@ -267,36 +268,37 @@ pub impl Glb: Combine { } } - fn sigils(p1: ast::Sigil, p2: ast::Sigil) -> cres { - super_sigils(&self, p1, p2) + fn sigils(&self, p1: ast::Sigil, p2: ast::Sigil) -> cres { + super_sigils(self, p1, p2) } - fn abis(p1: ast::Abi, p2: ast::Abi) -> cres { - super_abis(&self, p1, p2) + fn abis(&self, p1: ast::Abi, p2: ast::Abi) -> cres { + super_abis(self, p1, p2) } - fn bare_fn_tys(a: &ty::BareFnTy, + fn bare_fn_tys(&self, a: &ty::BareFnTy, b: &ty::BareFnTy) -> cres { - super_bare_fn_tys(&self, a, b) + super_bare_fn_tys(self, a, b) } - fn closure_tys(a: &ty::ClosureTy, + fn closure_tys(&self, a: &ty::ClosureTy, b: &ty::ClosureTy) -> cres { - super_closure_tys(&self, a, b) + super_closure_tys(self, a, b) } - fn substs(did: ast::def_id, + fn substs(&self, did: ast::def_id, as_: &ty::substs, bs: &ty::substs) -> cres { - super_substs(&self, did, as_, bs) + super_substs(self, did, as_, bs) } - fn tps(as_: &[ty::t], bs: &[ty::t]) -> cres<~[ty::t]> { - super_tps(&self, as_, bs) + fn tps(&self, as_: &[ty::t], bs: &[ty::t]) -> cres<~[ty::t]> { + super_tps(self, as_, bs) } - fn self_tys(a: Option, b: Option) -> cres> { - super_self_tys(&self, a, b) + fn self_tys(&self, a: Option, b: Option) + -> cres> { + super_self_tys(self, a, b) } } diff --git a/src/librustc/middle/typeck/infer/lattice.rs b/src/librustc/middle/typeck/infer/lattice.rs index 709864c0d13e2..1a919ac0f3b0b 100644 --- a/src/librustc/middle/typeck/infer/lattice.rs +++ b/src/librustc/middle/typeck/infer/lattice.rs @@ -50,30 +50,34 @@ use middle::typeck::infer::to_str::InferStr; use std::list; pub trait LatticeValue { - static fn sub(cf: &CombineFields, a: &Self, b: &Self) -> ures; - static fn lub(cf: &CombineFields, a: &Self, b: &Self) -> cres; - static fn glb(cf: &CombineFields, a: &Self, b: &Self) -> cres; + 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; } pub type LatticeOp = &fn(cf: &CombineFields, a: &T, b: &T) -> cres; -pub impl ty::t: LatticeValue { - static fn sub(cf: &CombineFields, a: &ty::t, b: &ty::t) -> ures { +pub impl LatticeValue for ty::t { + static fn sub(&self, cf: &CombineFields, a: &ty::t, b: &ty::t) -> ures { Sub(*cf).tys(*a, *b).to_ures() } - static fn lub(cf: &CombineFields, a: &ty::t, b: &ty::t) -> cres { + static fn lub(&self, cf: &CombineFields, a: &ty::t, b: &ty::t) + -> cres { Lub(*cf).tys(*a, *b) } - static fn glb(cf: &CombineFields, a: &ty::t, b: &ty::t) -> cres { + static fn glb(&self, cf: &CombineFields, a: &ty::t, b: &ty::t) + -> cres { Glb(*cf).tys(*a, *b) } } pub impl CombineFields { - fn var_sub_var>>( + fn var_sub_var>>( &self, +a_id: V, +b_id: V) -> ures @@ -125,8 +129,8 @@ pub impl CombineFields { } /// make variable a subtype of T - fn var_sub_t>>( + fn var_sub_t>>( &self, +a_id: V, +b: T) -> ures @@ -138,7 +142,7 @@ pub impl CombineFields { let node_a = self.infcx.get(a_id); let a_id = node_a.root; let a_bounds = &node_a.possible_types; - let b_bounds = &{lb: None, ub: Some(b)}; + let b_bounds = &Bounds { lb: None, ub: Some(b) }; debug!("var_sub_t(%s=%s <: %s)", a_id.to_str(), @@ -149,8 +153,8 @@ pub impl CombineFields { a_id, a_bounds, b_bounds, node_a.rank) } - fn t_sub_var>>( + fn t_sub_var>>( &self, +a: T, +b_id: V) -> ures @@ -159,7 +163,7 @@ pub impl CombineFields { * * Make a concrete type (`a`) a subtype of the variable `b_id` */ - let a_bounds = &{lb: Some(a), ub: None}; + let a_bounds = &Bounds { lb: Some(a), ub: None }; let node_b = self.infcx.get(b_id); let b_id = node_b.root; let b_bounds = &node_b.possible_types; @@ -173,7 +177,7 @@ pub impl CombineFields { b_id, a_bounds, b_bounds, node_b.rank) } - fn merge_bnd( + fn merge_bnd( &self, a: &Bound, b: &Bound, @@ -201,8 +205,8 @@ pub impl CombineFields { } } - fn set_var_to_merged_bounds>>( + fn set_var_to_merged_bounds>>( &self, +v_id: V, a: &Bounds, @@ -251,7 +255,7 @@ pub impl CombineFields { let () = if_ok!(self.bnds(&b.lb, &a.ub)); let ub = if_ok!(self.merge_bnd(&a.ub, &b.ub, LatticeValue::glb)); let lb = if_ok!(self.merge_bnd(&a.lb, &b.lb, LatticeValue::lub)); - let bounds = {lb: lb, ub: ub}; + let bounds = Bounds { lb: lb, ub: ub }; debug!("merge(%s): bounds=%s", v_id.to_str(), bounds.inf_str(self.infcx)); @@ -263,7 +267,7 @@ pub impl CombineFields { uok() } - fn bnds( + fn bnds( &self, a: &Bound, b: &Bound) -> ures @@ -292,44 +296,44 @@ pub impl CombineFields { // for pairs of variables or for variables and values. pub trait LatticeDir { - fn combine_fields() -> CombineFields; - fn bnd(b: &Bounds) -> Option; - fn with_bnd(b: &Bounds, +t: T) -> Bounds; + fn combine_fields(&self) -> CombineFields; + fn bnd(&self, b: &Bounds) -> Option; + fn with_bnd(&self, b: &Bounds, +t: T) -> Bounds; } pub trait TyLatticeDir { - fn ty_bot(t: ty::t) -> cres; + fn ty_bot(&self, t: ty::t) -> cres; } -pub impl Lub: LatticeDir { - fn combine_fields() -> CombineFields { *self } - fn bnd(b: &Bounds) -> Option { b.ub } - fn with_bnd(b: &Bounds, +t: T) -> Bounds { - {ub: Some(t), ..*b} +pub impl LatticeDir for Lub { + fn combine_fields(&self) -> CombineFields { **self } + fn bnd(&self, b: &Bounds) -> Option { b.ub } + fn with_bnd(&self, b: &Bounds, +t: T) -> Bounds { + Bounds { ub: Some(t), ..*b } } } -pub impl Lub: TyLatticeDir { - fn ty_bot(t: ty::t) -> cres { +pub impl TyLatticeDir for Lub { + fn ty_bot(&self, t: ty::t) -> cres { Ok(t) } } -pub impl Glb: LatticeDir { - fn combine_fields() -> CombineFields { *self } - fn bnd(b: &Bounds) -> Option { b.lb } - fn with_bnd(b: &Bounds, +t: T) -> Bounds { - {lb: Some(t), ..*b} +pub impl LatticeDir for Glb { + fn combine_fields(&self) -> CombineFields { **self } + fn bnd(&self, b: &Bounds) -> Option { b.lb } + fn with_bnd(&self, b: &Bounds, +t: T) -> Bounds { + Bounds { lb: Some(t), ..*b } } } -pub impl Glb: TyLatticeDir { - fn ty_bot(_t: ty::t) -> cres { +pub impl TyLatticeDir for Glb { + fn ty_bot(&self, _t: ty::t) -> cres { Ok(ty::mk_bot(self.infcx.tcx)) } } -pub fn super_lattice_tys( +pub fn super_lattice_tys( self: &L, a: ty::t, b: ty::t) -> cres { @@ -395,9 +399,9 @@ pub enum LatticeVarResult { * the variables and return the unified variable, in which case the * result is a variable. This is indicated with a `VarResult` * return. */ -pub fn lattice_vars>>( +pub fn lattice_vars>>( self: &L, // defines whether we want LUB or GLB +a_vid: V, // first variable +b_vid: V, // second variable @@ -441,9 +445,9 @@ pub fn lattice_vars>>( +pub fn lattice_var_and_t>>( self: &L, +a_id: V, b: &T, @@ -485,7 +489,7 @@ pub fn lattice_var_and_t(self: &T, isr: isr_alist) -> ~[RegionVid] { +pub fn var_ids(self: &T, isr: isr_alist) -> ~[RegionVid] { let mut result = ~[]; for list::each(isr) |pair| { match pair.second() { diff --git a/src/librustc/middle/typeck/infer/lub.rs b/src/librustc/middle/typeck/infer/lub.rs index e19d5b3f47bed..df4b8c0be09b5 100644 --- a/src/librustc/middle/typeck/infer/lub.rs +++ b/src/librustc/middle/typeck/infer/lub.rs @@ -32,21 +32,22 @@ pub fn macros() { pub enum Lub = CombineFields; // least-upper-bound: common supertype pub impl Lub { - fn bot_ty(b: ty::t) -> cres { Ok(b) } - fn ty_bot(b: ty::t) -> cres { self.bot_ty(b) } // commutative + fn bot_ty(&self, b: ty::t) -> cres { Ok(b) } + fn ty_bot(&self, b: ty::t) + -> cres { self.bot_ty(b) } // commutative } -pub impl Lub: Combine { - fn infcx() -> @mut InferCtxt { self.infcx } - fn tag() -> ~str { ~"lub" } - fn a_is_expected() -> bool { self.a_is_expected } - fn span() -> span { self.span } +pub impl Combine for Lub { + fn infcx(&self) -> @mut InferCtxt { self.infcx } + fn tag(&self) -> ~str { ~"lub" } + fn a_is_expected(&self) -> bool { self.a_is_expected } + fn span(&self) -> span { self.span } - fn sub() -> Sub { Sub(*self) } - fn lub() -> Lub { Lub(*self) } - fn glb() -> Glb { Glb(*self) } + fn sub(&self) -> Sub { Sub(**self) } + fn lub(&self) -> Lub { Lub(**self) } + fn glb(&self) -> Glb { Glb(**self) } - fn mts(a: ty::mt, b: ty::mt) -> cres { + fn mts(&self, a: ty::mt, b: ty::mt) -> cres { let tcx = self.infcx.tcx; debug!("%s.mts(%s, %s)", @@ -67,7 +68,7 @@ pub impl Lub: Combine { m_mutbl => { self.infcx.try(|| { - eq_tys(&self, a.ty, b.ty).then(|| { + eq_tys(self, a.ty, b.ty).then(|| { Ok(ty::mt {ty: a.ty, mutbl: m}) }) }).chain_err(|_e| { @@ -79,11 +80,11 @@ pub impl Lub: Combine { } } - fn contratys(a: ty::t, b: ty::t) -> cres { - Glb(*self).tys(a, b) + fn contratys(&self, a: ty::t, b: ty::t) -> cres { + Glb(**self).tys(a, b) } - fn purities(a: purity, b: purity) -> cres { + fn purities(&self, a: purity, b: purity) -> cres { match (a, b) { (unsafe_fn, _) | (_, unsafe_fn) => Ok(unsafe_fn), (impure_fn, _) | (_, impure_fn) => Ok(impure_fn), @@ -92,18 +93,19 @@ pub impl Lub: Combine { } } - fn oncenesses(a: Onceness, b: Onceness) -> cres { + fn oncenesses(&self, a: Onceness, b: Onceness) -> cres { match (a, b) { (Once, _) | (_, Once) => Ok(Once), (Many, Many) => Ok(Many) } } - fn contraregions(a: ty::Region, b: ty::Region) -> cres { - return Glb(*self).regions(a, b); + fn contraregions(&self, a: ty::Region, b: ty::Region) + -> cres { + return Glb(**self).regions(a, b); } - fn regions(a: ty::Region, b: ty::Region) -> cres { + fn regions(&self, a: ty::Region, b: ty::Region) -> cres { debug!("%s.regions(%?, %?)", self.tag(), a.inf_str(self.infcx), @@ -114,7 +116,7 @@ pub impl Lub: Combine { } } - fn fn_sigs(a: &ty::FnSig, b: &ty::FnSig) -> cres { + fn fn_sigs(&self, a: &ty::FnSig, b: &ty::FnSig) -> cres { // Note: this is a subtle algorithm. For a full explanation, // please see the large comment in `region_inference.rs`. @@ -133,7 +135,7 @@ pub impl Lub: Combine { self.span, b); // Collect constraints. - let sig0 = if_ok!(super_fn_sigs(&self, &a_with_fresh, &b_with_fresh)); + let sig0 = if_ok!(super_fn_sigs(self, &a_with_fresh, &b_with_fresh)); debug!("sig0 = %s", sig0.inf_str(self.infcx)); // Generalize the regions appearing in sig0 if possible @@ -142,9 +144,9 @@ pub impl Lub: Combine { let sig1 = self.infcx.fold_regions_in_sig( &sig0, - |r, _in_fn| generalize_region(&self, snapshot, new_vars, + |r, _in_fn| generalize_region(self, snapshot, new_vars, a_isr, r)); - return Ok(move sig1); + return Ok(sig1); fn generalize_region(self: &Lub, snapshot: uint, @@ -191,58 +193,60 @@ pub impl Lub: Combine { } } - fn bare_fn_tys(a: &ty::BareFnTy, + fn bare_fn_tys(&self, a: &ty::BareFnTy, b: &ty::BareFnTy) -> cres { - super_bare_fn_tys(&self, a, b) + super_bare_fn_tys(self, a, b) } - fn closure_tys(a: &ty::ClosureTy, + fn closure_tys(&self, a: &ty::ClosureTy, b: &ty::ClosureTy) -> cres { - super_closure_tys(&self, a, b) + super_closure_tys(self, a, b) } // Traits please (FIXME: #2794): - fn sigils(p1: ast::Sigil, p2: ast::Sigil) -> cres { - super_sigils(&self, p1, p2) + fn sigils(&self, p1: ast::Sigil, p2: ast::Sigil) + -> cres { + super_sigils(self, p1, p2) } - fn abis(p1: ast::Abi, p2: ast::Abi) -> cres { - super_abis(&self, p1, p2) + fn abis(&self, p1: ast::Abi, p2: ast::Abi) -> cres { + super_abis(self, p1, p2) } - fn tys(a: ty::t, b: ty::t) -> cres { - super_lattice_tys(&self, a, b) + fn tys(&self, a: ty::t, b: ty::t) -> cres { + super_lattice_tys(self, a, b) } - fn flds(a: ty::field, b: ty::field) -> cres { - super_flds(&self, a, b) + fn flds(&self, a: ty::field, b: ty::field) -> cres { + super_flds(self, a, b) } - fn vstores(vk: ty::terr_vstore_kind, + fn vstores(&self, vk: ty::terr_vstore_kind, a: ty::vstore, b: ty::vstore) -> cres { - super_vstores(&self, vk, a, b) + super_vstores(self, vk, a, b) } - fn modes(a: ast::mode, b: ast::mode) -> cres { - super_modes(&self, a, b) + fn modes(&self, a: ast::mode, b: ast::mode) -> cres { + super_modes(self, a, b) } - fn args(a: ty::arg, b: ty::arg) -> cres { - super_args(&self, a, b) + fn args(&self, a: ty::arg, b: ty::arg) -> cres { + super_args(self, a, b) } - fn substs(did: ast::def_id, + fn substs(&self, did: ast::def_id, as_: &ty::substs, bs: &ty::substs) -> cres { - super_substs(&self, did, as_, bs) + super_substs(self, did, as_, bs) } - fn tps(as_: &[ty::t], bs: &[ty::t]) -> cres<~[ty::t]> { - super_tps(&self, as_, bs) + fn tps(&self, as_: &[ty::t], bs: &[ty::t]) -> cres<~[ty::t]> { + super_tps(self, as_, bs) } - fn self_tys(a: Option, b: Option) -> cres> { - super_self_tys(&self, a, b) + fn self_tys(&self, a: Option, b: Option) + -> cres> { + super_self_tys(self, a, b) } } diff --git a/src/librustc/middle/typeck/infer/macros.rs b/src/librustc/middle/typeck/infer/macros.rs index 8cccf75d6dc4e..01174d1620ada 100644 --- a/src/librustc/middle/typeck/infer/macros.rs +++ b/src/librustc/middle/typeck/infer/macros.rs @@ -13,8 +13,8 @@ macro_rules! if_ok( ($inp: expr) => ( match $inp { - Ok(move v) => { move v } - Err(move e) => { return Err(e); } + Ok(v) => { v } + Err(e) => { return Err(e); } } ) ); diff --git a/src/librustc/middle/typeck/infer/mod.rs b/src/librustc/middle/typeck/infer/mod.rs index f6af29c1a8df9..f013712595281 100644 --- a/src/librustc/middle/typeck/infer/mod.rs +++ b/src/librustc/middle/typeck/infer/mod.rs @@ -299,7 +299,10 @@ pub mod unify; pub mod coercion; pub type Bound = Option; -pub type Bounds = {lb: Bound, ub: Bound}; +pub struct Bounds { + lb: Bound, + ub: Bound +} pub type cres = Result; // "combine result" pub type ures = cres<()>; // "unify result" @@ -348,7 +351,7 @@ pub fn fixup_err_to_str(f: fixup_err) -> ~str { } } -fn new_ValsAndBindings() -> ValsAndBindings { +fn new_ValsAndBindings() -> ValsAndBindings { ValsAndBindings { vals: oldsmallintmap::mk(), bindings: ~[] @@ -486,24 +489,24 @@ fn resolve_borrowings(cx: @mut InferCtxt) { */ trait then { - fn then(f: fn() -> Result) + fn then(&self, f: fn() -> Result) -> Result; } impl then for ures { - fn then(f: fn() -> Result) + fn then(&self, f: fn() -> Result) -> Result { self.chain(|_i| f()) } } trait ToUres { - fn to_ures() -> ures; + fn to_ures(&self) -> ures; } impl ToUres for cres { - fn to_ures() -> ures { - match self { + fn to_ures(&self) -> ures { + match *self { Ok(ref _v) => Ok(()), Err(ref e) => Err((*e)) } @@ -511,14 +514,14 @@ impl ToUres for cres { } trait CresCompare { - fn compare(t: T, f: fn() -> ty::type_err) -> cres; + fn compare(&self, t: T, f: fn() -> ty::type_err) -> cres; } -impl CresCompare for cres { - fn compare(t: T, f: fn() -> ty::type_err) -> cres { +impl CresCompare for cres { + fn compare(&self, t: T, f: fn() -> ty::type_err) -> cres { do self.chain |s| { if s == t { - self + *self } else { Err(f()) } @@ -530,7 +533,7 @@ pub fn uok() -> ures { Ok(()) } -fn rollback_to( +fn rollback_to( vb: &mut ValsAndBindings, len: uint) { @@ -548,22 +551,22 @@ struct Snapshot { } impl @mut InferCtxt { - fn combine_fields(a_is_expected: bool, + fn combine_fields(&self, a_is_expected: bool, span: span) -> CombineFields { - CombineFields {infcx: self, + CombineFields {infcx: *self, a_is_expected: a_is_expected, span: span} } - fn sub(a_is_expected: bool, span: span) -> Sub { + fn sub(&self, a_is_expected: bool, span: span) -> Sub { Sub(self.combine_fields(a_is_expected, span)) } - fn in_snapshot() -> bool { + fn in_snapshot(&self) -> bool { self.region_vars.in_snapshot() } - fn start_snapshot() -> Snapshot { + fn start_snapshot(&self) -> Snapshot { Snapshot { ty_var_bindings_len: self.ty_var_bindings.bindings.len(), @@ -576,7 +579,7 @@ impl @mut InferCtxt { } } - fn rollback_to(snapshot: &Snapshot) { + fn rollback_to(&self, snapshot: &Snapshot) { debug!("rollback!"); rollback_to(&mut self.ty_var_bindings, snapshot.ty_var_bindings_len); @@ -599,7 +602,7 @@ impl @mut InferCtxt { self.ty_var_bindings.bindings.truncate(0); self.int_var_bindings.bindings.truncate(0); self.region_vars.commit(); - move r + r } } @@ -613,7 +616,7 @@ impl @mut InferCtxt { Ok(_) => (), Err(_) => self.rollback_to(&snapshot) } - move r + r } } @@ -624,12 +627,12 @@ impl @mut InferCtxt { let snapshot = self.start_snapshot(); let r = self.try(f); self.rollback_to(&snapshot); - move r + r } } } -fn next_simple_var( +fn next_simple_var( +counter: &mut uint, +bindings: &mut ValsAndBindings>) -> uint { @@ -640,45 +643,45 @@ fn next_simple_var( } impl @mut InferCtxt { - fn next_ty_var_id() -> TyVid { + fn next_ty_var_id(&self) -> TyVid { let id = self.ty_var_counter; self.ty_var_counter += 1; let vals = self.ty_var_bindings.vals; - vals.insert(id, Root({lb: None, ub: None}, 0u)); + vals.insert(id, Root(Bounds { lb: None, ub: None }, 0u)); return TyVid(id); } - fn next_ty_var() -> ty::t { + fn next_ty_var(&self) -> ty::t { ty::mk_var(self.tcx, self.next_ty_var_id()) } - fn next_ty_vars(n: uint) -> ~[ty::t] { + fn next_ty_vars(&self, n: uint) -> ~[ty::t] { vec::from_fn(n, |_i| self.next_ty_var()) } - fn next_int_var_id() -> IntVid { + fn next_int_var_id(&self) -> IntVid { IntVid(next_simple_var(&mut self.int_var_counter, &mut self.int_var_bindings)) } - fn next_int_var() -> ty::t { + fn next_int_var(&self) -> ty::t { ty::mk_int_var(self.tcx, self.next_int_var_id()) } - fn next_float_var_id() -> FloatVid { + fn next_float_var_id(&self) -> FloatVid { FloatVid(next_simple_var(&mut self.float_var_counter, &mut self.float_var_bindings)) } - fn next_float_var() -> ty::t { + fn next_float_var(&self) -> ty::t { ty::mk_float_var(self.tcx, self.next_float_var_id()) } - fn next_region_var_nb(span: span) -> ty::Region { + fn next_region_var_nb(&self, span: span) -> ty::Region { ty::re_infer(ty::ReVar(self.region_vars.new_region_var(span))) } - fn next_region_var_with_lb(span: span, + fn next_region_var_with_lb(&self, span: span, lb_region: ty::Region) -> ty::Region { let region_var = self.next_region_var_nb(span); @@ -690,27 +693,28 @@ impl @mut InferCtxt { return region_var; } - fn next_region_var(span: span, scope_id: ast::node_id) -> ty::Region { + fn next_region_var(&self, span: span, scope_id: ast::node_id) + -> ty::Region { self.next_region_var_with_lb(span, ty::re_scope(scope_id)) } - fn resolve_regions() { + fn resolve_regions(&self) { self.region_vars.resolve_regions(); } - fn ty_to_str(t: ty::t) -> ~str { + fn ty_to_str(&self, t: ty::t) -> ~str { ty_to_str(self.tcx, self.resolve_type_vars_if_possible(t)) } - fn resolve_type_vars_if_possible(typ: ty::t) -> ty::t { - match resolve_type(self, typ, resolve_nested_tvar | resolve_ivar) { + fn resolve_type_vars_if_possible(&self, typ: ty::t) -> ty::t { + match resolve_type(*self, typ, resolve_nested_tvar | resolve_ivar) { result::Ok(new_type) => new_type, result::Err(_) => typ } } - fn type_error_message(sp: span, mk_msg: fn(~str) -> ~str, + fn type_error_message(&self, sp: span, mk_msg: fn(~str) -> ~str, actual_ty: ty::t, err: Option<&ty::type_err>) { let actual_ty = self.resolve_type_vars_if_possible(actual_ty); @@ -728,7 +732,7 @@ impl @mut InferCtxt { ty::note_and_explain_type_err(self.tcx, *err)); } - fn report_mismatched_types(sp: span, e: ty::t, a: ty::t, + fn report_mismatched_types(&self, sp: span, e: ty::t, a: ty::t, err: &ty::type_err) { // Don't report an error if expected is ty_err let resolved_expected = @@ -746,11 +750,11 @@ impl @mut InferCtxt { self.type_error_message(sp, mk_msg, a, Some(err)); } - fn replace_bound_regions_with_fresh_regions( + fn replace_bound_regions_with_fresh_regions(&self, span: span, fsig: &ty::FnSig) -> (ty::FnSig, isr_alist) { - let {fn_sig: fn_sig, isr: isr, _} = + let(isr, _, fn_sig) = replace_bound_regions_in_fn_sig(self.tcx, @Nil, None, fsig, |br| { // N.B.: The name of the bound region doesn't have anything to // do with the region variable that's created for it. The diff --git a/src/librustc/middle/typeck/infer/region_inference.rs b/src/librustc/middle/typeck/infer/region_inference.rs index c838a52a6892f..cc5e860715d6d 100644 --- a/src/librustc/middle/typeck/infer/region_inference.rs +++ b/src/librustc/middle/typeck/infer/region_inference.rs @@ -899,7 +899,7 @@ pub impl RegionVarBindings { // replace the NoValue entry with ErrorValue. let mut values = self.values.take(); values[*rid] = ErrorValue; - self.values.put_back(move values); + self.values.put_back(values); re_static } @@ -999,9 +999,9 @@ pub impl RegionVarBindings { None => {} Some((ref r1, ref r2)) => { result_set = - consider_adding_edge(move result_set, &r, r1, r2); + consider_adding_edge(result_set, &r, r1, r2); result_set = - consider_adding_edge(move result_set, &r, r2, r1); + consider_adding_edge(result_set, &r, r2, r1); } } @@ -1018,13 +1018,13 @@ pub impl RegionVarBindings { r1: &Region, r2: &Region) -> ~[Region] { - let mut result_set = move result_set; + let mut result_set = result_set; if *r == *r1 { // Clearly, this is potentially inefficient. if !result_set.contains(r2) { result_set.push(*r2); } } - return move result_set; + return result_set; } } @@ -1254,8 +1254,8 @@ impl RegionVarBindings { } let mut graph = Graph { - nodes: move nodes, - edges: move edges + nodes: nodes, + edges: edges }; for uint::range(0, num_edges) |edge_idx| { @@ -1273,7 +1273,7 @@ impl RegionVarBindings { } } - return (move graph); + return (graph); fn insert_edge(+graph: &mut Graph, node_id: RegionVid, diff --git a/src/librustc/middle/typeck/infer/resolve.rs b/src/librustc/middle/typeck/infer/resolve.rs index 7c5e3f715c3a8..a4e706db60e9c 100644 --- a/src/librustc/middle/typeck/infer/resolve.rs +++ b/src/librustc/middle/typeck/infer/resolve.rs @@ -51,7 +51,7 @@ use core::prelude::*; use middle::ty::{FloatVar, FloatVid, IntVar, IntVid, RegionVid, TyVar, TyVid}; use middle::ty::{type_is_bot, IntType, UintType}; use middle::ty; -use middle::typeck::infer::{cyclic_ty, fixup_err, fres, InferCtxt}; +use middle::typeck::infer::{Bounds, cyclic_ty, fixup_err, fres, InferCtxt}; use middle::typeck::infer::{region_var_bound_by_region_var, unresolved_ty}; use middle::typeck::infer::to_str::InferStr; use middle::typeck::infer::unify::Root; @@ -223,10 +223,11 @@ pub impl ResolveState { let bounds = nde.possible_types; let t1 = match bounds { - { ub:_, lb:Some(t) } if !type_is_bot(t) => self.resolve_type(t), - { ub:Some(t), lb:_ } => self.resolve_type(t), - { ub:_, lb:Some(t) } => self.resolve_type(t), - { ub:None, lb:None } => { + Bounds { ub:_, lb:Some(t) } if !type_is_bot(t) + => self.resolve_type(t), + Bounds { ub:Some(t), lb:_ } => self.resolve_type(t), + Bounds { ub:_, lb:Some(t) } => self.resolve_type(t), + Bounds { ub:None, lb:None } => { if self.should(force_tvar) { self.err = Some(unresolved_ty(vid)); } diff --git a/src/librustc/middle/typeck/infer/sub.rs b/src/librustc/middle/typeck/infer/sub.rs index 33a3220f68a31..661c67dbefc62 100644 --- a/src/librustc/middle/typeck/infer/sub.rs +++ b/src/librustc/middle/typeck/infer/sub.rs @@ -32,31 +32,32 @@ pub fn macros() { pub enum Sub = CombineFields; // "subtype", "subregion" etc -pub impl Sub: Combine { - fn infcx() -> @mut InferCtxt { self.infcx } - fn tag() -> ~str { ~"sub" } - fn a_is_expected() -> bool { self.a_is_expected } - fn span() -> span { self.span } +pub impl Combine for Sub { + fn infcx(&self) -> @mut InferCtxt { self.infcx } + fn tag(&self) -> ~str { ~"sub" } + fn a_is_expected(&self) -> bool { self.a_is_expected } + fn span(&self) -> span { self.span } - fn sub() -> Sub { Sub(*self) } - fn lub() -> Lub { Lub(*self) } - fn glb() -> Glb { Glb(*self) } + fn sub(&self) -> Sub { Sub(**self) } + fn lub(&self) -> Lub { Lub(**self) } + fn glb(&self) -> Glb { Glb(**self) } - fn contratys(a: ty::t, b: ty::t) -> cres { + fn contratys(&self, a: ty::t, b: ty::t) -> cres { let opp = CombineFields { - a_is_expected: !self.a_is_expected,.. *self + a_is_expected: !self.a_is_expected,.. **self }; Sub(opp).tys(b, a) } - fn contraregions(a: ty::Region, b: ty::Region) -> cres { + fn contraregions(&self, a: ty::Region, b: ty::Region) + -> cres { let opp = CombineFields { - a_is_expected: !self.a_is_expected,.. *self + a_is_expected: !self.a_is_expected,.. **self }; Sub(opp).regions(b, a) } - fn regions(a: ty::Region, b: ty::Region) -> cres { + fn regions(&self, a: ty::Region, b: ty::Region) -> cres { debug!("%s.regions(%s, %s)", self.tag(), a.inf_str(self.infcx), @@ -69,7 +70,7 @@ pub impl Sub: Combine { } } - fn mts(a: ty::mt, b: ty::mt) -> cres { + fn mts(&self, a: ty::mt, b: ty::mt) -> cres { debug!("mts(%s <: %s)", a.inf_str(self.infcx), b.inf_str(self.infcx)); if a.mutbl != b.mutbl && b.mutbl != m_const { @@ -80,7 +81,7 @@ pub impl Sub: Combine { m_mutbl => { // If supertype is mut, subtype must match exactly // (i.e., invariant if mut): - eq_tys(&self, a.ty, b.ty).then(|| Ok(a) ) + eq_tys(self, a.ty, b.ty).then(|| Ok(a) ) } m_imm | m_const => { // Otherwise we can be covariant: @@ -89,19 +90,19 @@ pub impl Sub: Combine { } } - fn purities(a: purity, b: purity) -> cres { + fn purities(&self, a: purity, b: purity) -> cres { self.lub().purities(a, b).compare(b, || { - ty::terr_purity_mismatch(expected_found(&self, a, b)) + ty::terr_purity_mismatch(expected_found(self, a, b)) }) } - fn oncenesses(a: Onceness, b: Onceness) -> cres { + fn oncenesses(&self, a: Onceness, b: Onceness) -> cres { self.lub().oncenesses(a, b).compare(b, || { - ty::terr_onceness_mismatch(expected_found(&self, a, b)) + ty::terr_onceness_mismatch(expected_found(self, a, b)) }) } - fn tys(a: ty::t, b: ty::t) -> cres { + fn tys(&self, a: ty::t, b: ty::t) -> cres { debug!("%s.tys(%s, %s)", self.tag(), a.inf_str(self.infcx), b.inf_str(self.infcx)); if a == b { return Ok(a); } @@ -125,16 +126,16 @@ pub impl Sub: Combine { } (_, &ty::ty_bot) => { - Err(ty::terr_sorts(expected_found(&self, a, b))) + Err(ty::terr_sorts(expected_found(self, a, b))) } _ => { - super_tys(&self, a, b) + super_tys(self, a, b) } } } - fn fn_sigs(a: &ty::FnSig, b: &ty::FnSig) -> cres { + fn fn_sigs(&self, a: &ty::FnSig, b: &ty::FnSig) -> cres { debug!("fn_sigs(a=%s, b=%s)", a.inf_str(self.infcx), b.inf_str(self.infcx)); let _indenter = indenter(); @@ -160,7 +161,7 @@ pub impl Sub: Combine { // Second, we instantiate each bound region in the supertype with a // fresh concrete region. - let {fn_sig: b_sig, isr: skol_isr, _} = { + let (skol_isr, _, b_sig) = { do replace_bound_regions_in_fn_sig(self.infcx.tcx, @Nil, None, b) |br| { let skol = self.infcx.region_vars.new_skolemized(br); @@ -175,7 +176,7 @@ pub impl Sub: Combine { debug!("b_sig=%s", b_sig.inf_str(self.infcx)); // Compare types now that bound regions have been replaced. - let sig = if_ok!(super_fn_sigs(&self, &a_sig, &b_sig)); + let sig = if_ok!(super_fn_sigs(self, &a_sig, &b_sig)); // Presuming type comparison succeeds, we need to check // that the skolemized regions do not "leak". @@ -212,53 +213,54 @@ pub impl Sub: Combine { // Traits please (FIXME: #2794): - fn sigils(p1: ast::Sigil, p2: ast::Sigil) -> cres { - super_sigils(&self, p1, p2) + fn sigils(&self, p1: ast::Sigil, p2: ast::Sigil) -> cres { + super_sigils(self, p1, p2) } - fn abis(p1: ast::Abi, p2: ast::Abi) -> cres { - super_abis(&self, p1, p2) + fn abis(&self, p1: ast::Abi, p2: ast::Abi) -> cres { + super_abis(self, p1, p2) } - fn flds(a: ty::field, b: ty::field) -> cres { - super_flds(&self, a, b) + fn flds(&self, a: ty::field, b: ty::field) -> cres { + super_flds(self, a, b) } - fn bare_fn_tys(a: &ty::BareFnTy, + fn bare_fn_tys(&self, a: &ty::BareFnTy, b: &ty::BareFnTy) -> cres { - super_bare_fn_tys(&self, a, b) + super_bare_fn_tys(self, a, b) } - fn closure_tys(a: &ty::ClosureTy, + fn closure_tys(&self, a: &ty::ClosureTy, b: &ty::ClosureTy) -> cres { - super_closure_tys(&self, a, b) + super_closure_tys(self, a, b) } - fn vstores(vk: ty::terr_vstore_kind, + fn vstores(&self, vk: ty::terr_vstore_kind, a: ty::vstore, b: ty::vstore) -> cres { - super_vstores(&self, vk, a, b) + super_vstores(self, vk, a, b) } - fn modes(a: ast::mode, b: ast::mode) -> cres { - super_modes(&self, a, b) + fn modes(&self, a: ast::mode, b: ast::mode) -> cres { + super_modes(self, a, b) } - fn args(a: ty::arg, b: ty::arg) -> cres { - super_args(&self, a, b) + fn args(&self, a: ty::arg, b: ty::arg) -> cres { + super_args(self, a, b) } - fn substs(did: ast::def_id, + fn substs(&self, did: ast::def_id, as_: &ty::substs, bs: &ty::substs) -> cres { - super_substs(&self, did, as_, bs) + super_substs(self, did, as_, bs) } - fn tps(as_: &[ty::t], bs: &[ty::t]) -> cres<~[ty::t]> { - super_tps(&self, as_, bs) + fn tps(&self, as_: &[ty::t], bs: &[ty::t]) -> cres<~[ty::t]> { + super_tps(self, as_, bs) } - fn self_tys(a: Option, b: Option) -> cres> { - super_self_tys(&self, a, b) + fn self_tys(&self, a: Option, b: Option) + -> cres> { + super_self_tys(self, a, b) } } diff --git a/src/librustc/middle/typeck/infer/test.rs b/src/librustc/middle/typeck/infer/test.rs index d79343e64a69d..27355da4b9aee 100644 --- a/src/librustc/middle/typeck/infer/test.rs +++ b/src/librustc/middle/typeck/infer/test.rs @@ -69,7 +69,7 @@ fn setup_env(test_name: &str, source_string: &str) -> Env { cfg, parse_sess); let tcx = ty::mk_ctxt(sess, dm, amap, freevars, region_map, - region_paramd_items, move lang_items, crate); + region_paramd_items, lang_items, crate); let infcx = infer::new_infer_ctxt(tcx); @@ -192,7 +192,7 @@ impl Env { onceness: ast::Many, region: ty::re_static, bounds: @~[]}, - sig: FnSig {inputs: move inputs, + sig: FnSig {inputs: inputs, output: output_ty} }) } diff --git a/src/librustc/middle/typeck/infer/to_str.rs b/src/librustc/middle/typeck/infer/to_str.rs index bade7639e4baf..0013b417f7a31 100644 --- a/src/librustc/middle/typeck/infer/to_str.rs +++ b/src/librustc/middle/typeck/infer/to_str.rs @@ -28,13 +28,13 @@ pub trait InferStr { fn inf_str(&self, cx: &InferCtxt) -> ~str; } -pub impl ty::t : InferStr { +pub impl InferStr for ty::t { fn inf_str(&self, cx: &InferCtxt) -> ~str { ty_to_str(cx.tcx, *self) } } -pub impl FnSig : InferStr { +pub impl InferStr for FnSig { fn inf_str(&self, cx: &InferCtxt) -> ~str { fmt!("(%s) -> %s", str::connect(self.inputs.map(|a| a.ty.inf_str(cx)), ", "), @@ -42,19 +42,19 @@ pub impl FnSig : InferStr { } } -pub impl ty::mt : InferStr { +pub impl InferStr for ty::mt { fn inf_str(&self, cx: &InferCtxt) -> ~str { mt_to_str(cx.tcx, *self) } } -pub impl ty::Region : InferStr { +pub impl InferStr for ty::Region { fn inf_str(&self, _cx: &InferCtxt) -> ~str { fmt!("%?", *self) } } -pub impl Bound : InferStr { +pub impl InferStr for Bound { fn inf_str(&self, cx: &InferCtxt) -> ~str { match *self { Some(ref v) => v.inf_str(cx), @@ -63,7 +63,7 @@ pub impl Bound : InferStr { } } -pub impl Bounds : InferStr { +pub impl InferStr for Bounds { fn inf_str(&self, cx: &InferCtxt) -> ~str { fmt!("{%s <: %s}", self.lb.inf_str(cx), @@ -71,7 +71,7 @@ pub impl Bounds : InferStr { } } -pub impl VarValue : InferStr { +pub impl InferStr for VarValue { fn inf_str(&self, cx: &InferCtxt) -> ~str { match *self { Redirect(ref vid) => fmt!("Redirect(%s)", vid.to_str()), @@ -81,13 +81,13 @@ pub impl VarValue : InferStr { } } -pub impl IntVarValue : InferStr { +pub impl InferStr for IntVarValue { fn inf_str(&self, _cx: &InferCtxt) -> ~str { self.to_str() } } -pub impl ast::float_ty : InferStr { +pub impl InferStr for ast::float_ty { fn inf_str(&self, _cx: &InferCtxt) -> ~str { self.to_str() } diff --git a/src/librustc/middle/typeck/infer/unify.rs b/src/librustc/middle/typeck/infer/unify.rs index 69e4f373f9742..d9b2b73890d42 100644 --- a/src/librustc/middle/typeck/infer/unify.rs +++ b/src/librustc/middle/typeck/infer/unify.rs @@ -38,7 +38,7 @@ pub struct Node { } pub trait UnifyVid { - static fn appropriate_vals_and_bindings(infcx: &v/mut InferCtxt) + static fn appropriate_vals_and_bindings(&self, infcx: &v/mut InferCtxt) -> &v/mut ValsAndBindings; } @@ -89,7 +89,7 @@ pub impl InferCtxt { } } - fn set>( + fn set>( &mut self, +vid: V, +new_v: VarValue) { @@ -109,7 +109,7 @@ pub impl InferCtxt { } } - fn unify>( + fn unify>( &mut self, node_a: &Node, node_b: &Node) -> (V, uint) @@ -147,10 +147,10 @@ pub impl InferCtxt { // doesn't have a subtyping relationship we need to worry about. pub trait SimplyUnifiable { - static fn to_type_err(expected_found) -> ty::type_err; + static fn to_type_err(&self, expected_found) -> ty::type_err; } -pub fn mk_err(+a_is_expected: bool, +pub fn mk_err(+a_is_expected: bool, +a_t: T, +b_t: T) -> ures { if a_is_expected { @@ -163,8 +163,8 @@ pub fn mk_err(+a_is_expected: bool, } pub impl InferCtxt { - fn simple_vars>>( + fn simple_vars>>( &mut self, +a_is_expected: bool, +a_id: V, @@ -201,8 +201,8 @@ pub impl InferCtxt { return uok(); } - fn simple_var_t>>( + fn simple_var_t>>( &mut self, +a_is_expected: bool, +a_id: V, @@ -237,36 +237,36 @@ pub impl InferCtxt { // ______________________________________________________________________ -pub impl ty::TyVid : UnifyVid> { - static fn appropriate_vals_and_bindings(infcx: &v/mut InferCtxt) +pub impl UnifyVid> for ty::TyVid { + static fn appropriate_vals_and_bindings(&self, infcx: &v/mut InferCtxt) -> &v/mut ValsAndBindings> { return &mut infcx.ty_var_bindings; } } -pub impl ty::IntVid : UnifyVid> { - static fn appropriate_vals_and_bindings(infcx: &v/mut InferCtxt) +pub impl UnifyVid> for ty::IntVid { + static fn appropriate_vals_and_bindings(&self, infcx: &v/mut InferCtxt) -> &v/mut ValsAndBindings> { return &mut infcx.int_var_bindings; } } -pub impl IntVarValue : SimplyUnifiable { - static fn to_type_err(err: expected_found) +pub impl SimplyUnifiable for IntVarValue { + static fn to_type_err(&self, err: expected_found) -> ty::type_err { return ty::terr_int_mismatch(err); } } -pub impl ty::FloatVid : UnifyVid> { - static fn appropriate_vals_and_bindings(infcx: &v/mut InferCtxt) +pub impl UnifyVid> for ty::FloatVid { + static fn appropriate_vals_and_bindings(&self, infcx: &v/mut InferCtxt) -> &v/mut ValsAndBindings> { return &mut infcx.float_var_bindings; } } -pub impl ast::float_ty : SimplyUnifiable { - static fn to_type_err(err: expected_found) +pub impl SimplyUnifiable for ast::float_ty { + static fn to_type_err(&self, 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 fa02c14b6c906..49b818328be06 100644 --- a/src/librustc/middle/typeck/mod.rs +++ b/src/librustc/middle/typeck/mod.rs @@ -157,7 +157,7 @@ pub enum vtable_origin { vtable_static(ast::def_id, ~[ty::t], vtable_res), /* Dynamic vtable, comes from a parameter that has a bound on it: - fn foo(a: T) -- a's vtable would have a + fn foo(a: T) -- a's vtable would have a vtable_param origin The first uint is the param number (identifying T in the example), @@ -172,8 +172,8 @@ pub enum vtable_origin { } pub impl vtable_origin { - fn to_str(tcx: ty::ctxt) -> ~str { - match self { + fn to_str(&self, tcx: ty::ctxt) -> ~str { + match *self { vtable_static(def_id, ref tys, ref vtable_res) => { fmt!("vtable_static(%?:%s, %?, %?)", def_id, ty::item_path_str(tcx, def_id), @@ -208,7 +208,7 @@ pub struct CrateCtxt { // Functions that write types into the node type table pub fn write_ty_to_tcx(tcx: ty::ctxt, node_id: ast::node_id, ty: ty::t) { debug!("write_ty_to_tcx(%d, %s)", node_id, ppaux::ty_to_str(tcx, ty)); - oldsmallintmap::insert(*tcx.node_types, node_id as uint, ty); + tcx.node_types.insert(node_id as uint, ty); } pub fn write_substs_to_tcx(tcx: ty::ctxt, node_id: ast::node_id, @@ -235,7 +235,11 @@ pub fn lookup_def_ccx(ccx: @mut CrateCtxt, sp: span, id: ast::node_id) } pub fn no_params(t: ty::t) -> ty::ty_param_bounds_and_ty { - {bounds: @~[], region_param: None, ty: t} + ty::ty_param_bounds_and_ty { + bounds: @~[], + region_param: None, + ty: t + } } pub fn require_same_types( @@ -275,17 +279,17 @@ pub fn require_same_types( pub type isr_alist = @List<(ty::bound_region, ty::Region)>; trait get_and_find_region { - fn get(br: ty::bound_region) -> ty::Region; - fn find(br: ty::bound_region) -> Option; + fn get(&self, br: ty::bound_region) -> ty::Region; + fn find(&self, br: ty::bound_region) -> Option; } impl get_and_find_region for isr_alist { - fn get(br: ty::bound_region) -> ty::Region { + fn get(&self, br: ty::bound_region) -> ty::Region { self.find(br).get() } - fn find(br: ty::bound_region) -> Option { - for list::each(self) |isr| { + fn find(&self, br: ty::bound_region) -> Option { + for list::each(*self) |isr| { let (isr_br, isr_r) = *isr; if isr_br == br { return Some(isr_r); } } diff --git a/src/librustc/middle/typeck/rscope.rs b/src/librustc/middle/typeck/rscope.rs index fab86ef69fe11..141a730ca8d34 100644 --- a/src/librustc/middle/typeck/rscope.rs +++ b/src/librustc/middle/typeck/rscope.rs @@ -19,39 +19,39 @@ use syntax::codemap::span; use syntax::parse::token::special_idents; pub trait region_scope { - pure fn anon_region(span: span) -> Result; - pure fn self_region(span: span) -> Result; - pure fn named_region(span: span, id: ast::ident) + pure fn anon_region(&self, span: span) -> Result; + pure fn self_region(&self, span: span) -> Result; + pure fn named_region(&self, span: span, id: ast::ident) -> Result; } pub enum empty_rscope { empty_rscope } -pub impl empty_rscope: region_scope { - pure fn anon_region(_span: span) -> Result { +pub impl region_scope for empty_rscope { + pure fn anon_region(&self, _span: span) -> Result { result::Ok(ty::re_static) } - pure fn self_region(_span: span) -> Result { + pure fn self_region(&self, _span: span) -> Result { result::Err(~"only the static region is allowed here") } - pure fn named_region(_span: span, _id: ast::ident) + pure fn named_region(&self, _span: span, _id: ast::ident) -> Result { result::Err(~"only the static region is allowed here") } } pub enum type_rscope = Option; -pub impl type_rscope: region_scope { - pure fn anon_region(_span: span) -> Result { - match *self { +pub impl region_scope for type_rscope { + pure fn anon_region(&self, _span: span) -> Result { + match **self { Some(_) => result::Ok(ty::re_bound(ty::br_self)), None => result::Err(~"to use region types here, the containing \ type must be declared with a region bound") } } - pure fn self_region(span: span) -> Result { + pure fn self_region(&self, span: span) -> Result { self.anon_region(span) } - pure fn named_region(span: span, id: ast::ident) + pure fn named_region(&self, span: span, id: ast::ident) -> Result { do empty_rscope.named_region(span, id).chain_err |_e| { result::Err(~"named regions other than `self` are not \ @@ -68,19 +68,20 @@ pub fn bound_self_region(rp: Option) } } -pub enum anon_rscope = {anon: ty::Region, base: region_scope}; -pub fn in_anon_rscope(self: RS, r: ty::Region) - -> @anon_rscope { - @anon_rscope({anon: r, base: self as region_scope}) +pub struct anon_rscope { anon: ty::Region, base: region_scope } +pub fn in_anon_rscope(self: RS, + r: ty::Region) + -> @anon_rscope { + @anon_rscope {anon: r, base: self as region_scope} } -pub impl @anon_rscope: region_scope { - pure fn anon_region(_span: span) -> Result { +pub impl region_scope for @anon_rscope { + pure fn anon_region(&self, _span: span) -> Result { result::Ok(self.anon) } - pure fn self_region(span: span) -> Result { + pure fn self_region(&self, span: span) -> Result { self.base.self_region(span) } - pure fn named_region(span: span, id: ast::ident) + pure fn named_region(&self, span: span, id: ast::ident) -> Result { self.base.named_region(span, id) } @@ -91,13 +92,13 @@ pub struct binding_rscope { anon_bindings: uint, } -pub fn in_binding_rscope(self: RS) +pub fn in_binding_rscope(self: RS) -> @mut binding_rscope { let base = self as region_scope; @mut binding_rscope { base: base, anon_bindings: 0 } } -pub impl @mut binding_rscope: region_scope { - pure fn anon_region(_span: span) -> Result { +pub impl region_scope for @mut binding_rscope { + pure fn anon_region(&self, _span: span) -> Result { // XXX: Unsafe to work around purity unsafe { let idx = self.anon_bindings; @@ -105,10 +106,10 @@ pub impl @mut binding_rscope: region_scope { result::Ok(ty::re_bound(ty::br_anon(idx))) } } - pure fn self_region(span: span) -> Result { + pure fn self_region(&self, span: span) -> Result { self.base.self_region(span) } - pure fn named_region(span: span, id: ast::ident) + pure fn named_region(&self, span: span, id: ast::ident) -> Result { do self.base.named_region(span, id).chain_err |_e| { result::Ok(ty::re_bound(ty::br_named(id))) diff --git a/src/librustc/rustc.rc b/src/librustc/rustc.rc index 62067a4bd7aae..01758a1845d7c 100644 --- a/src/librustc/rustc.rc +++ b/src/librustc/rustc.rc @@ -19,7 +19,6 @@ #[crate_type = "lib"]; #[legacy_modes]; -#[legacy_records]; #[allow(non_implicitly_copyable_typarams)]; #[allow(non_camel_case_types)]; @@ -187,7 +186,7 @@ Available lint options: io::println(fmt!(" %s %7.7s %s\n", padded(max_key, ~"----"), ~"-------", ~"-------")); for lint_dict.each |&k, &v| { - let k = str::replace(k, ~"_", ~"-"); + let k = str::replace(*k, ~"_", ~"-"); io::println(fmt!(" %s %7.7s %s", padded(max_key, k), match v.default { @@ -296,18 +295,12 @@ pub fn run_compiler(args: &~[~str], demitter: diagnostic::Emitter) { compile_input(sess, cfg, input, &odir, &ofile); } +#[deriving_eq] pub enum monitor_msg { fatal, done, } -pub impl monitor_msg : cmp::Eq { - pure fn eq(&self, other: &monitor_msg) -> bool { - ((*self) as uint) == ((*other) as uint) - } - pure fn ne(&self, other: &monitor_msg) -> bool { !(*self).eq(other) } -} - /* This is a sanity check that any failure of the compiler is performed through the diagnostic module and reported properly - we shouldn't be calling @@ -321,12 +314,12 @@ fails without recording a fatal error then we've encountered a compiler bug and need to present an error. */ pub fn monitor(+f: fn~(diagnostic::Emitter)) { - use core::pipes::*; + use core::comm::*; use std::cell::Cell; let (p, ch) = stream(); let ch = SharedChan(ch); let ch_capture = ch.clone(); - match do task::try |move f| { + match do task::try || { let ch = ch_capture.clone(); let ch_capture = ch.clone(); // The 'diagnostics emitter'. Every error, warning, etc. should @@ -375,7 +368,7 @@ pub fn monitor(+f: fn~(diagnostic::Emitter)) { pub fn main() { let args = os::args(); - do monitor |move args, demitter| { + do monitor |demitter| { run_compiler(&args, demitter); } } diff --git a/src/librustc/util/common.rs b/src/librustc/util/common.rs index 85f4ba94e5a9b..7b980b9de0db6 100644 --- a/src/librustc/util/common.rs +++ b/src/librustc/util/common.rs @@ -27,7 +27,7 @@ pub fn indent(op: fn() -> R) -> R { debug!(">>"); let r = op(); debug!("<< (Result = %?)", r); - move r + r } pub struct _indenter { diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs index 43d12c95c4df6..8b0c84cff8343 100644 --- a/src/librustc/util/ppaux.rs +++ b/src/librustc/util/ppaux.rs @@ -145,7 +145,8 @@ pub fn bound_region_to_str_adorned(cx: ctxt, prefix: &str, if cx.sess.verbose() { return fmt!("%s%?%s", prefix, br, sep); } match br { - br_named(id) => fmt!("%s%s%s", prefix, cx.sess.str_of(id), sep), + br_named(id) => fmt!("%s%s%s", prefix, *cx.sess.str_of(id), + sep), br_self => fmt!("%sself%s", prefix, sep), br_anon(_) => prefix.to_str(), br_fresh(_) => prefix.to_str(), @@ -321,7 +322,7 @@ pub fn ty_to_str(cx: ctxt, typ: t) -> ~str { match ident { Some(i) => { s.push_char(' '); - s.push_str(cx.sess.str_of(i)); + s.push_str(*cx.sess.str_of(i)); } _ => { } } @@ -387,7 +388,7 @@ pub fn ty_to_str(cx: ctxt, typ: t) -> ~str { &m.fty.sig) + ~";" } fn field_to_str(cx: ctxt, f: field) -> ~str { - return cx.sess.str_of(f.ident) + ~": " + mt_to_str(cx, f.mt); + return *cx.sess.str_of(f.ident) + ~": " + mt_to_str(cx, f.mt); } // if there is an id, print that instead of the structural type: diff --git a/src/librustdoc/astsrv.rs b/src/librustdoc/astsrv.rs index f07701f05e799..fff2e189eb85c 100644 --- a/src/librustdoc/astsrv.rs +++ b/src/librustdoc/astsrv.rs @@ -23,7 +23,7 @@ use parse; use util; use std::cell::Cell; -use core::pipes::{stream, Chan, SharedChan, Port}; +use core::comm::{stream, Chan, SharedChan, Port}; use core::vec; use core::ops::Drop; use rustc::back::link; @@ -91,7 +91,7 @@ fn run(owner: SrvOwner, source: ~str, parse: Parser) -> T { let res = owner(srv_.clone()); srv_.ch.send(Exit); - move res + res } fn act(po: &Port, source: ~str, parse: Parser) { @@ -120,10 +120,10 @@ pub fn exec( f: fn~(ctxt: Ctxt) -> T ) -> T { let (po, ch) = stream(); - let msg = HandleRequest(fn~(move f, ctxt: Ctxt) { + let msg = HandleRequest(fn~(ctxt: Ctxt) { ch.send(f(ctxt)) }); - srv.ch.send(move msg); + srv.ch.send(msg); po.recv() } diff --git a/src/librustdoc/attr_parser.rs b/src/librustdoc/attr_parser.rs index 0beb651afc4ed..bb9ba93cbe06a 100644 --- a/src/librustdoc/attr_parser.rs +++ b/src/librustdoc/attr_parser.rs @@ -65,9 +65,10 @@ fn doc_metas( pub fn parse_crate(attrs: ~[ast::attribute]) -> CrateAttrs { let link_metas = attr::find_linkage_metas(attrs); + let name = attr::last_meta_item_value_str_by_name(link_metas, ~"name"); CrateAttrs { - name: attr::last_meta_item_value_str_by_name(link_metas, ~"name") + name: name.map(|s| copy **s) } } @@ -97,7 +98,7 @@ fn should_not_extract_crate_name_if_no_name_value_in_link_attribute() { pub fn parse_desc(attrs: ~[ast::attribute]) -> Option<~str> { let doc_strs = do doc_metas(attrs).filter_mapped |meta| { - attr::get_meta_item_value_str(*meta) + attr::get_meta_item_value_str(*meta).map(|s| copy **s) }; if doc_strs.is_empty() { None diff --git a/src/librustdoc/attr_pass.rs b/src/librustdoc/attr_pass.rs index 9669beae57589..85ac952d6d481 100644 --- a/src/librustdoc/attr_pass.rs +++ b/src/librustdoc/attr_pass.rs @@ -115,7 +115,7 @@ fn parse_item_attrs( srv: astsrv::Srv, id: doc::AstId, parse_attrs: fn~(a: ~[ast::attribute]) -> T) -> T { - do astsrv::exec(srv) |move parse_attrs, ctxt| { + do astsrv::exec(srv) |ctxt| { let attrs = match ctxt.ast_map.get(&id) { ast_map::node_item(item, _) => copy item.attrs, ast_map::node_foreign_item(item, _, _) => copy item.attrs, diff --git a/src/librustdoc/config.rs b/src/librustdoc/config.rs index f75f4b83a1d62..e904015e419f6 100644 --- a/src/librustdoc/config.rs +++ b/src/librustdoc/config.rs @@ -59,7 +59,7 @@ pub struct Config { pandoc_cmd: Option<~str> } -pub impl Config: Clone { +pub impl Clone for Config { fn clone(&self) -> Config { copy *self } } @@ -133,7 +133,7 @@ pub fn parse_config_( result::Ok(matches) => { if matches.free.len() == 1 { let input_crate = Path(vec::head(matches.free)); - config_from_opts(&input_crate, &matches, move program_output) + config_from_opts(&input_crate, &matches, program_output) } else if matches.free.is_empty() { result::Err(~"no crates specified") } else { @@ -191,11 +191,11 @@ fn config_from_opts( } } }; - let program_output = Cell(move program_output); + let program_output = Cell(program_output); let result = do result::chain(result) |config| { let pandoc_cmd = getopts::opt_maybe_str(matches, opt_pandoc_cmd()); let pandoc_cmd = maybe_find_pandoc( - &config, pandoc_cmd, move program_output.take()); + &config, pandoc_cmd, program_output.take()); do result::chain(pandoc_cmd) |pandoc_cmd| { result::Ok(Config { pandoc_cmd: pandoc_cmd, @@ -268,7 +268,7 @@ fn should_find_pandoc() { status: 0, out: ~"pandoc 1.8.2.1", err: ~"" } }; - let result = maybe_find_pandoc(&config, None, move mock_program_output); + let result = maybe_find_pandoc(&config, None, mock_program_output); assert result == result::Ok(Some(~"pandoc")); } @@ -284,7 +284,7 @@ fn should_error_with_no_pandoc() { status: 1, out: ~"", err: ~"" } }; - let result = maybe_find_pandoc(&config, None, move mock_program_output); + let result = maybe_find_pandoc(&config, None, mock_program_output); assert result == result::Err(~"couldn't find pandoc"); } diff --git a/src/librustdoc/fold.rs b/src/librustdoc/fold.rs index b9e598dc19d66..d03af547af094 100644 --- a/src/librustdoc/fold.rs +++ b/src/librustdoc/fold.rs @@ -35,7 +35,7 @@ pub struct Fold { fold_struct: FoldStruct } -impl Clone for Fold { +impl Clone for Fold { fn clone(&self) -> Fold { Fold { ctxt: self.ctxt.clone(), @@ -87,25 +87,25 @@ fn mk_fold( fold_struct: FoldStruct ) -> Fold { Fold { - ctxt: move ctxt, - fold_doc: move fold_doc, - fold_crate: move fold_crate, - fold_item: move fold_item, - fold_mod: move fold_mod, - fold_nmod: move fold_nmod, - fold_fn: move fold_fn, - fold_const: move fold_const, - fold_enum: move fold_enum, - fold_trait: move fold_trait, - fold_impl: move fold_impl, - fold_type: move fold_type, - fold_struct: move fold_struct + ctxt: ctxt, + fold_doc: fold_doc, + fold_crate: fold_crate, + fold_item: fold_item, + fold_mod: fold_mod, + fold_nmod: fold_nmod, + fold_fn: fold_fn, + fold_const: fold_const, + fold_enum: fold_enum, + fold_trait: fold_trait, + fold_impl: fold_impl, + fold_type: fold_type, + fold_struct: fold_struct } } -pub fn default_any_fold(ctxt: T) -> Fold { +pub fn default_any_fold(ctxt: T) -> Fold { mk_fold( - move ctxt, + ctxt, |f, d| default_seq_fold_doc(f, d), |f, d| default_seq_fold_crate(f, d), |f, d| default_seq_fold_item(f, d), @@ -121,9 +121,9 @@ pub fn default_any_fold(ctxt: T) -> Fold { ) } -pub fn default_seq_fold(ctxt: T) -> Fold { +pub fn default_seq_fold(ctxt: T) -> Fold { mk_fold( - move ctxt, + ctxt, |f, d| default_seq_fold_doc(f, d), |f, d| default_seq_fold_crate(f, d), |f, d| default_seq_fold_item(f, d), @@ -139,9 +139,9 @@ pub fn default_seq_fold(ctxt: T) -> Fold { ) } -pub fn default_par_fold(ctxt: T) -> Fold { +pub fn default_par_fold(ctxt: T) -> Fold { mk_fold( - move ctxt, + ctxt, |f, d| default_seq_fold_doc(f, d), |f, d| default_seq_fold_crate(f, d), |f, d| default_seq_fold_item(f, d), diff --git a/src/librustdoc/markdown_pass.rs b/src/librustdoc/markdown_pass.rs index bf499e2c5d0ec..ff9faabaec24b 100644 --- a/src/librustdoc/markdown_pass.rs +++ b/src/librustdoc/markdown_pass.rs @@ -74,7 +74,7 @@ fn run( ~"mods last", mods_last ).f)(srv, copy doc); - write_markdown(sorted_doc, move writer_factory); + write_markdown(sorted_doc, writer_factory); return doc; } @@ -148,7 +148,7 @@ fn should_request_new_writer_for_each_page() { let (srv, doc) = test::create_doc_srv(~"mod a { }"); // Split the document up into pages let doc = (page_pass::mk_pass(config::DocPerMod).f)(srv, doc); - write_markdown(doc, move writer_factory); + write_markdown(doc, writer_factory); // We expect two pages to have been written for iter::repeat(2) { po.recv(); @@ -180,7 +180,7 @@ fn should_write_title_for_each_page() { let (srv, doc) = test::create_doc_srv( ~"#[link(name = \"core\")]; mod a { }"); let doc = (page_pass::mk_pass(config::DocPerMod).f)(srv, doc); - write_markdown(doc, move writer_factory); + write_markdown(doc, writer_factory); for iter::repeat(2) { let (page, markdown) = po.recv(); match page { @@ -761,7 +761,7 @@ fn should_write_impl_header() { #[test] fn should_write_impl_header_with_trait() { - let markdown = test::render(~"impl int: j { fn a() { } }"); + let markdown = test::render(~"impl j for int { fn a() { } }"); assert str::contains(markdown, ~"## Implementation of `j` for `int`"); } @@ -894,7 +894,7 @@ mod test { doc: doc::Doc ) -> ~str { let (writer_factory, po) = markdown_writer::future_writer_factory(); - write_markdown(doc, move writer_factory); + write_markdown(doc, writer_factory); return po.recv().second(); } @@ -903,7 +903,7 @@ mod test { doc: doc::Doc ) -> ~str { let (writer_factory, po) = markdown_writer::future_writer_factory(); - let pass = mk_pass(move writer_factory); + let pass = mk_pass(writer_factory); (pass.f)(srv, doc); return po.recv().second(); } diff --git a/src/librustdoc/markdown_writer.rs b/src/librustdoc/markdown_writer.rs index f0d9effe6fc51..45a8aa9fd2920 100644 --- a/src/librustdoc/markdown_writer.rs +++ b/src/librustdoc/markdown_writer.rs @@ -20,12 +20,12 @@ use core::io::ReaderUtil; use core::io; use core::libc; use core::os; -use core::pipes; +use core::comm; use core::result; use core::run; use core::str; use core::task; -use core::pipes::*; +use core::comm::*; use std::future; use syntax; @@ -128,13 +128,13 @@ fn pandoc_writer( os::close(pipe_err.out); os::close(pipe_in.out); - let (stdout_po, stdout_ch) = pipes::stream(); - do task::spawn_sched(task::SingleThreaded) |move stdout_ch| { + let (stdout_po, stdout_ch) = comm::stream(); + do task::spawn_sched(task::SingleThreaded) || { stdout_ch.send(readclose(pipe_out.in)); } - let (stderr_po, stderr_ch) = pipes::stream(); - do task::spawn_sched(task::SingleThreaded) |move stderr_ch| { + let (stderr_po, stderr_ch) = comm::stream(); + do task::spawn_sched(task::SingleThreaded) || { stderr_ch.send(readclose(pipe_err.in)); } let stdout = stdout_po.recv(); @@ -169,7 +169,7 @@ fn readclose(fd: libc::c_int) -> ~str { fn generic_writer(process: fn~(markdown: ~str)) -> Writer { let (po, ch) = stream::(); - do task::spawn |move process, move setup_ch| { + do task::spawn || { let mut markdown = ~""; let mut keep_going = true; while keep_going { @@ -178,7 +178,7 @@ fn generic_writer(process: fn~(markdown: ~str)) -> Writer { Done => keep_going = false } } - process(move markdown); + process(markdown); }; fn~(instr: WriteInstr) { ch.send(instr); @@ -296,26 +296,26 @@ pub fn future_writer_factory( let (markdown_po, markdown_ch) = stream(); let markdown_ch = SharedChan(markdown_ch); let writer_factory = fn~(page: doc::Page) -> Writer { - let (writer_po, writer_ch) = pipes::stream(); + let (writer_po, writer_ch) = comm::stream(); let markdown_ch = markdown_ch.clone(); - do task::spawn |move writer_ch| { + do task::spawn || { let (writer, future) = future_writer(); - writer_ch.send(move writer); + writer_ch.send(writer); let s = future.get(); markdown_ch.send((copy page, s)); } writer_po.recv() }; - (move writer_factory, markdown_po) + (writer_factory, markdown_po) } fn future_writer() -> (Writer, future::Future<~str>) { - let (port, chan) = pipes::stream(); - let writer = fn~(move chan, instr: WriteInstr) { + let (port, chan) = comm::stream(); + let writer = fn~(instr: WriteInstr) { chan.send(copy instr); }; - let future = do future::from_fn |move port| { + let future = do future::from_fn || { let mut res = ~""; loop { match port.recv() { @@ -325,5 +325,5 @@ fn future_writer() -> (Writer, future::Future<~str>) { } res }; - (move writer, move future) + (writer, future) } diff --git a/src/librustdoc/page_pass.rs b/src/librustdoc/page_pass.rs index 08abe4b351b6f..2a2c388864723 100644 --- a/src/librustdoc/page_pass.rs +++ b/src/librustdoc/page_pass.rs @@ -30,7 +30,7 @@ use util; use core::option; use core::vec; -use core::pipes::*; +use core::comm::*; use syntax::ast; pub fn mk_pass(output_style: config::OutputStyle) -> Pass { @@ -71,7 +71,7 @@ fn make_doc_from_pages(page_port: &PagePort) -> doc::Doc { loop { let val = page_port.recv(); if val.is_some() { - pages += ~[option::unwrap(move val)]; + pages += ~[option::unwrap(val)]; } else { break; } diff --git a/src/librustdoc/path_pass.rs b/src/librustdoc/path_pass.rs index 7dc8d0202cbf1..c03eb06d2dde0 100644 --- a/src/librustdoc/path_pass.rs +++ b/src/librustdoc/path_pass.rs @@ -31,14 +31,14 @@ pub fn mk_pass() -> Pass { struct Ctxt { srv: astsrv::Srv, - mut path: ~[~str] + path: @mut ~[~str] } impl Clone for Ctxt { fn clone(&self) -> Ctxt { Ctxt { srv: self.srv.clone(), - path: copy self.path + path: @mut copy *self.path } } } @@ -47,21 +47,21 @@ impl Clone for Ctxt { fn run(srv: astsrv::Srv, doc: doc::Doc) -> doc::Doc { let ctxt = Ctxt { srv: srv, - mut path: ~[] + path: @mut ~[] }; let fold = Fold { ctxt: ctxt.clone(), fold_item: fold_item, fold_mod: fold_mod, fold_nmod: fold_nmod, - .. fold::default_any_fold(move ctxt) + .. fold::default_any_fold(ctxt) }; (fold.fold_doc)(&fold, doc) } fn fold_item(fold: &fold::Fold, doc: doc::ItemDoc) -> doc::ItemDoc { doc::ItemDoc { - path: copy fold.ctxt.path, + path: copy *fold.ctxt.path, .. doc } } diff --git a/src/librustdoc/rustdoc.rc b/src/librustdoc/rustdoc.rc index b3e9c43e87a1e..7d94352cc8233 100644 --- a/src/librustdoc/rustdoc.rc +++ b/src/librustdoc/rustdoc.rc @@ -149,5 +149,5 @@ fn time(what: ~str, f: fn() -> T) -> T { let rv = f(); let end = std::time::precise_time_s(); info!("time: %3.3f s %s", end - start, what); - move rv + rv } diff --git a/src/librustdoc/sort_pass.rs b/src/librustdoc/sort_pass.rs index b7614a785c742..3bdb08974044d 100644 --- a/src/librustdoc/sort_pass.rs +++ b/src/librustdoc/sort_pass.rs @@ -42,7 +42,7 @@ fn run( ) -> doc::Doc { let fold = Fold { fold_mod: fold_mod, - .. fold::default_any_fold(move lteq) + .. fold::default_any_fold(lteq) }; (fold.fold_doc)(&fold, doc) } diff --git a/src/librustdoc/text_pass.rs b/src/librustdoc/text_pass.rs index 79ba8f0684a58..b9dbe523fdd33 100644 --- a/src/librustdoc/text_pass.rs +++ b/src/librustdoc/text_pass.rs @@ -42,14 +42,14 @@ fn run( op: Op ) -> doc::Doc { let op = NominalOp { - op: move op + op: op }; let fold = Fold { fold_item: fold_item, fold_enum: fold_enum, fold_trait: fold_trait, fold_impl: fold_impl, - .. fold::default_any_fold(move op) + .. fold::default_any_fold(op) }; (fold.fold_doc)(&fold, doc) } @@ -76,7 +76,7 @@ fn apply_to_sections( op: NominalOp, sections: ~[doc::Section] ) -> ~[doc::Section] { - sections.map(|section, copy op| doc::Section { + sections.map(|section| doc::Section { header: (op.op)(copy section.header), body: (op.op)(copy section.body) }) @@ -89,7 +89,7 @@ fn fold_enum( let fold_copy = copy *fold; doc::EnumDoc { - variants: do doc.variants.map |variant, copy fold_copy| { + variants: do doc.variants.map |variant| { doc::VariantDoc { desc: maybe_apply_op(copy fold_copy.ctxt, &variant.desc), .. copy *variant diff --git a/src/librustdoc/tystr_pass.rs b/src/librustdoc/tystr_pass.rs index c14eb32022fb1..b39cee875251a 100644 --- a/src/librustdoc/tystr_pass.rs +++ b/src/librustdoc/tystr_pass.rs @@ -137,7 +137,7 @@ fn fold_enum( variants: do vec::map(doc.variants) |variant| { let sig = { let variant = copy *variant; - do astsrv::exec(srv.clone()) |copy variant, ctxt| { + do astsrv::exec(srv.clone()) |ctxt| { match ctxt.ast_map.get(&doc_id) { ast_map::node_item(@ast::item { node: ast::item_enum(ref enum_definition, _), _ @@ -198,7 +198,7 @@ fn get_method_sig( item_id: doc::AstId, method_name: ~str ) -> Option<~str> { - do astsrv::exec(srv) |copy method_name, ctxt| { + do astsrv::exec(srv) |ctxt| { match ctxt.ast_map.get(&item_id) { ast_map::node_item(@ast::item { node: ast::item_trait(_, _, ref methods), _ @@ -297,7 +297,7 @@ fn fold_impl( #[test] fn should_add_impl_trait_types() { - let doc = test::mk_doc(~"impl int: j { fn a() { } }"); + let doc = test::mk_doc(~"impl j for int { fn a() { } }"); assert doc.cratemod().impls()[0].trait_types[0] == ~"j"; } diff --git a/src/librustdoc/util.rs b/src/librustdoc/util.rs index 3ec9d17c854be..61c02bf684938 100644 --- a/src/librustdoc/util.rs +++ b/src/librustdoc/util.rs @@ -17,6 +17,6 @@ pub struct NominalOp { op: T } -impl Clone for NominalOp { +impl Clone for NominalOp { fn clone(&self) -> NominalOp { copy *self } } diff --git a/src/librusti/rusti.rc b/src/librusti/rusti.rc index 87beeaf4ec210..0fe533e3dd9f0 100644 --- a/src/librusti/rusti.rc +++ b/src/librusti/rusti.rc @@ -17,7 +17,6 @@ #[crate_type = "lib"]; -#[legacy_records]; #[no_core]; #[allow(vecs_implicitly_copyable, @@ -131,7 +130,7 @@ fn record(repl: Repl, blk: @ast::blk, intr: @token::ident_interner) -> Repl { /// Run an input string in a Repl, returning the new Repl. fn run(repl: Repl, input: ~str) -> Repl { - let options: @session::options = @{ + let options = @session::options { crate_type: session::unknown_crate, binary: repl.binary, addl_lib_search_paths: repl.lib_search_paths.map(|p| Path(*p)), @@ -157,7 +156,7 @@ fn run(repl: Repl, input: ~str) -> Repl { let outputs = driver::build_output_filenames(wrapped, &None, &None, sess); debug!("calling compile_upto"); - let {crate: crate, tcx: _} = driver::compile_upto(sess, cfg, wrapped, + let (crate, _) = driver::compile_upto(sess, cfg, wrapped, driver::cu_everything, Some(outputs)); @@ -196,7 +195,7 @@ fn run(repl: Repl, input: ~str) -> Repl { fn compile_crate(src_filename: ~str, binary: ~str) -> Option { match do task::try { let src_path = Path(src_filename); - let options: @session::options = @{ + let options = @session::options { binary: binary, addl_lib_search_paths: ~[os::getcwd()], .. *session::basic_options() @@ -351,7 +350,7 @@ fn run_line(repl: &mut Repl, in: io::Reader, out: io::Writer, line: ~str) if !cmd.is_empty() { let args = if len > 1 { - vec::slice(split, 1, len) + vec::slice(split, 1, len).to_vec() } else { ~[] }; match run_cmd(repl, in, out, cmd, args) { @@ -368,7 +367,7 @@ fn run_line(repl: &mut Repl, in: io::Reader, out: io::Writer, line: ~str) } let r = *repl; - let result = do task::try |copy r| { + let result = do task::try { run(r, line) }; diff --git a/src/librusti/wrapper.rs b/src/librusti/wrapper.rs index aebc5e77c29d0..7766602dd89bf 100644 --- a/src/librusti/wrapper.rs +++ b/src/librusti/wrapper.rs @@ -16,7 +16,6 @@ #[allow(non_implicitly_copyable_typarams)]; #[allow(owned_heap_memory)]; #[allow(path_statement)]; -#[allow(structural_records)]; #[allow(unrecognized_lint)]; #[allow(unused_imports)]; #[allow(vecs_implicitly_copyable)]; diff --git a/src/librustpkg/rustpkg.rc b/src/librustpkg/rustpkg.rc new file mode 100644 index 0000000000000..c16a56249ffab --- /dev/null +++ b/src/librustpkg/rustpkg.rc @@ -0,0 +1,1036 @@ +// 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. + +// rustpkg - a purely function package manager and build system + +#[link(name = "rustpkg", + vers = "0.6", + uuid = "25de5e6e-279e-4a20-845c-4cabae92daaf", + url = "https://github.com/mozilla/rust/tree/master/src/librustpkg")]; + +#[crate_type = "lib"]; +#[no_core]; +#[allow(vecs_implicitly_copyable, + non_implicitly_copyable_typarams)]; + +extern mod core(vers = "0.6"); +extern mod std(vers = "0.6"); +extern mod rustc(vers = "0.6"); +extern mod syntax(vers = "0.6"); + +use core::*; +use io::{ReaderUtil, WriterUtil}; +use std::{json, semver, getopts}; +use std::net::url; +use hashmap::linear::LinearMap; +use rustc::metadata::filesearch; +use rustc::driver::{driver, session}; +use syntax::{ast, attr, codemap, diagnostic, parse, visit}; +use syntax::codemap::spanned; + +mod usage; +mod util; + +use util::Package; + +struct PackageScript { + id: ~str, + name: ~str, + vers: semver::Version, + crates: ~[~str], + deps: ~[(~str, Option<~str>)], + input: driver::input, + sess: session::Session, + cfg: ast::crate_cfg, + crate: @ast::crate, + custom: bool +} + +impl PackageScript { + static fn parse(parent: &Path) -> Result { + let script = parent.push(~"pkg.rs"); + + if !os::path_exists(&script) { + return result::Err(~"no pkg.rs file"); + } + + let binary = os::args()[0]; + let options = @session::options { + binary: binary, + crate_type: session::bin_crate, + .. *session::basic_options() + }; + let input = driver::file_input(script); + let sess = driver::build_session(options, diagnostic::emit); + let cfg = driver::build_configuration(sess, binary, input); + let (crate, _) = driver::compile_upto(sess, cfg, input, + driver::cu_parse, None); + let mut id = None; + let mut vers = None; + let mut crates = ~[]; + let mut deps = ~[]; + + fn load_pkg_attr(mis: ~[@ast::meta_item]) -> (Option<~str>, + Option<~str>) { + let mut id = None; + let mut vers = None; + + for mis.each |a| { + match a.node { + ast::meta_name_value(v, spanned { + node: ast::lit_str(s), + span: _}) => { + match *v { + ~"id" => id = Some(*s), + ~"vers" => vers = Some(*s), + _ => () + } + } + _ => {} + } + } + + (id, vers) + } + + fn load_pkg_dep_attr(mis: ~[@ast::meta_item]) -> (Option<~str>, + Option<~str>) { + let mut url = None; + let mut target = None; + + for mis.each |a| { + match a.node { + ast::meta_name_value(v, spanned { + node: ast::lit_str(s), + span: _}) => { + match *v { + ~"url" => url = Some(*s), + ~"target" => target = Some(*s), + _ => () + } + } + _ => {} + } + } + + (url, target) + } + + fn load_pkg_crate_attr(mis: ~[@ast::meta_item]) -> Option<~str> { + let mut file = None; + + for mis.each |a| { + match a.node { + ast::meta_name_value(v, spanned { + node: ast::lit_str(s), + span: _}) => { + match *v { + ~"file" => file = Some(*s), + _ => () + } + } + _ => {} + } + } + + file + } + + for crate.node.attrs.each |a| { + match a.node.value.node { + ast::meta_list(v, mis) => { + match *v { + ~"pkg" => { + let (i, v) = load_pkg_attr(mis); + + id = i; + vers = v; + } + ~"pkg_dep" => { + let (u, t) = load_pkg_dep_attr(mis); + + if u.is_none() { + fail!(~"pkg_dep attr without a url value"); + } + + deps.push((u.get(), t)); + } + ~"pkg_crate" => { + let f = load_pkg_crate_attr(mis); + + if f.is_none() { + fail!(~"pkg_file attr without a file value"); + } + + crates.push(f.get()); + } + _ => {} + } + } + _ => {} + } + } + + let mut custom = false; + + // If we hit a function, we assume they want to use + // the build API. + for crate.node.module.items.each |i| { + match i.node { + ast::item_fn(_, _, _, _) => { + custom = true; + + break; + } + _ => {} + } + } + + if id.is_none() || vers.is_none() { + return result::Err(~"pkg attr without (id, vers) values"); + } + + let id = id.get(); + let name = match util::parse_name(id) { + result::Ok(name) => name, + result::Err(err) => return result::Err(err) + }; + let vers = match util::parse_vers(vers.get()) { + result::Ok(vers) => vers, + result::Err(err) => return result::Err(err) + }; + + result::Ok(PackageScript { + id: id, + name: name, + vers: vers, + crates: crates, + deps: deps, + input: input, + sess: sess, + cfg: cfg, + crate: crate, + custom: custom + }) + } + + // Build the bootstrap and run a command + // FIXME (#4432): Use workcache to only compile the script when changed + fn run(&self, cmd: ~str, test: bool) -> int { + let work_dir = self.work_dir(); + let input = self.input; + let sess = self.sess; + let cfg = self.cfg; + let crate = util::ready_crate(sess, self.crate); + let outputs = driver::build_output_filenames(input, &Some(work_dir), + &None, sess); + let exe = work_dir.push(~"pkg" + util::exe_suffix()); + let root = filesearch::get_rustpkg_sysroot().get().pop().pop(); + + driver::compile_rest(sess, cfg, driver::cu_parse, + Some(outputs), Some(crate)); + run::run_program(exe.to_str(), ~[root.to_str(), cmd, test.to_str()]) + } + + fn hash(&self) -> ~str { + fmt!("%s-%s-%s", self.name, util::hash(self.id + self.vers.to_str()), + self.vers.to_str()) + } + + fn work_dir(&self) -> Path { + util::root().push(~"work").push(self.hash()) + } +} + +struct Ctx { + cfgs: ~[~str], + json: bool, + dep_cache: @mut LinearMap<~str, bool> +} + +impl Ctx { + fn run(&self, cmd: ~str, args: ~[~str]) { + let root = util::root(); + + util::need_dir(&root); + util::need_dir(&root.push(~"work")); + util::need_dir(&root.push(~"lib")); + util::need_dir(&root.push(~"bin")); + util::need_dir(&root.push(~"tmp")); + + fn sep_name_vers(in: ~str) -> (Option<~str>, Option<~str>) { + let mut name = None; + let mut vers = None; + let parts = str::split_char(in, '@'); + + if parts.len() >= 1 { + name = Some(parts[0]); + + if parts.len() >= 2 { + vers = Some(parts[1]); + } + } + + (name, vers) + } + + match cmd { + ~"build" => { + self.build(&os::getcwd(), true, false, false); + } + ~"clean" => { + self.clean(); + } + ~"do" => { + if args.len() < 1 { + return usage::do_cmd(); + } + + self.do_cmd(args[0]); + } + ~"info" => { + self.info(); + } + ~"install" => { + self.install(if args.len() >= 1 { Some(args[0]) } + else { None }, + if args.len() >= 2 { Some(args[1]) } + else { None }, false); + } + ~"prefer" => { + if args.len() < 1 { + return usage::uninstall(); + } + + let (name, vers) = sep_name_vers(args[0]); + + self.prefer(name.get(), vers); + } + ~"test" => { + self.test(); + } + ~"uninstall" => { + if args.len() < 1 { + return usage::uninstall(); + } + + let (name, vers) = sep_name_vers(args[0]); + + self.uninstall(name.get(), vers); + } + ~"unprefer" => { + if args.len() < 1 { + return usage::uninstall(); + } + + let (name, vers) = sep_name_vers(args[0]); + + self.unprefer(name.get(), vers); + } + _ => fail!(~"reached an unhandled command") + } + } + + fn do_cmd(&self, cmd: ~str) -> bool { + match cmd { + ~"build" | ~"test" => { + util::error(~"that command cannot be manually called"); + + return false; + } + _ => {} + } + + let cwd = &os::getcwd(); + let script = match PackageScript::parse(cwd) { + result::Ok(script) => script, + result::Err(err) => { + util::error(err); + + return false; + } + }; + let status = script.run(cmd, false); + + if status == 42 { + util::error(~"no fns are listening for that cmd"); + + return false; + } + + status == 0 + } + + fn build(&self, dir: &Path, verbose: bool, opt: bool, + test: bool) -> Option { + let cwd = &os::getcwd(); + let script = match PackageScript::parse(dir) { + result::Ok(script) => script, + result::Err(err) => { + util::error(err); + + return None; + } + }; + let work_dir = script.work_dir(); + let mut success = true; + + util::need_dir(&work_dir); + + if script.deps.len() >= 1 { + util::note(~"installing dependencies"); + + for script.deps.each |&dep| { + let (url, target) = dep; + + success = self.install(Some(url), target, true); + + if !success { break; } + } + + + if !success { + util::error( + fmt!("building %s v%s failed: a dep wasn't installed", + script.name, script.vers.to_str())); + + return None; + } + + util::note(~"installed dependencies"); + } + + // Build imperative crates + os::change_dir(dir); + + if script.custom { + let status = script.run(~"build", test); + + if status != 0 && status != 42 { + util::error( + fmt!("building %s v%s failed: custom logic failed (%d)", + script.name, script.vers.to_str(), status)); + + return None; + } + } + + os::change_dir(cwd); + + for script.crates.each |&crate| { + let crate = &dir.push_rel(&Path(crate)).normalize(); + + util::note(fmt!("compiling %s", crate.to_str())); + + success = self.compile(crate, &work_dir, ~[], + ~[], opt, test); + + if !success { break; } + } + + if !success { + util::error( + fmt!("building %s v%s failed: a crate failed to compile", + script.name, script.vers.to_str())); + + return None; + } + + if verbose { + util::note(fmt!("built %s v%s", script.name, + script.vers.to_str())); + } + + Some(script) + } + + fn compile(&self, crate: &Path, dir: &Path, flags: ~[~str], + cfgs: ~[~str], opt: bool, test: bool) -> bool { + util::compile_crate(None, crate, dir, flags, cfgs, opt, test) + } + + fn clean(&self) -> bool { + let script = match PackageScript::parse(&os::getcwd()) { + result::Ok(script) => script, + result::Err(err) => { + util::error(err); + + return false; + } + }; + let dir = script.work_dir(); + + util::note(fmt!("cleaning %s v%s (%s)", script.name, + script.vers.to_str(), script.id)); + + if os::path_exists(&dir) { + util::remove_dir_r(&dir); + util::note(fmt!("removed %s", dir.to_str())); + } + + util::note(fmt!("cleaned %s v%s", script.name, + script.vers.to_str())); + + true + } + + fn info(&self) { + if self.json { + match PackageScript::parse(&os::getcwd()) { + result::Ok(script) => { + let mut map = ~LinearMap::new(); + + map.insert(~"id", json::String(script.id)); + map.insert(~"name", json::String(script.name)); + map.insert(~"vers", json::String(script.vers.to_str())); + map.insert(~"deps", json::List(do script.deps.map |&dep| { + let (url, target) = dep; + let mut inner = ~LinearMap::new(); + + inner.insert(~"url", json::String(url)); + + if !target.is_none() { + inner.insert(~"target", + json::String(target.get())); + } + + json::Object(inner) + })); + + io::println(json::to_pretty_str(&json::Object(map))); + } + result::Err(_) => io::println(~"{}") + } + } else { + let script = match PackageScript::parse(&os::getcwd()) { + result::Ok(script) => script, + result::Err(err) => { + util::error(err); + + return; + } + }; + + util::note(fmt!("id: %s", script.id)); + util::note(fmt!("name: %s", script.name)); + util::note(fmt!("vers: %s", script.vers.to_str())); + util::note(fmt!("deps: %s", + if script.deps.len() > 0 { + ~"" + } else { + ~"none" + })); + + for script.deps.each |&dep| { + let (url, target) = dep; + + util::note(fmt!(" <%s> (%s)", url, match target { + Some(target) => target, + None => ~"" + })); + } + } + } + + fn install(&self, url: Option<~str>, + target: Option<~str>, cache: bool) -> bool { + let mut success; + let mut dir; + + if url.is_none() { + util::note(~"installing from the cwd"); + + dir = os::getcwd(); + } else { + let url = url.get(); + let hash = util::hash(if !target.is_none() { url + target.get() } + else { url }); + + if self.dep_cache.contains_key(&hash) { + util::warn(~"already installed dep this run"); + + return true; + } + + self.dep_cache.insert(hash, true); + + dir = util::root().push(~"tmp").push(hash); + + if cache && os::path_exists(&dir) { + return true; + } + + success = self.fetch(&dir, url, target); + + if !success { + return false; + } + } + + let script = match self.build(&dir, false, true, false) { + Some(script) => script, + None => { + return false; + } + }; + let work_dir = script.work_dir(); + let from_bin_dir = work_dir.push(~"bin"); + let from_lib_dir = work_dir.push(~"lib"); + let to_bin_dir = util::root().push(~"bin"); + let to_lib_dir = util::root().push(~"lib"); + let mut bins = ~[]; + let mut libs = ~[]; + + for os::walk_dir(&from_bin_dir) |bin| { + let to = to_bin_dir.push_rel(&bin.file_path()); + + os::copy_file(bin, &to); + bins.push(to.to_str()); + } + + for os::walk_dir(&from_lib_dir) |lib| { + let to = to_lib_dir.push_rel(&lib.file_path()); + + os::copy_file(lib, &to); + libs.push(to.to_str()); + } + + let package = Package { + id: script.id, + vers: script.vers, + bins: bins, + libs: libs + }; + + util::note(fmt!("installed %s v%s", script.name, + script.vers.to_str())); + util::add_pkg(&package); + + true + } + + fn fetch(&self, dir: &Path, url: ~str, target: Option<~str>) -> bool { + let url = if str::find_str(url, "://").is_none() { + ~"http://" + url } + else { url }; + let url = match url::from_str(url) { + result::Ok(url) => url, + result::Err(err) => { + util::error(fmt!("failed parsing %s", err.to_lower())); + + return false; + } + }; + let str = url.to_str(); + + match Path(url.path).filetype() { + Some(ext) => { + if ext == ~".git" { + return self.fetch_git(dir, str, target); + } + } + None => {} + } + + match url.scheme { + ~"git" => self.fetch_git(dir, str, target), + ~"http" | ~"ftp" | ~"file" => self.fetch_curl(dir, str), + _ => { + util::warn(~"unknown url scheme to fetch, using curl"); + self.fetch_curl(dir, str) + } + } + } + + fn fetch_curl(&self, dir: &Path, url: ~str) -> bool { + util::note(fmt!("fetching from %s using curl", url)); + + let tar = dir.dir_path().push(&dir.file_path().to_str() + ~".tar"); + + if run::program_output(~"curl", ~[~"-f", ~"-s", + ~"-o", tar.to_str(), + url]).status != 0 { + util::error(~"fetching failed: downloading using curl failed"); + + return false; + } + + if run::program_output(~"tar", ~[~"-x", ~"--strip-components=1", + ~"-C", dir.to_str(), ~"-f", + tar.to_str()]).status != 0 { + util::error(~"fetching failed: extracting using tar failed" + + ~"(is it a valid tar archive?)"); + + return false; + } + + true + } + + fn fetch_git(&self, dir: &Path, url: ~str, target: Option<~str>) -> bool { + util::note(fmt!("fetching from %s using git", url)); + + // Git can't clone into a non-empty directory + util::remove_dir_r(dir); + + if run::program_output(~"git", ~[~"clone", url, + dir.to_str()]).status != 0 { + util::error(~"fetching failed: can't clone repository"); + + return false; + } + + if !target.is_none() { + let mut success = true; + + do util::temp_change_dir(dir) { + success = run::program_output(~"git", + ~[~"checkout", + target.get()]).status != 0 + } + + if !success { + util::error(~"fetching failed: can't checkout target"); + + return false; + } + } + + true + } + + fn prefer(&self, id: ~str, vers: Option<~str>) -> bool { + let package = match util::get_pkg(id, vers) { + result::Ok(package) => package, + result::Err(err) => { + util::error(err); + + return false; + } + }; + let name = match util::parse_name(package.id) { + result::Ok(name) => name, + result::Err(err) => { + util::error(err); + + return false; + } + }; + + util::note(fmt!("preferring %s v%s (%s)", name, package.vers.to_str(), + package.id)); + + let bin_dir = util::root().push(~"bin"); + + for package.bins.each |&bin| { + let path = Path(bin); + let name = str::split_char(path.file_path().to_str(), '-')[0]; + let out = bin_dir.push(name); + + util::link_exe(&path, &out); + util::note(fmt!("linked %s", out.to_str())); + } + + util::note(fmt!("preferred %s v%s", name, package.vers.to_str())); + + true + } + + fn test(&self) -> bool { + let script = match self.build(&os::getcwd(), false, false, true) { + Some(script) => script, + None => { + return false; + } + }; + let work_dir = script.work_dir(); + let test_dir = work_dir.push(~"test"); + + for os::walk_dir(&test_dir) |test| { + util::note(fmt!("running %s", test.to_str())); + + let status = run::run_program(test.to_str(), ~[]); + + if status != 0 { + os::set_exit_status(status); + } + } + + // Run custom test listener + if script.custom { + let status = script.run(~"test", false); + + if status != 0 && status != 42 { + util::error( + fmt!("testing %s v%s failed: custom logic failed (%d)", + script.name, script.vers.to_str(), status)); + + os::set_exit_status(status); + } + } + + util::note(fmt!("tested %s v%s", script.name, script.vers.to_str())); + + true + } + + fn uninstall(&self, id: ~str, vers: Option<~str>) -> bool { + let package = match util::get_pkg(id, vers) { + result::Ok(package) => package, + result::Err(err) => { + util::error(err); + + return false; + } + }; + let name = match util::parse_name(package.id) { + result::Ok(name) => name, + result::Err(err) => { + util::error(err); + + return false; + } + }; + + util::note(fmt!("uninstalling %s v%s (%s)", name, + package.vers.to_str(), package.id)); + + for vec::append(package.bins, package.libs).each |&file| { + let path = Path(file); + + if os::path_exists(&path) { + if os::remove_file(&path) { + util::note(fmt!("removed %s", path.to_str())); + } else { + util::error(fmt!("could not remove %s", path.to_str())); + } + } + } + + util::note(fmt!("uninstalled %s v%s", name, package.vers.to_str())); + util::remove_pkg(&package); + + true + } + + fn unprefer(&self, id: ~str, vers: Option<~str>) -> bool { + let package = match util::get_pkg(id, vers) { + result::Ok(package) => package, + result::Err(err) => { + util::error(err); + + return false; + } + }; + let name = match util::parse_name(package.id) { + result::Ok(name) => name, + result::Err(err) => { + util::error(err); + + return false; + } + }; + + util::note(fmt!("unpreferring %s v%s (%s)", name, + package.vers.to_str(), package.id)); + + let bin_dir = util::root().push(~"bin"); + + for package.bins.each |&bin| { + let path = Path(bin); + let name = str::split_char(path.file_path().to_str(), '-')[0]; + let out = bin_dir.push(name); + + if os::path_exists(&out) { + if os::remove_file(&out) { + util::note(fmt!("unlinked %s", out.to_str())); + } else { + util::error(fmt!("could not unlink %s", out.to_str())); + } + } + } + + util::note(fmt!("unpreferred %s v%s", name, package.vers.to_str())); + + true + } +} + +pub fn main() { + let args = os::args(); + let opts = ~[getopts::optflag(~"h"), getopts::optflag(~"help"), + getopts::optflag(~"j"), getopts::optflag(~"json"), + getopts::optmulti(~"c"), getopts::optmulti(~"cfg")]; + let matches = &match getopts::getopts(args, opts) { + result::Ok(m) => m, + result::Err(f) => { + util::error(fmt!("%s", getopts::fail_str(f))); + + return; + } + }; + let help = getopts::opt_present(matches, ~"h") || + getopts::opt_present(matches, ~"help"); + let json = getopts::opt_present(matches, ~"j") || + getopts::opt_present(matches, ~"json"); + let cfgs = vec::append(getopts::opt_strs(matches, ~"cfg"), + getopts::opt_strs(matches, ~"c")); + let mut args = copy matches.free; + + args.shift(); + + if (args.len() < 1) { + return usage::general(); + } + + let cmd = args.shift(); + + if !util::is_cmd(cmd) { + return usage::general(); + } else if help { + return match cmd { + ~"build" => usage::build(), + ~"clean" => usage::clean(), + ~"do" => usage::do_cmd(), + ~"info" => usage::info(), + ~"install" => usage::install(), + ~"prefer" => usage::prefer(), + ~"test" => usage::test(), + ~"uninstall" => usage::uninstall(), + ~"unprefer" => usage::unprefer(), + _ => usage::general() + }; + } + + Ctx { + cfgs: cfgs, + json: json, + dep_cache: @mut LinearMap::new() + }.run(cmd, args); +} + +/// A crate is a unit of Rust code to be compiled into a binary or library +pub struct Crate { + file: ~str, + flags: ~[~str], + cfgs: ~[~str] +} + +pub struct Listener { + cmds: ~[~str], + cb: fn~() +} + +pub fn run(listeners: ~[Listener]) { + let rcmd = os::args()[2]; + let mut found = false; + + for listeners.each |listener| { + for listener.cmds.each |&cmd| { + if cmd == rcmd { + (listener.cb)(); + + found = true; + + break; + } + } + } + + if !found { + os::set_exit_status(42); + } +} + +pub impl Crate { + pub fn flag(&self, flag: ~str) -> Crate { + Crate { + flags: vec::append(copy self.flags, ~[flag]), + .. copy *self + } + } + + pub fn flags(&self, flags: ~[~str]) -> Crate { + Crate { + flags: vec::append(copy self.flags, flags), + .. copy *self + } + } + + pub fn cfg(&self, cfg: ~str) -> Crate { + Crate { + cfgs: vec::append(copy self.cfgs, ~[cfg]), + .. copy *self + } + } + + pub fn cfgs(&self, cfgs: ~[~str]) -> Crate { + Crate { + cfgs: vec::append(copy self.cfgs, cfgs), + .. copy *self + } + } +} + +/// Create a crate target from a source file +pub fn Crate(file: ~str) -> Crate { + Crate { + file: file, + flags: ~[], + cfgs: ~[] + } +} + +/** + * Get the working directory of the package script. + * Assumes that the package script has been compiled + * in is the working directory. + */ +pub fn work_dir() -> Path { + os::self_exe_path().get() +} + +/** + * Get the source directory of the package (i.e. + * where the crates are located). Assumes + * that the cwd is changed to it before + * running this executable. + */ +pub fn src_dir() -> Path { + os::getcwd() +} + +/// Build a set of crates, should be called once +pub fn build(crates: ~[Crate]) -> bool { + let args = os::args(); + let dir = src_dir(); + let work_dir = work_dir(); + let mut success = true; + let sysroot = Path(args[1]); + let test = args[3] == ~"true"; + + for crates.each |&crate| { + let path = &dir.push_rel(&Path(crate.file)).normalize(); + + util::note(fmt!("compiling %s", path.to_str())); + + success = util::compile_crate(Some(sysroot), path, &work_dir, + crate.flags, crate.cfgs, + false, test); + + if !success { break; } + } + + if !success { + os::set_exit_status(101); + } + + success +} diff --git a/src/librustpkg/usage.rs b/src/librustpkg/usage.rs new file mode 100644 index 0000000000000..cfda56f777ab2 --- /dev/null +++ b/src/librustpkg/usage.rs @@ -0,0 +1,121 @@ +// 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. + +use core::io; + +pub fn general() { + io::println(~"Usage: rustpkg [options] [args..] + +Where is one of: + build, clean, do, info, install, prefer, test, uninstall, unprefer + +Options: + + -h, --help Display this message + -h, --help Display help for "); +} + +pub fn build() { + io::println(~"rustpkg [options..] build + +Build all targets described in the package script in the current +directory. + +Options: + -c, --cfg Pass a cfg flag to the package script"); +} + +pub fn clean() { + io::println(~"rustpkg clean + +Remove all build files in the work cache for the package in the current +directory."); +} + +pub fn do_cmd() { + io::println(~"rustpkg do + +Runs a command in the package script. You can listen to a command +by tagging a function with the attribute `#[pkg_do(cmd)]`."); +} + +pub fn info() { + io::println(~"rustpkg [options..] info + +Probe the package script in the current directory for information. + +Options: + -j, --json Output the result as JSON"); +} + +pub fn install() { + io::println(~"rustpkg [options..] install [url] [target] + +Install a package from a URL by Git or cURL (FTP, HTTP, etc.). +If target is provided, Git will checkout the branch or tag before +continuing. If the URL is a TAR file (with or without compression), +extract it before installing. If a URL isn't provided, the package will +be built and installed from the current directory (which is +functionally the same as `rustpkg build` and installing the result). + +Examples: + rustpkg install + rustpkg install git://github.com/mozilla/servo.git + rustpkg install git://github.com/mozilla/servo.git v0.1.2 + rustpkg install http://rust-lang.org/servo-0.1.2.tar.gz + +Options: + -c, --cfg Pass a cfg flag to the package script"); +} + +pub fn uninstall() { + io::println(~"rustpkg uninstall [@version] + +Remove a package by id or name and optionally version. If the package(s) +is/are depended on by another package then they cannot be removed."); +} + +pub fn prefer() { + io::println(~"rustpkg [options..] prefer [@version] + +By default all binaries are given a unique name so that multiple versions can +coexist. The prefer command will symlink the uniquely named binary to +the binary directory under its bare name. If version is not supplied, the +latest version of the package will be preferred. + +Example: + export PATH=$PATH:/home/user/.rustpkg/bin + rustpkg prefer machine@1.2.4 + machine -v + ==> v1.2.4 + rustpkg prefer machine@0.4.6 + machine -v + ==> v0.4.6"); +} + +pub fn unprefer() { + io::println(~"rustpkg [options..] unprefer [@version] + +Remove all symlinks from the store to the binary directory for a package +name and optionally version. If version is not supplied, the latest version +of the package will be unpreferred. See `rustpkg prefer -h` for more +information."); +} + +pub fn test() { + io::println(~"rustpkg [options..] test + +Build all targets described in the package script in the current directory +with the test flag. The test bootstraps will be run afterwards and the output +and exit code will be redirected. + +Options: + -c, --cfg Pass a cfg flag to the package script"); +} diff --git a/src/librustpkg/util.rs b/src/librustpkg/util.rs new file mode 100644 index 0000000000000..64a6d9c50554a --- /dev/null +++ b/src/librustpkg/util.rs @@ -0,0 +1,804 @@ +// 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. + +use core::*; +use hashmap::linear::LinearMap; +use rustc::metadata::filesearch; +use rustc::driver::{driver, session}; +use syntax::ast_util::*; +use syntax::{ast, attr, codemap, diagnostic, fold, parse, visit}; +use codemap::{span, dummy_sp, spanned}; +use std::semver; +use std::{json, term, sort, getopts}; +use getopts::groups::getopts; +use Listener; + +use syntax::ext::base::{mk_ctxt, ext_ctxt}; +use syntax::ext::build; + +pub struct Package { + id: ~str, + vers: semver::Version, + bins: ~[~str], + libs: ~[~str], +} + +pub fn root() -> Path { + match filesearch::get_rustpkg_root() { + result::Ok(path) => path, + result::Err(err) => fail!(err) + } +} + +pub fn is_cmd(cmd: ~str) -> bool { + let cmds = &[~"build", ~"clean", ~"do", ~"info", ~"install", ~"prefer", + ~"test", ~"uninstall", ~"unprefer"]; + + vec::contains(cmds, &cmd) +} + +pub fn parse_name(id: ~str) -> result::Result<~str, ~str> { + let parts = str::split_char(id, '.'); + + for parts.each |&part| { + for str::chars(part).each |&char| { + if char::is_whitespace(char) { + return result::Err( + ~"could not parse id: contains whitespace"); + } else if char::is_uppercase(char) { + return result::Err( + ~"could not parse id: should be all lowercase"); + } + } + } + + result::Ok(parts.last()) +} + +struct ListenerFn { + cmds: ~[~str], + span: codemap::span, + path: ~[ast::ident] +} + +struct ReadyCtx { + sess: session::Session, + crate: @ast::crate, + ext_cx: ext_ctxt, + path: ~[ast::ident], + fns: ~[ListenerFn] +} + +fn fold_mod(_ctx: @mut ReadyCtx, m: ast::_mod, + fold: fold::ast_fold) -> ast::_mod { + fn strip_main(item: @ast::item) -> @ast::item { + @ast::item { + attrs: do item.attrs.filtered |attr| { + *attr::get_attr_name(attr) != ~"main" + }, + .. copy *item + } + } + + fold::noop_fold_mod(ast::_mod { + items: do vec::map(m.items) |item| { + strip_main(*item) + }, + .. m + }, fold) +} + +fn fold_item(ctx: @mut ReadyCtx, item: @ast::item, + fold: fold::ast_fold) -> Option<@ast::item> { + + ctx.path.push(item.ident); + + let attrs = attr::find_attrs_by_name(item.attrs, ~"pkg_do"); + + if attrs.len() > 0 { + let mut cmds = ~[]; + + for attrs.each |attr| { + match attr.node.value.node { + ast::meta_list(_, mis) => { + for mis.each |mi| { + match mi.node { + ast::meta_word(cmd) => cmds.push(copy *cmd), + _ => {} + }; + } + } + _ => cmds.push(~"build") + }; + } + + ctx.fns.push(ListenerFn { + cmds: cmds, + span: item.span, + path: /*bad*/copy ctx.path + }); + } + + let res = fold::noop_fold_item(item, fold); + + ctx.path.pop(); + + res +} + +fn add_pkg_module(ctx: @mut ReadyCtx, m: ast::_mod) -> ast::_mod { + let listeners = mk_listener_vec(ctx); + let ext_cx = ctx.ext_cx; + let item = quote_item! ( + mod __pkg { + extern mod rustpkg (vers="0.6"); + const listeners : &[rustpkg::Listener] = $listeners; + #[main] + fn main() { + rustpkg::run(listeners); + } + } + ); + ast::_mod { + items: vec::append_one(/*bad*/copy m.items, item.get()), + .. m + } +} + +fn mk_listener_vec(ctx: @mut ReadyCtx) -> @ast::expr { + let fns = ctx.fns; + let descs = do fns.map |listener| { + mk_listener_rec(ctx, *listener) + }; + let ext_cx = ctx.ext_cx; + build::mk_slice_vec_e(ext_cx, dummy_sp(), descs) +} + +fn mk_listener_rec(ctx: @mut ReadyCtx, listener: ListenerFn) -> @ast::expr { + let span = listener.span; + let cmds = do listener.cmds.map |&cmd| { + let ext_cx = ctx.ext_cx; + build::mk_base_str(ext_cx, span, cmd) + }; + + let ext_cx = ctx.ext_cx; + let cmds_expr = build::mk_slice_vec_e(ext_cx, span, cmds); + let cb_expr = build::mk_path(ext_cx, span, copy listener.path); + + quote_expr!( + Listener { + cmds: $cmds_expr, + cb: $cb_expr + } + ) +} + +/// Generate/filter main function, add the list of commands, etc. +pub fn ready_crate(sess: session::Session, + crate: @ast::crate) -> @ast::crate { + let ctx = @mut ReadyCtx { + sess: sess, + crate: crate, + ext_cx: mk_ctxt(sess.parse_sess, copy sess.opts.cfg), + path: ~[], + fns: ~[] + }; + let precursor = @fold::AstFoldFns { + // fold_crate: fold::wrap(|a, b| fold_crate(ctx, a, b)), + fold_item: |a, b| fold_item(ctx, a, b), + fold_mod: |a, b| fold_mod(ctx, a, b), + .. *fold::default_ast_fold() + }; + + let fold = fold::make_fold(precursor); + + @fold.fold_crate(*crate) +} + +pub fn parse_vers(vers: ~str) -> result::Result { + match semver::parse(vers) { + Some(vers) => result::Ok(vers), + None => result::Err(~"could not parse version: invalid") + } +} + +pub fn need_dir(s: &Path) { + if !os::path_is_dir(s) && !os::make_dir(s, 493_i32) { + fail!(fmt!("can't create dir: %s", s.to_str())); + } +} + +pub fn note(msg: ~str) { + let out = io::stdout(); + + if term::color_supported() { + term::fg(out, term::color_green); + out.write_str(~"note: "); + term::reset(out); + out.write_line(msg); + } else { + out.write_line(~"note: " + msg); + } +} + +pub fn warn(msg: ~str) { + let out = io::stdout(); + + if term::color_supported() { + term::fg(out, term::color_yellow); + out.write_str(~"warning: "); + term::reset(out); + out.write_line(msg); + } else { + out.write_line(~"warning: " + msg); + } +} + +pub fn error(msg: ~str) { + let out = io::stdout(); + + if term::color_supported() { + term::fg(out, term::color_red); + out.write_str(~"error: "); + term::reset(out); + out.write_line(msg); + } else { + out.write_line(~"error: " + msg); + } +} + +pub fn hash(data: ~str) -> ~str { + let hasher = hash::default_state(); + + hasher.write_str(data); + hasher.result_str() +} + +pub fn temp_change_dir(dir: &Path, cb: fn() -> T) { + let cwd = os::getcwd(); + + os::change_dir(dir); + cb(); + os::change_dir(&cwd); +} + +pub fn touch(path: &Path) { + match io::mk_file_writer(path, ~[io::Create]) { + result::Ok(writer) => writer.write_line(~""), + _ => {} + } +} + +pub fn remove_dir_r(path: &Path) { + for os::walk_dir(path) |&file| { + let mut cdir = file; + + loop { + if os::path_is_dir(&cdir) { + os::remove_dir(&cdir); + } else { + os::remove_file(&cdir); + } + + cdir = cdir.dir_path(); + + if cdir == *path { break; } + } + } + + os::remove_dir(path); +} + +pub fn wait_for_lock(path: &Path) { + if os::path_exists(path) { + warn(fmt!("the database appears locked, please wait (or rm %s)", + path.to_str())); + + loop { + if !os::path_exists(path) { break; } + } + } +} + +fn _add_pkg(packages: ~[json::Json], pkg: &Package) -> ~[json::Json] { + for packages.each |&package| { + match &package { + &json::Object(ref map) => { + let mut has_id = false; + + match map.get(&~"id") { + &json::String(ref str) => { + if pkg.id == *str { + has_id = true; + } + } + _ => {} + } + + match map.get(&~"vers") { + &json::String(ref str) => { + if has_id && pkg.vers.to_str() == *str { + return copy packages; + } + } + _ => {} + } + } + _ => {} + } + } + + let mut map = ~LinearMap::new(); + + map.insert(~"id", json::String(pkg.id)); + map.insert(~"vers", json::String(pkg.vers.to_str())); + map.insert(~"bins", json::List(do pkg.bins.map |&bin| { + json::String(bin) + })); + map.insert(~"libs", json::List(do pkg.libs.map |&lib| { + json::String(lib) + })); + + vec::append(packages, ~[json::Object(map)]) +} + +fn _rm_pkg(packages: ~[json::Json], pkg: &Package) -> ~[json::Json] { + do packages.filter_mapped |&package| { + match &package { + &json::Object(ref map) => { + let mut has_id = false; + + match map.get(&~"id") { + &json::String(str) => { + if pkg.id == str { + has_id = true; + } + } + _ => {} + } + + match map.get(&~"vers") { + &json::String(ref str) => { + if has_id && pkg.vers.to_str() == *str { + None + } else { + Some(copy package) + } + } + _ => { Some(copy package) } + } + } + _ => { Some(copy package) } + } + } +} + +pub fn load_pkgs() -> result::Result<~[json::Json], ~str> { + let root = root(); + let db = root.push(~"db.json"); + let db_lock = root.push(~"db.json.lck"); + + wait_for_lock(&db_lock); + touch(&db_lock); + + let packages = if os::path_exists(&db) { + match io::read_whole_file_str(&db) { + result::Ok(str) => { + match json::from_str(str) { + result::Ok(json) => { + match json { + json::List(list) => list, + _ => { + os::remove_file(&db_lock); + + return result::Err( + ~"package db's json is not a list"); + } + } + } + result::Err(err) => { + os::remove_file(&db_lock); + + return result::Err( + fmt!("failed to parse package db: %s", + err.to_str())); + } + } + } + result::Err(err) => { + os::remove_file(&db_lock); + + return result::Err(fmt!("failed to read package db: %s", + err)); + } + } + } else { ~[] }; + + os::remove_file(&db_lock); + + result::Ok(packages) +} + +pub fn get_pkg(id: ~str, + vers: Option<~str>) -> result::Result { + let name = match parse_name(id) { + result::Ok(name) => name, + result::Err(err) => return result::Err(err) + }; + let packages = match load_pkgs() { + result::Ok(packages) => packages, + result::Err(err) => return result::Err(err) + }; + let mut sel = None; + let mut possibs = ~[]; + let mut err = None; + + for packages.each |&package| { + match package { + json::Object(map) => { + let pid = match map.get(&~"id") { + &json::String(str) => str, + _ => loop + }; + let pname = match parse_name(pid) { + result::Ok(pname) => pname, + result::Err(perr) => { + err = Some(perr); + + break; + } + }; + let pvers = match map.get(&~"vers") { + &json::String(str) => str, + _ => loop + }; + if pid == id || pname == name { + let bins = match map.get(&~"bins") { + &json::List(ref list) => { + do list.map |&bin| { + match bin { + json::String(str) => str, + _ => ~"" + } + } + } + _ => ~[] + }; + let libs = match map.get(&~"libs") { + &json::List(ref list) => { + do list.map |&lib| { + match lib { + json::String(str) => str, + _ => ~"" + } + } + } + _ => ~[] + }; + let package = Package { + id: pid, + vers: match parse_vers(pvers) { + result::Ok(vers) => vers, + result::Err(verr) => { + err = Some(verr); + + break; + } + }, + bins: bins, + libs: libs + }; + + if !vers.is_none() && vers.get() == pvers { + sel = Some(package); + } + else { + possibs.push(package); + } + } + } + _ => {} + } + } + + if !err.is_none() { + return result::Err(err.get()); + } + if !sel.is_none() { + return result::Ok(sel.get()); + } + if !vers.is_none() || possibs.len() < 1 { + return result::Err(~"package not found"); + } + + result::Ok(sort::merge_sort(possibs, |v1, v2| { + v1.vers <= v2.vers + }).last()) +} + +pub fn add_pkg(pkg: &Package) -> bool { + let root = root(); + let db = root.push(~"db.json"); + let db_lock = root.push(~"db.json.lck"); + let packages = match load_pkgs() { + result::Ok(packages) => packages, + result::Err(err) => { + error(err); + + return false; + } + }; + + wait_for_lock(&db_lock); + touch(&db_lock); + os::remove_file(&db); + + match io::mk_file_writer(&db, ~[io::Create]) { + result::Ok(writer) => { + writer.write_line(json::to_pretty_str(&json::List( + _add_pkg(packages, pkg)))); + } + result::Err(err) => { + error(fmt!("failed to dump package db: %s", err)); + os::remove_file(&db_lock); + + return false; + } + } + + os::remove_file(&db_lock); + + true +} + +pub fn remove_pkg(pkg: &Package) -> bool { + let root = root(); + let db = root.push(~"db.json"); + let db_lock = root.push(~"db.json.lck"); + let packages = match load_pkgs() { + result::Ok(packages) => packages, + result::Err(err) => { + error(err); + + return false; + } + }; + + wait_for_lock(&db_lock); + touch(&db_lock); + os::remove_file(&db); + + match io::mk_file_writer(&db, ~[io::Create]) { + result::Ok(writer) => { + writer.write_line(json::to_pretty_str(&json::List( + _rm_pkg(packages, pkg)))); + } + result::Err(err) => { + error(fmt!("failed to dump package db: %s", err)); + os::remove_file(&db_lock); + + return false; + } + } + + os::remove_file(&db_lock); + + true +} + +pub fn compile_input(sysroot: Option, input: driver::input, dir: &Path, + flags: ~[~str], cfgs: ~[~str], opt: bool, test: bool) -> bool { + let lib_dir = dir.push(~"lib"); + let bin_dir = dir.push(~"bin"); + let test_dir = dir.push(~"test"); + let binary = os::args()[0]; + let matches = getopts(flags, driver::optgroups()).get(); + let options = @session::options { + crate_type: session::unknown_crate, + optimize: if opt { session::Aggressive } else { session::No }, + test: test, + maybe_sysroot: sysroot, + .. *driver::build_session_options(binary, &matches, diagnostic::emit) + }; + let mut crate_cfg = options.cfg; + + for cfgs.each |&cfg| { + crate_cfg.push(attr::mk_word_item(@cfg)); + } + + let options = @session::options { + cfg: vec::append(options.cfg, crate_cfg), + .. *options + }; + let sess = driver::build_session(options, diagnostic::emit); + let cfg = driver::build_configuration(sess, binary, input); + let mut outputs = driver::build_output_filenames(input, &None, &None, + sess); + let (crate, _) = driver::compile_upto(sess, cfg, input, driver::cu_parse, + Some(outputs)); + + let mut name = None; + let mut vers = None; + let mut uuid = None; + let mut crate_type = None; + + fn load_link_attr(mis: ~[@ast::meta_item]) -> (Option<~str>, + Option<~str>, + Option<~str>) { + let mut name = None; + let mut vers = None; + let mut uuid = None; + + for mis.each |a| { + match a.node { + ast::meta_name_value(v, spanned {node: ast::lit_str(s), + span: _}) => { + match *v { + ~"name" => name = Some(*s), + ~"vers" => vers = Some(*s), + ~"uuid" => uuid = Some(*s), + _ => { } + } + } + _ => {} + } + } + + (name, vers, uuid) + } + + for crate.node.attrs.each |a| { + match a.node.value.node { + ast::meta_name_value(v, spanned {node: ast::lit_str(s), + span: _}) => { + match *v { + ~"crate_type" => crate_type = Some(*s), + _ => {} + } + } + ast::meta_list(v, mis) => { + match *v { + ~"link" => { + let (n, v, u) = load_link_attr(mis); + + name = n; + vers = v; + uuid = u; + } + _ => {} + } + } + _ => {} + } + } + + if name.is_none() || vers.is_none() || uuid.is_none() { + error(~"link attr without (name, vers, uuid) values"); + + return false; + } + + let name = name.get(); + let vers = vers.get(); + let uuid = uuid.get(); + + let is_bin = match crate_type { + Some(crate_type) => { + match crate_type { + ~"bin" => true, + ~"lib" => false, + _ => { + warn(~"unknown crate_type, falling back to lib"); + + false + } + } + } + None => { + warn(~"missing crate_type attr, assuming lib"); + + false + } + }; + + if test { + need_dir(&test_dir); + + outputs = driver::build_output_filenames(input, &Some(test_dir), + &None, sess) + } + else if is_bin { + need_dir(&bin_dir); + + let path = bin_dir.push(fmt!("%s-%s-%s%s", name, + hash(name + uuid + vers), + vers, exe_suffix())); + outputs = driver::build_output_filenames(input, &None, &Some(path), + sess); + } else { + need_dir(&lib_dir); + + outputs = driver::build_output_filenames(input, &Some(lib_dir), + &None, sess) + } + + driver::compile_rest(sess, cfg, driver::cu_everything, + Some(outputs), Some(crate)); + + true +} + +#[cfg(windows)] +pub fn exe_suffix() -> ~str { ~".exe" } + +#[cfg(target_os = "linux")] +#[cfg(target_os = "android")] +#[cfg(target_os = "freebsd")] +#[cfg(target_os = "macos")] +pub fn exe_suffix() -> ~str { ~"" } + + +// FIXME (#4432): Use workcache to only compile when needed +pub fn compile_crate(sysroot: Option, crate: &Path, dir: &Path, + flags: ~[~str], cfgs: ~[~str], opt: bool, + test: bool) -> bool { + compile_input(sysroot, driver::file_input(*crate), dir, flags, cfgs, + opt, test) +} + +pub fn compile_str(sysroot: Option, code: ~str, dir: &Path, + flags: ~[~str], cfgs: ~[~str], opt: bool, + test: bool) -> bool { + compile_input(sysroot, driver::str_input(code), dir, flags, cfgs, + opt, test) +} + +#[cfg(windows)] +pub fn link_exe(_src: &Path, _dest: &Path) -> bool { + /* FIXME (#1768): Investigate how to do this on win32 + Node wraps symlinks by having a .bat, + but that won't work with minGW. */ + + false +} + +#[cfg(target_os = "linux")] +#[cfg(target_os = "android")] +#[cfg(target_os = "freebsd")] +#[cfg(target_os = "macos")] +pub fn link_exe(src: &Path, dest: &Path) -> bool { + unsafe { + do str::as_c_str(src.to_str()) |src_buf| { + do str::as_c_str(dest.to_str()) |dest_buf| { + libc::link(src_buf, dest_buf) == 0 as libc::c_int && + libc::chmod(dest_buf, 755) == 0 as libc::c_int + } + } + } +} + +#[test] +fn test_is_cmd() { + assert is_cmd(~"build"); + assert is_cmd(~"clean"); + assert is_cmd(~"do"); + assert is_cmd(~"info"); + assert is_cmd(~"install"); + assert is_cmd(~"prefer"); + assert is_cmd(~"test"); + assert is_cmd(~"uninstall"); + assert is_cmd(~"unprefer"); +} + +#[test] +fn test_parse_name() { + assert parse_name(~"org.mozilla.servo").get() == ~"servo"; + assert parse_name(~"org. mozilla.servo 2131").is_err(); +} diff --git a/src/libstd/arc.rs b/src/libstd/arc.rs index 59e278f17960f..61b5ffd845f89 100644 --- a/src/libstd/arc.rs +++ b/src/libstd/arc.rs @@ -80,15 +80,15 @@ impl &Condvar { struct ARC { x: SharedMutableState } /// Create an atomically reference counted wrapper. -pub fn ARC(data: T) -> ARC { - ARC { x: unsafe { shared_mutable_state(move data) } } +pub fn ARC(data: T) -> ARC { + ARC { x: unsafe { shared_mutable_state(data) } } } /** * Access the underlying data in an atomically reference counted * wrapper. */ -pub fn get(rc: &a/ARC) -> &a/T { +pub fn get(rc: &a/ARC) -> &a/T { unsafe { get_shared_immutable_state(&rc.x) } } @@ -99,7 +99,7 @@ pub fn get(rc: &a/ARC) -> &a/T { * object. However, one of the `arc` objects can be sent to another task, * allowing them to share the underlying data. */ -pub fn clone(rc: &ARC) -> ARC { +pub fn clone(rc: &ARC) -> ARC { ARC { x: unsafe { clone_shared_mutable_state(&rc.x) } } } @@ -112,12 +112,12 @@ pub fn clone(rc: &ARC) -> ARC { * unwrap from a task that holds another reference to the same ARC; it is * guaranteed to deadlock. */ -pub fn unwrap(rc: ARC) -> T { - let ARC { x: x } = move rc; - unsafe { unwrap_shared_mutable_state(move x) } +pub fn unwrap(rc: ARC) -> T { + let ARC { x: x } = rc; + unsafe { unwrap_shared_mutable_state(x) } } -impl Clone for ARC { +impl Clone for ARC { fn clone(&self) -> ARC { clone(self) } @@ -133,22 +133,22 @@ struct MutexARCInner { lock: Mutex, failed: bool, data: T } struct MutexARC { x: SharedMutableState> } /// Create a mutex-protected ARC with the supplied data. -pub fn MutexARC(user_data: T) -> MutexARC { - mutex_arc_with_condvars(move user_data, 1) +pub fn MutexARC(user_data: T) -> MutexARC { + mutex_arc_with_condvars(user_data, 1) } /** * Create a mutex-protected ARC with the supplied data and a specified number * of condvars (as sync::mutex_with_condvars). */ -pub fn mutex_arc_with_condvars(user_data: T, +pub fn mutex_arc_with_condvars(user_data: T, num_condvars: uint) -> MutexARC { let data = MutexARCInner { lock: mutex_with_condvars(num_condvars), - failed: false, data: move user_data }; - MutexARC { x: unsafe { shared_mutable_state(move data) } } + failed: false, data: user_data }; + MutexARC { x: unsafe { shared_mutable_state(data) } } } -impl Clone for MutexARC { +impl Clone for MutexARC { /// Duplicate a mutex-protected ARC, as arc::clone. fn clone(&self) -> MutexARC { // NB: Cloning the underlying mutex is not necessary. Its reference @@ -157,7 +157,7 @@ impl Clone for MutexARC { } } -impl &MutexARC { +impl &MutexARC { /** * Access the underlying mutable data with mutual exclusion from other @@ -219,14 +219,14 @@ impl &MutexARC { * Will additionally fail if another task has failed while accessing the arc. */ // FIXME(#3724) make this a by-move method on the arc -pub fn unwrap_mutex_arc(arc: MutexARC) -> T { - let MutexARC { x: x } = move arc; - let inner = unsafe { unwrap_shared_mutable_state(move x) }; - let MutexARCInner { failed: failed, data: data, _ } = move inner; +pub fn unwrap_mutex_arc(arc: MutexARC) -> T { + let MutexARC { x: x } = arc; + let inner = unsafe { unwrap_shared_mutable_state(x) }; + let MutexARCInner { failed: failed, data: data, _ } = inner; if failed { fail!(~"Can't unwrap poisoned MutexARC - another task failed inside!") } - move data + data } // Common code for {mutex.access,rwlock.write}{,_cond}. @@ -283,24 +283,24 @@ struct RWARC { } /// Create a reader/writer ARC with the supplied data. -pub fn RWARC(user_data: T) -> RWARC { - rw_arc_with_condvars(move user_data, 1) +pub fn RWARC(user_data: T) -> RWARC { + rw_arc_with_condvars(user_data, 1) } /** * Create a reader/writer ARC with the supplied data and a specified number * of condvars (as sync::rwlock_with_condvars). */ -pub fn rw_arc_with_condvars( +pub fn rw_arc_with_condvars( user_data: T, num_condvars: uint) -> RWARC { let data = RWARCInner { lock: rwlock_with_condvars(num_condvars), - failed: false, data: move user_data }; - RWARC { x: unsafe { shared_mutable_state(move data) }, cant_nest: () } + failed: false, data: user_data }; + RWARC { x: unsafe { shared_mutable_state(data) }, cant_nest: () } } -impl RWARC { +impl RWARC { /// Duplicate a rwlock-protected ARC, as arc::clone. fn clone(&self) -> RWARC { RWARC { x: unsafe { clone_shared_mutable_state(&self.x) }, @@ -309,7 +309,7 @@ impl RWARC { } -impl &RWARC { +impl &RWARC { /** * Access the underlying data mutably. Locks the rwlock in write mode; * other readers and writers will block. @@ -386,7 +386,7 @@ impl &RWARC { do (*borrow_rwlock(state)).write_downgrade |write_mode| { check_poison(false, (*state).failed); blk(RWWriteMode((&mut (*state).data, - move write_mode, + write_mode, PoisonOnFail(&mut (*state).failed)))) } } @@ -396,9 +396,9 @@ impl &RWARC { fn downgrade(token: RWWriteMode/&a) -> RWReadMode/&a { // The rwlock should assert that the token belongs to us for us. let state = unsafe { get_shared_immutable_state(&self.x) }; - let RWWriteMode((data, t, _poison)) = move token; + let RWWriteMode((data, t, _poison)) = token; // Let readers in - let new_token = (&state.lock).downgrade(move t); + let new_token = (&state.lock).downgrade(t); // Whatever region the input reference had, it will be safe to use // the same region for the output reference. (The only 'unsafe' part // of this cast is removing the mutability.) @@ -406,7 +406,7 @@ impl &RWARC { // Downgrade ensured the token belonged to us. Just a sanity check. assert ptr::ref_eq(&state.data, new_data); // Produce new token - RWReadMode((new_data, move new_token)) + RWReadMode((new_data, new_token)) } } @@ -418,21 +418,21 @@ impl &RWARC { * in write mode. */ // FIXME(#3724) make this a by-move method on the arc -pub fn unwrap_rw_arc(arc: RWARC) -> T { - let RWARC { x: x, _ } = move arc; - let inner = unsafe { unwrap_shared_mutable_state(move x) }; - let RWARCInner { failed: failed, data: data, _ } = move inner; +pub fn unwrap_rw_arc(arc: RWARC) -> T { + let RWARC { x: x, _ } = arc; + let inner = unsafe { unwrap_shared_mutable_state(x) }; + let RWARCInner { failed: failed, data: data, _ } = inner; if failed { fail!(~"Can't unwrap poisoned RWARC - another task failed inside!") } - move data + data } // Borrowck rightly complains about immutably aliasing the rwlock in order to // lock it. This wraps the unsafety, with the justification that the 'lock' // field is never overwritten; only 'failed' and 'data'. #[doc(hidden)] -fn borrow_rwlock(state: *const RWARCInner) -> *RWlock { +fn borrow_rwlock(state: *const RWARCInner) -> *RWlock { unsafe { cast::transmute(&const (*state).lock) } } @@ -444,7 +444,7 @@ pub enum RWWriteMode = /// The "read permission" token used for RWARC.write_downgrade(). pub enum RWReadMode = (&T, sync::RWlockReadMode); -impl &RWWriteMode { +impl &RWWriteMode { /// Access the pre-downgrade RWARC in write mode. fn write(blk: fn(x: &mut T) -> U) -> U { match *self { @@ -474,7 +474,7 @@ impl &RWWriteMode { } } -impl &RWReadMode { +impl &RWReadMode { /// Access the post-downgrade rwlock in read mode. fn read(blk: fn(x: &T) -> U) -> U { match *self { @@ -507,10 +507,10 @@ mod tests { let v = ~[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; let arc_v = arc::ARC(v); - let (p, c) = pipes::stream(); + let (p, c) = comm::stream(); - do task::spawn() |move c| { - let p = pipes::PortSet(); + do task::spawn() || { + let p = comm::PortSet(); c.send(p.chan()); let arc_v = p.recv(); @@ -531,18 +531,18 @@ mod tests { pub fn test_mutex_arc_condvar() { let arc = ~MutexARC(false); let arc2 = ~arc.clone(); - let (p,c) = pipes::oneshot(); - let (c,p) = (~mut Some(move c), ~mut Some(move p)); - do task::spawn |move arc2, move p| { + let (p,c) = comm::oneshot(); + let (c,p) = (~mut Some(c), ~mut Some(p)); + do task::spawn || { // wait until parent gets in - pipes::recv_one(option::swap_unwrap(p)); + comm::recv_one(option::swap_unwrap(p)); do arc2.access_cond |state, cond| { *state = true; cond.signal(); } } do arc.access_cond |state, cond| { - pipes::send_one(option::swap_unwrap(c), ()); + comm::send_one(option::swap_unwrap(c), ()); assert !*state; while !*state { cond.wait(); @@ -553,9 +553,9 @@ mod tests { pub fn test_arc_condvar_poison() { let arc = ~MutexARC(1); let arc2 = ~arc.clone(); - let (p, c) = pipes::stream(); + let (p, c) = comm::stream(); - do task::spawn_unlinked |move arc2, move p| { + do task::spawn_unlinked || { let _ = p.recv(); do arc2.access_cond |one, cond| { cond.signal(); @@ -574,7 +574,7 @@ mod tests { pub fn test_mutex_arc_poison() { let arc = ~MutexARC(1); let arc2 = ~arc.clone(); - do task::try |move arc2| { + do task::try || { do arc2.access |one| { assert *one == 2; } @@ -587,22 +587,22 @@ mod tests { pub fn test_mutex_arc_unwrap_poison() { let arc = MutexARC(1); let arc2 = ~(&arc).clone(); - let (p, c) = pipes::stream(); - do task::spawn |move c, move arc2| { + let (p, c) = comm::stream(); + do task::spawn || { do arc2.access |one| { c.send(()); assert *one == 2; } } let _ = p.recv(); - let one = unwrap_mutex_arc(move arc); + let one = unwrap_mutex_arc(arc); assert one == 1; } #[test] #[should_fail] #[ignore(cfg(windows))] pub fn test_rw_arc_poison_wr() { let arc = ~RWARC(1); let arc2 = ~arc.clone(); - do task::try |move arc2| { + do task::try || { do arc2.write |one| { assert *one == 2; } @@ -615,7 +615,7 @@ mod tests { pub fn test_rw_arc_poison_ww() { let arc = ~RWARC(1); let arc2 = ~arc.clone(); - do task::try |move arc2| { + do task::try || { do arc2.write |one| { assert *one == 2; } @@ -628,7 +628,7 @@ mod tests { pub fn test_rw_arc_poison_dw() { let arc = ~RWARC(1); let arc2 = ~arc.clone(); - do task::try |move arc2| { + do task::try || { do arc2.write_downgrade |write_mode| { do (&write_mode).write |one| { assert *one == 2; @@ -643,7 +643,7 @@ mod tests { pub fn test_rw_arc_no_poison_rr() { let arc = ~RWARC(1); let arc2 = ~arc.clone(); - do task::try |move arc2| { + do task::try || { do arc2.read |one| { assert *one == 2; } @@ -656,7 +656,7 @@ mod tests { pub fn test_rw_arc_no_poison_rw() { let arc = ~RWARC(1); let arc2 = ~arc.clone(); - do task::try |move arc2| { + do task::try || { do arc2.read |one| { assert *one == 2; } @@ -669,9 +669,9 @@ mod tests { pub fn test_rw_arc_no_poison_dr() { let arc = ~RWARC(1); let arc2 = ~arc.clone(); - do task::try |move arc2| { + do task::try || { do arc2.write_downgrade |write_mode| { - let read_mode = arc2.downgrade(move write_mode); + let read_mode = arc2.downgrade(write_mode); do (&read_mode).read |one| { assert *one == 2; } @@ -685,9 +685,9 @@ mod tests { pub fn test_rw_arc() { let arc = ~RWARC(0); let arc2 = ~arc.clone(); - let (p,c) = pipes::stream(); + let (p,c) = comm::stream(); - do task::spawn |move arc2, move c| { + do task::spawn || { do arc2.write |num| { for 10.times { let tmp = *num; @@ -703,8 +703,8 @@ mod tests { let mut children = ~[]; for 5.times { let arc3 = ~arc.clone(); - do task::task().future_result(|+r| children.push(move r)).spawn - |move arc3| { + do task::task().future_result(|+r| children.push(r)).spawn + || { do arc3.read |num| { assert *num >= 0; } @@ -731,10 +731,10 @@ mod tests { // Reader tasks let mut reader_convos = ~[]; for 10.times { - let ((rp1,rc1),(rp2,rc2)) = (pipes::stream(),pipes::stream()); - reader_convos.push((move rc1, move rp2)); + let ((rp1,rc1),(rp2,rc2)) = (comm::stream(),comm::stream()); + reader_convos.push((rc1, rp2)); let arcn = ~arc.clone(); - do task::spawn |move rp1, move rc2, move arcn| { + do task::spawn || { rp1.recv(); // wait for downgrader to give go-ahead do arcn.read |state| { assert *state == 31337; @@ -745,8 +745,8 @@ mod tests { // Writer task let arc2 = ~arc.clone(); - let ((wp1,wc1),(wp2,wc2)) = (pipes::stream(),pipes::stream()); - do task::spawn |move arc2, move wc2, move wp1| { + let ((wp1,wc1),(wp2,wc2)) = (comm::stream(),comm::stream()); + do task::spawn || { wp1.recv(); do arc2.write_cond |state, cond| { assert *state == 0; @@ -779,7 +779,7 @@ mod tests { } } } - let read_mode = arc.downgrade(move write_mode); + let read_mode = arc.downgrade(write_mode); do (&read_mode).read |state| { // complete handshake with other readers for vec::each(reader_convos) |x| { diff --git a/src/libstd/bigint.rs b/src/libstd/bigint.rs index ab622438511bb..23a4769775c00 100644 --- a/src/libstd/bigint.rs +++ b/src/libstd/bigint.rs @@ -216,8 +216,9 @@ impl Mul for BigUint { pure fn cut_at(a: &BigUint, n: uint) -> (BigUint, BigUint) { let mid = uint::min(a.data.len(), n); - return (BigUint::from_slice(vec::view(a.data, mid, a.data.len())), - BigUint::from_slice(vec::view(a.data, 0, mid))); + 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) { @@ -301,7 +302,7 @@ pub impl BigUint { let mut power: BigUint = One::one(); loop { let start = uint::max(end, unit_len) - unit_len; - match uint::parse_bytes(vec::view(buf, start, end), radix) { + match uint::parse_bytes(vec::slice(buf, start, end), radix) { Some(d) => n += BigUint::from_uint(d) * power, None => return None } @@ -380,7 +381,7 @@ pub impl BigUint { return (Zero::zero(), Zero::zero(), copy *a); } - let an = vec::view(a.data, a.data.len() - n, a.data.len()); + let an = vec::slice(a.data, a.data.len() - n, a.data.len()); let bn = b.data.last(); let mut d = ~[]; let mut carry = 0; @@ -487,7 +488,7 @@ pub impl BigUint { if n_unit == 0 { return self; } if self.data.len() < n_unit { return Zero::zero(); } return BigUint::from_slice( - vec::view(self.data, n_unit, self.data.len()) + vec::slice(self.data, n_unit, self.data.len()) ); } @@ -770,7 +771,7 @@ pub impl BigInt { sign = Minus; start = 1; } - return BigUint::parse_bytes(vec::view(buf, start, buf.len()), radix) + return BigUint::parse_bytes(vec::slice(buf, start, buf.len()), radix) .map(|bu| BigInt::from_biguint(sign, *bu)); } @@ -885,7 +886,7 @@ mod biguint_tests { let data = [ &[], &[1], &[2], &[-1], &[0, 1], &[2, 1], &[1, 1, 1] ] .map(|v| BigUint::from_slice(*v)); for data.eachi |i, ni| { - for vec::view(data, i, data.len()).eachi |j0, nj| { + for vec::slice(data, i, data.len()).eachi |j0, nj| { let j = j0 + i; if i == j { assert ni.cmp(nj) == 0; @@ -1298,7 +1299,7 @@ mod bigint_tests { nums.push_all_move(vs.map(|s| BigInt::from_slice(Plus, *s))); for nums.eachi |i, ni| { - for vec::view(nums, i, nums.len()).eachi |j0, nj| { + for vec::slice(nums, i, nums.len()).eachi |j0, nj| { let j = i + j0; if i == j { assert ni.cmp(nj) == 0; diff --git a/src/libstd/bitv.rs b/src/libstd/bitv.rs index e6557d163f9db..30d7b825add4a 100644 --- a/src/libstd/bitv.rs +++ b/src/libstd/bitv.rs @@ -8,107 +8,104 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +use core::container::{Container, Mutable, Set}; +use core::num::NumCast; use core::ops; use core::prelude::*; use core::uint; -use core::vec::{cast_to_mut, from_elem}; +use core::vec::from_elem; use core::vec; struct SmallBitv { /// only the lowest nbits of this value are used. the rest is undefined. - mut bits: u32 -} - -fn SmallBitv(bits: u32) -> SmallBitv { - SmallBitv {bits: bits} + bits: uint } /// a mask that has a 1 for each defined bit in a small_bitv, assuming n bits #[inline(always)] -fn small_mask(nbits: uint) -> u32 { +fn small_mask(nbits: uint) -> uint { (1 << nbits) - 1 } impl SmallBitv { + static fn new(bits: uint) -> SmallBitv { + SmallBitv {bits: bits} + } #[inline(always)] - fn bits_op(right_bits: u32, nbits: uint, f: fn(u32, u32) -> u32) -> bool { + fn bits_op(&mut self, right_bits: uint, nbits: uint, + f: fn(uint, uint) -> uint) -> bool { let mask = small_mask(nbits); - let old_b: u32 = self.bits; + let old_b: uint = self.bits; let new_b = f(old_b, right_bits); self.bits = new_b; mask & old_b != mask & new_b } #[inline(always)] - fn union(s: &SmallBitv, nbits: uint) -> bool { + fn union(&mut self, s: &SmallBitv, nbits: uint) -> bool { self.bits_op(s.bits, nbits, |u1, u2| u1 | u2) } #[inline(always)] - fn intersect(s: &SmallBitv, nbits: uint) -> bool { + fn intersect(&mut self, s: &SmallBitv, nbits: uint) -> bool { self.bits_op(s.bits, nbits, |u1, u2| u1 & u2) } #[inline(always)] - fn become(s: &SmallBitv, nbits: uint) -> bool { + fn become(&mut self, s: &SmallBitv, nbits: uint) -> bool { self.bits_op(s.bits, nbits, |_u1, u2| u2) } #[inline(always)] - fn difference(s: &SmallBitv, nbits: uint) -> bool { + fn difference(&mut self, s: &SmallBitv, nbits: uint) -> bool { self.bits_op(s.bits, nbits, |u1, u2| u1 & !u2) } #[inline(always)] - pure fn get(i: uint) -> bool { + pure fn get(&self, i: uint) -> bool { (self.bits & (1 << i)) != 0 } #[inline(always)] - fn set(i: uint, x: bool) { + fn set(&mut self, i: uint, x: bool) { if x { self.bits |= 1< bool { + fn equals(&self, b: &SmallBitv, nbits: uint) -> bool { let mask = small_mask(nbits); mask & self.bits == mask & b.bits } #[inline(always)] - fn clear() { self.bits = 0; } + fn clear(&mut self) { self.bits = 0; } #[inline(always)] - fn set_all() { self.bits = !0; } + fn set_all(&mut self) { self.bits = !0; } #[inline(always)] - fn is_true(nbits: uint) -> bool { + fn is_true(&self, nbits: uint) -> bool { small_mask(nbits) & !self.bits == 0 } #[inline(always)] - fn is_false(nbits: uint) -> bool { + fn is_false(&self, nbits: uint) -> bool { small_mask(nbits) & self.bits == 0 } #[inline(always)] - fn invert() { self.bits = !self.bits; } + fn invert(&mut self) { self.bits = !self.bits; } } struct BigBitv { - // only mut b/c of clone and lack of other constructor - mut storage: ~[uint] -} - -fn BigBitv(storage: ~[uint]) -> BigBitv { - BigBitv {storage: move storage} + storage: ~[uint] } /** @@ -117,8 +114,8 @@ fn BigBitv(storage: ~[uint]) -> BigBitv { */ #[inline(always)] fn big_mask(nbits: uint, elem: uint) -> uint { - let rmd = nbits % uint_bits; - let nelems = nbits/uint_bits + if rmd == 0 {0} else {1}; + let rmd = nbits % uint::bits; + let nelems = nbits/uint::bits + if rmd == 0 {0} else {1}; if elem < nelems - 1 || rmd == 0 { !0 @@ -128,30 +125,31 @@ fn big_mask(nbits: uint, elem: uint) -> uint { } impl BigBitv { + static fn new(storage: ~[uint]) -> BigBitv { + BigBitv {storage: storage} + } #[inline(always)] - fn process(b: &BigBitv, nbits: uint, op: fn(uint, uint) -> uint) -> bool { + fn process(&mut self, b: &BigBitv, nbits: uint, + op: fn(uint, uint) -> uint) -> bool { let len = b.storage.len(); assert (self.storage.len() == len); let mut changed = false; - do uint::range(0, len) |i| { + for uint::range(0, len) |i| { let mask = big_mask(nbits, i); let w0 = self.storage[i] & mask; let w1 = b.storage[i] & mask; let w = op(w0, w1) & mask; if w0 != w { - unsafe { - changed = true; - self.storage[i] = w; - } + changed = true; + self.storage[i] = w; } - true } changed } #[inline(always)] - fn each_storage(op: fn(v: &mut uint) -> bool) { + fn each_storage(&mut self, op: fn(v: &mut uint) -> bool) { for uint::range(0, self.storage.len()) |i| { let mut w = self.storage[i]; let b = op(&mut w); @@ -161,47 +159,47 @@ impl BigBitv { } #[inline(always)] - fn invert() { for self.each_storage() |w| { *w = !*w } } + fn invert(&mut self) { for self.each_storage |w| { *w = !*w } } #[inline(always)] - fn union(b: &BigBitv, nbits: uint) -> bool { - self.process(b, nbits, lor) + fn union(&mut self, b: &BigBitv, nbits: uint) -> bool { + self.process(b, nbits, |w1, w2| w1 | w2) } #[inline(always)] - fn intersect(b: &BigBitv, nbits: uint) -> bool { - self.process(b, nbits, land) + fn intersect(&mut self, b: &BigBitv, nbits: uint) -> bool { + self.process(b, nbits, |w1, w2| w1 & w2) } #[inline(always)] - fn become(b: &BigBitv, nbits: uint) -> bool { - self.process(b, nbits, right) + fn become(&mut self, b: &BigBitv, nbits: uint) -> bool { + self.process(b, nbits, |_, w| w) } #[inline(always)] - fn difference(b: &BigBitv, nbits: uint) -> bool { - self.process(b, nbits, difference) + fn difference(&mut self, b: &BigBitv, nbits: uint) -> bool { + self.process(b, nbits, |w1, w2| w1 & !w2) } #[inline(always)] - pure fn get(i: uint) -> bool { - let w = i / uint_bits; - let b = i % uint_bits; + pure fn get(&self, i: uint) -> bool { + let w = i / uint::bits; + let b = i % uint::bits; let x = 1 & self.storage[w] >> b; x == 1 } #[inline(always)] - fn set(i: uint, x: bool) { - let w = i / uint_bits; - let b = i % uint_bits; + fn set(&mut self, i: uint, x: bool) { + let w = i / uint::bits; + let b = i % uint::bits; let flag = 1 << b; self.storage[w] = if x { self.storage[w] | flag } - else { self.storage[w] & !flag }; + else { self.storage[w] & !flag }; } #[inline(always)] - fn equals(b: &BigBitv, nbits: uint) -> bool { + fn equals(&self, b: &BigBitv, nbits: uint) -> bool { let len = b.storage.len(); for uint::iterate(0, len) |i| { let mask = big_mask(nbits, i); @@ -223,33 +221,19 @@ pub struct Bitv { nbits: uint } -pub fn Bitv (nbits: uint, init: bool) -> Bitv { - let rep = if nbits <= 32 { - Small(~SmallBitv(if init {!0} else {0})) - } - else { - let nelems = nbits/uint_bits + - if nbits % uint_bits == 0 {0} else {1}; - let elem = if init {!0} else {0}; - let s = from_elem(nelems, elem); - Big(~BigBitv(move s)) - }; - Bitv {rep: move rep, nbits: nbits} -} - priv impl Bitv { - fn die() -> ! { + fn die(&self) -> ! { fail!(~"Tried to do operation on bit vectors with different sizes"); } #[inline(always)] - fn do_op(op: Op, other: &Bitv) -> bool { + fn do_op(&mut self, op: Op, other: &Bitv) -> bool { if self.nbits != other.nbits { self.die(); } match self.rep { - Small(ref s) => match other.rep { + Small(ref mut s) => match other.rep { Small(ref s1) => match op { Union => s.union(*s1, self.nbits), Intersect => s.intersect(*s1, self.nbits), @@ -258,7 +242,7 @@ priv impl Bitv { }, Big(_) => self.die() }, - Big(ref s) => match other.rep { + Big(ref mut s) => match other.rep { Small(_) => self.die(), Big(ref s1) => match op { Union => s.union(*s1, self.nbits), @@ -273,6 +257,19 @@ priv impl Bitv { } impl Bitv { + static fn new(nbits: uint, init: bool) -> Bitv { + let rep = if nbits <= uint::bits { + Small(~SmallBitv::new(if init {!0} else {0})) + } + else { + let nelems = nbits/uint::bits + + if nbits % uint::bits == 0 {0} else {1}; + let elem = if init {!0} else {0}; + let s = from_elem(nelems, elem); + Big(~BigBitv::new(s)) + }; + Bitv {rep: rep, nbits: nbits} + } /** * Calculates the union of two bitvectors @@ -281,7 +278,7 @@ impl Bitv { * the same length. Returns 'true' if `self` changed. */ #[inline(always)] - fn union(v1: &Bitv) -> bool { self.do_op(Union, v1) } + fn union(&mut self, v1: &Bitv) -> bool { self.do_op(Union, v1) } /** * Calculates the intersection of two bitvectors @@ -290,7 +287,7 @@ impl Bitv { * must be the same length. Returns 'true' if `self` changed. */ #[inline(always)] - fn intersect(v1: &Bitv) -> bool { self.do_op(Intersect, v1) } + fn intersect(&mut self, v1: &Bitv) -> bool { self.do_op(Intersect, v1) } /** * Assigns the value of `v1` to `self` @@ -299,11 +296,11 @@ impl Bitv { * changed */ #[inline(always)] - fn assign(v: &Bitv) -> bool { self.do_op(Assign, v) } + fn assign(&mut self, v: &Bitv) -> bool { self.do_op(Assign, v) } /// Retrieve the value at index `i` #[inline(always)] - pure fn get(i: uint) -> bool { + pure fn get(&self, i: uint) -> bool { assert (i < self.nbits); match self.rep { Big(ref b) => b.get(i), @@ -317,11 +314,11 @@ impl Bitv { * `i` must be less than the length of the bitvector. */ #[inline(always)] - fn set(i: uint, x: bool) { + fn set(&mut self, i: uint, x: bool) { assert (i < self.nbits); match self.rep { - Big(ref b) => b.set(i, x), - Small(ref s) => s.set(i, x) + Big(ref mut b) => b.set(i, x), + Small(ref mut s) => s.set(i, x) } } @@ -332,7 +329,7 @@ impl Bitv { * bitvectors contain identical elements. */ #[inline(always)] - fn equal(v1: &Bitv) -> bool { + fn equal(&self, v1: &Bitv) -> bool { if self.nbits != v1.nbits { return false; } match self.rep { Small(ref b) => match v1.rep { @@ -348,27 +345,27 @@ impl Bitv { /// Set all bits to 0 #[inline(always)] - fn clear() { + fn clear(&mut self) { match self.rep { - Small(ref b) => b.clear(), - Big(ref s) => for s.each_storage() |w| { *w = 0u } + Small(ref mut b) => b.clear(), + Big(ref mut s) => for s.each_storage() |w| { *w = 0u } } } /// Set all bits to 1 #[inline(always)] - fn set_all() { + fn set_all(&mut self) { match self.rep { - Small(ref b) => b.set_all(), - Big(ref s) => for s.each_storage() |w| { *w = !0u } } + Small(ref mut b) => b.set_all(), + Big(ref mut s) => for s.each_storage() |w| { *w = !0u } } } /// Invert all bits #[inline(always)] - fn invert() { + fn invert(&mut self) { match self.rep { - Small(ref b) => b.invert(), - Big(ref s) => for s.each_storage() |w| { *w = !*w } } + Small(ref mut b) => b.invert(), + Big(ref mut s) => for s.each_storage() |w| { *w = !*w } } } /** @@ -381,11 +378,11 @@ impl Bitv { * Returns `true` if `v0` was changed. */ #[inline(always)] - fn difference(v: &Bitv) -> bool { self.do_op(Difference, v) } + fn difference(&mut self, v: &Bitv) -> bool { self.do_op(Difference, v) } /// Returns true if all bits are 1 #[inline(always)] - fn is_true() -> bool { + fn is_true(&self) -> bool { match self.rep { Small(ref b) => b.is_true(self.nbits), _ => { @@ -396,7 +393,7 @@ impl Bitv { } #[inline(always)] - fn each(f: fn(bool) -> bool) { + fn each(&self, f: fn(bool) -> bool) { let mut i = 0; while i < self.nbits { if !f(self.get(i)) { break; } @@ -405,7 +402,7 @@ impl Bitv { } /// Returns true if all bits are 0 - fn is_false() -> bool { + fn is_false(&self) -> bool { match self.rep { Small(ref b) => b.is_false(self.nbits), Big(_) => { @@ -415,7 +412,7 @@ impl Bitv { } } - fn init_to_vec(i: uint) -> uint { + fn init_to_vec(&self, i: uint) -> uint { return if self.get(i) { 1 } else { 0 }; } @@ -424,7 +421,7 @@ impl Bitv { * * Each uint in the resulting vector has either value 0u or 1u. */ - fn to_vec() -> ~[uint] { + fn to_vec(&self) -> ~[uint] { vec::from_fn(self.nbits, |x| self.init_to_vec(x)) } @@ -434,7 +431,7 @@ impl Bitv { * size of the bitv is not a multiple of 8 then trailing bits * will be filled-in with false/0 */ - fn to_bytes() -> ~[u8] { + fn to_bytes(&self) -> ~[u8] { fn bit (bitv: &Bitv, byte: uint, bit: uint) -> u8 { let offset = byte * 8 + bit; @@ -448,21 +445,21 @@ impl Bitv { let len = self.nbits/8 + if self.nbits % 8 == 0 { 0 } else { 1 }; vec::from_fn(len, |i| - bit(&self, i, 0) | - bit(&self, i, 1) | - bit(&self, i, 2) | - bit(&self, i, 3) | - bit(&self, i, 4) | - bit(&self, i, 5) | - bit(&self, i, 6) | - bit(&self, i, 7) + bit(self, i, 0) | + bit(self, i, 1) | + bit(self, i, 2) | + bit(self, i, 3) | + bit(self, i, 4) | + bit(self, i, 5) | + bit(self, i, 6) | + bit(self, i, 7) ) } /** * Transform self into a [bool] by turning each bit into a bool */ - fn to_bools() -> ~[bool] { + fn to_bools(&self) -> ~[bool] { vec::from_fn(self.nbits, |i| self[i]) } @@ -485,7 +482,7 @@ impl Bitv { * The uint vector is expected to only contain the values 0u and 1u. Both * the bitvector and vector must have the same length */ - fn eq_vec(v: ~[uint]) -> bool { + fn eq_vec(&self, v: ~[uint]) -> bool { assert self.nbits == v.len(); let mut i = 0; while i < self.nbits { @@ -497,7 +494,7 @@ impl Bitv { true } - fn ones(f: fn(uint) -> bool) { + fn ones(&self, f: fn(uint) -> bool) { for uint::range(0, self.nbits) |i| { if self.get(i) { if !f(i) { break } @@ -516,10 +513,10 @@ impl Clone for Bitv { Bitv{nbits: self.nbits, rep: Small(~SmallBitv{bits: b.bits})} } Big(ref b) => { - let mut st = from_elem(self.nbits / uint_bits + 1, 0); + let mut st = from_elem(self.nbits / uint::bits + 1, 0); let len = st.len(); for uint::range(0, len) |i| { st[i] = b.storage[i]; }; - Bitv{nbits: self.nbits, rep: Big(~BigBitv{storage: move st})} + Bitv{nbits: self.nbits, rep: Big(~BigBitv{storage: st})} } } } @@ -551,45 +548,344 @@ pub fn from_bools(bools: &[bool]) -> Bitv { * index is f(index). */ pub fn from_fn(len: uint, f: fn(index: uint) -> bool) -> Bitv { - let bitv = Bitv(len, false); + let mut bitv = Bitv::new(len, false); for uint::range(0, len) |i| { bitv.set(i, f(i)); } - move bitv + bitv } -const uint_bits: uint = 32u + (1u << 32u >> 27u); +impl ops::Index for Bitv { + pure fn index(&self, i: uint) -> bool { + self.get(i) + } +} -pure fn lor(w0: uint, w1: uint) -> uint { return w0 | w1; } +#[inline(always)] +pure fn iterate_bits(base: uint, bits: uint, f: fn(uint) -> bool) -> bool { + if bits == 0 { + return true; + } + for uint::range(0, uint::bits) |i| { + if bits & (1 << i) != 0 { + if !f(base + i) { + return false; + } + } + } + return true; +} -pure fn land(w0: uint, w1: uint) -> uint { return w0 & w1; } +/// An implementation of a set using a bit vector as an underlying +/// representation for holding numerical elements. +/// +/// It should also be noted that the amount of storage necessary for holding a +/// set of objects is proportional to the maximum of the objects when viewed +/// as a uint. +pub struct BitvSet { + priv size: uint, + + // In theory this is a Bitv instead of always a BigBitv, but knowing that + // there's an array of storage makes our lives a whole lot easier when + // performing union/intersection/etc operations + priv bitv: BigBitv +} -pure fn difference(w0: uint, w1: uint) -> uint { return w0 & !w1; } +impl BitvSet { + /// Creates a new bit vector set with initially no contents + static fn new() -> BitvSet { + BitvSet{ size: 0, bitv: BigBitv::new(~[0]) } + } -pure fn right(_w0: uint, w1: uint) -> uint { return w1; } + /// Creates a new bit vector set from the given bit vector + static fn from_bitv(bitv: Bitv) -> BitvSet { + let mut size = 0; + for bitv.ones |_| { + size += 1; + } + let Bitv{rep, _} = bitv; + match rep { + Big(~b) => BitvSet{ size: size, bitv: b }, + Small(~SmallBitv{bits}) => + BitvSet{ size: size, bitv: BigBitv{ storage: ~[bits] } }, + } + } -impl ops::Index for Bitv { - pure fn index(&self, i: uint) -> bool { - self.get(i) + /// 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 } + + /// Consumes this set to return the underlying bit vector + fn unwrap(self) -> Bitv { + let cap = self.capacity(); + let BitvSet{bitv, _} = self; + return Bitv{ nbits:cap, rep: Big(~bitv) }; + } + + #[inline(always)] + priv fn other_op(&mut self, other: &BitvSet, f: fn(uint, uint) -> uint) { + fn nbits(mut w: uint) -> uint { + let mut bits = 0; + for uint::bits.times { + if w == 0 { + break; + } + bits += w & 1; + w >>= 1; + } + return bits; + } + if self.capacity() < other.capacity() { + self.bitv.storage.grow(other.capacity() / uint::bits, &0); + } + for other.bitv.storage.eachi |i, &w| { + let old = self.bitv.storage[i]; + let new = f(old, w); + self.bitv.storage[i] = new; + self.size += nbits(new) - nbits(old); + } + } + + /// Union in-place with the specified other bit vector + fn union_with(&mut self, other: &BitvSet) { + self.other_op(other, |w1, w2| w1 | w2); + } + + /// Intersect in-place with the specified other bit vector + fn intersect_with(&mut self, other: &BitvSet) { + self.other_op(other, |w1, w2| w1 & w2); + } + + /// Difference in-place with the specified other bit vector + fn difference_with(&mut self, other: &BitvSet) { + self.other_op(other, |w1, w2| w1 & !w2); + } + + /// Symmetric difference in-place with the specified other bit vector + fn symmetric_difference_with(&mut self, other: &BitvSet) { + self.other_op(other, |w1, w2| w1 ^ w2); + } +} + +impl BaseIter for BitvSet { + pure fn size_hint(&self) -> Option { Some(self.len()) } + + pure 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; + } + } + } +} + +impl cmp::Eq for BitvSet { + pure fn eq(&self, other: &BitvSet) -> bool { + if self.size != other.size { + return false; + } + for self.each_common(other) |_, w1, w2| { + if w1 != w2 { + return false; + } + } + for self.each_outlier(other) |_, _, w| { + if w != 0 { + return false; + } + } + return true; + } + + pure fn ne(&self, other: &BitvSet) -> bool { !self.eq(other) } +} + +impl Container for BitvSet { + pure fn len(&self) -> uint { self.size } + pure fn is_empty(&self) -> bool { self.size == 0 } +} + +impl Mutable for BitvSet { + fn clear(&mut self) { + for self.bitv.each_storage |w| { *w = 0; } + self.size = 0; + } +} + +impl Set for BitvSet { + pure fn contains(&self, value: &uint) -> bool { + *value < self.bitv.storage.len() * uint::bits && self.bitv.get(*value) + } + + fn insert(&mut self, value: uint) -> bool { + if self.contains(&value) { + return false; + } + let nbits = self.capacity(); + if value >= nbits { + let newsize = uint::max(value, nbits * 2) / uint::bits + 1; + assert newsize > self.bitv.storage.len(); + self.bitv.storage.grow(newsize, &0); + } + self.size += 1; + self.bitv.set(value, true); + return true; + } + + fn remove(&mut self, value: &uint) -> bool { + if !self.contains(value) { + return false; + } + self.size -= 1; + self.bitv.set(*value, false); + + // Attempt to truncate our storage + let mut i = self.bitv.storage.len(); + while i > 1 && self.bitv.storage[i - 1] == 0 { + i -= 1; + } + self.bitv.storage.truncate(i); + + return true; + } + + pure fn is_disjoint(&self, other: &BitvSet) -> bool { + for self.intersection(other) |_| { + return false; + } + return true; + } + + pure fn is_subset(&self, other: &BitvSet) -> bool { + for self.each_common(other) |_, w1, w2| { + if w1 & w2 != w1 { + return false; + } + } + /* If anything is not ours, then everything is not ours so we're + definitely a subset in that case. Otherwise if there's any stray + ones that 'other' doesn't have, we're not a subset. */ + for self.each_outlier(other) |mine, _, w| { + if !mine { + return true; + } else if w != 0 { + return false; + } + } + return true; + } + + pure fn is_superset(&self, other: &BitvSet) -> bool { + other.is_subset(self) + } + + pure 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; + } + } + /* everything we have that they don't also shows up */ + self.each_outlier(other, |mine, i, w| + !mine || iterate_bits(i, w, |b| f(&b)) + ); + } + + pure 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)) { + return; + } + } + self.each_outlier(other, |_, i, w| + iterate_bits(i, w, |b| f(&b)) + ); + } + + pure 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; + } + } + } + + pure 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; + } + } + self.each_outlier(other, |_, i, w| + iterate_bits(i, w, |b| f(&b)) + ); + } +} + +priv impl BitvSet { + /// Visits each of the words that the two bit vectors (self and other) + /// 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, + 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| { + if !f(i * uint::bits, w, other.bitv.storage[i]) { + return; + } + } + } + + /// Visits each word in self or other that extends beyond the other. This + /// will only iterate through one of the vectors, and it only iterates + /// over the portion that doesn't overlap with the other one. + /// + /// 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, + 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| { + if !f(true, (i + min) * uint::bits, w) { + return; + } + } + for other.bitv.storage.view(min, len2).eachi |i, &w| { + if !f(false, (i + min) * uint::bits, w) { + return; + } + } } } #[cfg(test)] mod tests { use core::prelude::*; + use std::test::BenchHarness; use bitv::*; use bitv; use core::uint; use core::vec; + use core::rand; + + const bench_bits : uint = 1 << 14; #[test] pub fn test_to_str() { - let zerolen = Bitv(0u, false); + let zerolen = Bitv::new(0u, false); assert zerolen.to_str() == ~""; - let eightbits = Bitv(8u, false); + let eightbits = Bitv::new(8u, false); assert eightbits.to_str() == ~"00000000"; } @@ -597,7 +893,7 @@ mod tests { pub fn test_0_elements() { let mut act; let mut exp; - act = Bitv(0u, false); + act = Bitv::new(0u, false); exp = vec::from_elem::(0u, 0u); assert act.eq_vec(exp); } @@ -605,15 +901,15 @@ mod tests { #[test] pub fn test_1_element() { let mut act; - act = Bitv(1u, false); + act = Bitv::new(1u, false); assert act.eq_vec(~[0u]); - act = Bitv(1u, true); + act = Bitv::new(1u, true); assert act.eq_vec(~[1u]); } #[test] pub fn test_2_elements() { - let b = bitv::Bitv(2, false); + let mut b = bitv::Bitv::new(2, false); b.set(0, true); b.set(1, false); assert b.to_str() == ~"10"; @@ -624,15 +920,15 @@ mod tests { let mut act; // all 0 - act = Bitv(10u, false); + act = Bitv::new(10u, false); assert (act.eq_vec(~[0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u])); // all 1 - act = Bitv(10u, true); + act = Bitv::new(10u, true); assert (act.eq_vec(~[1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u])); // mixed - act = Bitv(10u, false); + act = Bitv::new(10u, false); act.set(0u, true); act.set(1u, true); act.set(2u, true); @@ -641,7 +937,7 @@ mod tests { assert (act.eq_vec(~[1u, 1u, 1u, 1u, 1u, 0u, 0u, 0u, 0u, 0u])); // mixed - act = Bitv(10u, false); + act = Bitv::new(10u, false); act.set(5u, true); act.set(6u, true); act.set(7u, true); @@ -650,7 +946,7 @@ mod tests { assert (act.eq_vec(~[0u, 0u, 0u, 0u, 0u, 1u, 1u, 1u, 1u, 1u])); // mixed - act = Bitv(10u, false); + act = Bitv::new(10u, false); act.set(0u, true); act.set(3u, true); act.set(6u, true); @@ -663,21 +959,21 @@ mod tests { let mut act; // all 0 - act = Bitv(31u, false); + act = Bitv::new(31u, false); assert (act.eq_vec( ~[0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u])); // all 1 - act = Bitv(31u, true); + act = Bitv::new(31u, true); assert (act.eq_vec( ~[1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u])); // mixed - act = Bitv(31u, false); + act = Bitv::new(31u, false); act.set(0u, true); act.set(1u, true); act.set(2u, true); @@ -692,7 +988,7 @@ mod tests { 0u, 0u, 0u, 0u, 0u])); // mixed - act = Bitv(31u, false); + act = Bitv::new(31u, false); act.set(16u, true); act.set(17u, true); act.set(18u, true); @@ -707,7 +1003,7 @@ mod tests { 0u, 0u, 0u, 0u, 0u])); // mixed - act = Bitv(31u, false); + act = Bitv::new(31u, false); act.set(24u, true); act.set(25u, true); act.set(26u, true); @@ -721,7 +1017,7 @@ mod tests { 1u, 1u, 1u, 1u, 1u])); // mixed - act = Bitv(31u, false); + act = Bitv::new(31u, false); act.set(3u, true); act.set(17u, true); act.set(30u, true); @@ -736,21 +1032,21 @@ mod tests { let mut act; // all 0 - act = Bitv(32u, false); + act = Bitv::new(32u, false); assert (act.eq_vec( ~[0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u])); // all 1 - act = Bitv(32u, true); + act = Bitv::new(32u, true); assert (act.eq_vec( ~[1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u])); // mixed - act = Bitv(32u, false); + act = Bitv::new(32u, false); act.set(0u, true); act.set(1u, true); act.set(2u, true); @@ -765,7 +1061,7 @@ mod tests { 0u, 0u, 0u, 0u, 0u, 0u])); // mixed - act = Bitv(32u, false); + act = Bitv::new(32u, false); act.set(16u, true); act.set(17u, true); act.set(18u, true); @@ -780,7 +1076,7 @@ mod tests { 0u, 0u, 0u, 0u, 0u, 0u])); // mixed - act = Bitv(32u, false); + act = Bitv::new(32u, false); act.set(24u, true); act.set(25u, true); act.set(26u, true); @@ -795,7 +1091,7 @@ mod tests { 1u, 1u, 1u, 1u, 1u, 1u])); // mixed - act = Bitv(32u, false); + act = Bitv::new(32u, false); act.set(3u, true); act.set(17u, true); act.set(30u, true); @@ -811,21 +1107,21 @@ mod tests { let mut act; // all 0 - act = Bitv(33u, false); + act = Bitv::new(33u, false); assert (act.eq_vec( ~[0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u])); // all 1 - act = Bitv(33u, true); + act = Bitv::new(33u, true); assert (act.eq_vec( ~[1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u])); // mixed - act = Bitv(33u, false); + act = Bitv::new(33u, false); act.set(0u, true); act.set(1u, true); act.set(2u, true); @@ -840,7 +1136,7 @@ mod tests { 0u, 0u, 0u, 0u, 0u, 0u, 0u])); // mixed - act = Bitv(33u, false); + act = Bitv::new(33u, false); act.set(16u, true); act.set(17u, true); act.set(18u, true); @@ -855,7 +1151,7 @@ mod tests { 0u, 0u, 0u, 0u, 0u, 0u, 0u])); // mixed - act = Bitv(33u, false); + act = Bitv::new(33u, false); act.set(24u, true); act.set(25u, true); act.set(26u, true); @@ -870,7 +1166,7 @@ mod tests { 1u, 1u, 1u, 1u, 1u, 1u, 0u])); // mixed - act = Bitv(33u, false); + act = Bitv::new(33u, false); act.set(3u, true); act.set(17u, true); act.set(30u, true); @@ -884,24 +1180,24 @@ mod tests { #[test] pub fn test_equal_differing_sizes() { - let v0 = Bitv(10u, false); - let v1 = Bitv(11u, false); + let v0 = Bitv::new(10u, false); + let v1 = Bitv::new(11u, false); assert !v0.equal(&v1); } #[test] pub fn test_equal_greatly_differing_sizes() { - let v0 = Bitv(10u, false); - let v1 = Bitv(110u, false); + let v0 = Bitv::new(10u, false); + let v1 = Bitv::new(110u, false); assert !v0.equal(&v1); } #[test] pub fn test_equal_sneaky_small() { - let a = bitv::Bitv(1, false); + let mut a = bitv::Bitv::new(1, false); a.set(0, true); - let b = bitv::Bitv(1, true); + let mut b = bitv::Bitv::new(1, true); b.set(0, true); assert a.equal(&b); @@ -909,12 +1205,12 @@ mod tests { #[test] pub fn test_equal_sneaky_big() { - let a = bitv::Bitv(100, false); + let mut a = bitv::Bitv::new(100, false); for uint::range(0, 100) |i| { a.set(i, true); } - let b = bitv::Bitv(100, true); + let mut b = bitv::Bitv::new(100, true); for uint::range(0, 100) |i| { b.set(i, true); } @@ -931,11 +1227,11 @@ mod tests { #[test] pub fn test_to_bytes() { - let bv = Bitv(3, true); + let mut bv = Bitv::new(3, true); bv.set(1, false); assert bv.to_bytes() == ~[0b10100000]; - let bv = Bitv(9, false); + let mut bv = Bitv::new(9, false); bv.set(2, true); bv.set(8, true); assert bv.to_bytes() == ~[0b00100000, 0b10000000]; @@ -954,48 +1250,266 @@ mod tests { #[test] pub fn test_small_difference() { - let b1 = Bitv(3, false); - let b2 = Bitv(3, false); - b1.set(0, true); - b1.set(1, true); - b2.set(1, true); - b2.set(2, true); - assert b1.difference(&b2); - assert b1[0]; - assert !b1[1]; - assert !b1[2]; + let mut b1 = Bitv::new(3, false); + let mut b2 = Bitv::new(3, false); + b1.set(0, true); + b1.set(1, true); + b2.set(1, true); + b2.set(2, true); + assert b1.difference(&b2); + assert b1[0]; + assert !b1[1]; + assert !b1[2]; } #[test] pub fn test_big_difference() { - let b1 = Bitv(100, false); - let b2 = Bitv(100, false); - b1.set(0, true); - b1.set(40, true); - b2.set(40, true); - b2.set(80, true); - assert b1.difference(&b2); - assert b1[0]; - assert !b1[40]; - assert !b1[80]; + let mut b1 = Bitv::new(100, false); + let mut b2 = Bitv::new(100, false); + b1.set(0, true); + b1.set(40, true); + b2.set(40, true); + b2.set(80, true); + assert b1.difference(&b2); + assert b1[0]; + assert !b1[40]; + assert !b1[80]; } #[test] pub fn test_small_clear() { - let b = Bitv(14, true); - b.clear(); - for b.ones |i| { - fail!(fmt!("found 1 at %?", i)); - } + let mut b = Bitv::new(14, true); + b.clear(); + for b.ones |i| { + fail!(fmt!("found 1 at %?", i)); + } } #[test] pub fn test_big_clear() { - let b = Bitv(140, true); - b.clear(); - for b.ones |i| { - fail!(fmt!("found 1 at %?", i)); - } + let mut b = Bitv::new(140, true); + b.clear(); + for b.ones |i| { + fail!(fmt!("found 1 at %?", i)); + } + } + + #[test] + pub fn test_bitv_set_basic() { + let mut b = BitvSet::new(); + assert b.insert(3); + assert !b.insert(3); + assert b.contains(&3); + assert b.insert(400); + assert !b.insert(400); + assert b.contains(&400); + assert b.len() == 2; + } + + #[test] + fn test_bitv_set_intersection() { + let mut a = BitvSet::new(); + let mut b = BitvSet::new(); + + assert a.insert(11); + assert a.insert(1); + assert a.insert(3); + assert a.insert(77); + assert a.insert(103); + assert a.insert(5); + + assert b.insert(2); + assert b.insert(11); + assert b.insert(77); + assert b.insert(5); + assert b.insert(3); + + let mut i = 0; + let expected = [3, 5, 11, 77]; + for a.intersection(&b) |x| { + assert *x == expected[i]; + i += 1 + } + assert i == expected.len(); + } + + #[test] + fn test_bitv_set_difference() { + let mut a = BitvSet::new(); + let mut b = BitvSet::new(); + + assert a.insert(1); + assert a.insert(3); + assert a.insert(5); + assert a.insert(200); + assert a.insert(500); + + assert b.insert(3); + assert b.insert(200); + + let mut i = 0; + let expected = [1, 5, 500]; + for a.difference(&b) |x| { + assert *x == expected[i]; + i += 1 + } + assert i == expected.len(); + } + + #[test] + fn test_bitv_set_symmetric_difference() { + let mut a = BitvSet::new(); + let mut b = BitvSet::new(); + + assert a.insert(1); + assert a.insert(3); + assert a.insert(5); + assert a.insert(9); + assert a.insert(11); + + assert b.insert(3); + assert b.insert(9); + assert b.insert(14); + assert b.insert(220); + + let mut i = 0; + let expected = [1, 5, 11, 14, 220]; + for a.symmetric_difference(&b) |x| { + assert *x == expected[i]; + i += 1 + } + assert i == expected.len(); + } + + #[test] + pub fn test_bitv_set_union() { + let mut a = BitvSet::new(); + let mut b = BitvSet::new(); + assert a.insert(1); + assert a.insert(3); + assert a.insert(5); + assert a.insert(9); + assert a.insert(11); + assert a.insert(160); + assert a.insert(19); + assert a.insert(24); + + assert b.insert(1); + assert b.insert(5); + assert b.insert(9); + assert b.insert(13); + assert b.insert(19); + + let mut i = 0; + let expected = [1, 3, 5, 9, 11, 13, 19, 24, 160]; + for a.union(&b) |x| { + assert *x == expected[i]; + i += 1 + } + assert i == expected.len(); + } + + #[test] + pub fn test_bitv_remove() { + let mut a = BitvSet::new(); + + assert a.insert(1); + assert a.remove(&1); + + assert a.insert(100); + assert a.remove(&100); + + assert a.insert(1000); + assert a.remove(&1000); + assert a.capacity() == uint::bits; + } + + fn rng() -> rand::Rng { + let seed = [1, 2, 3, 4, 5, 6, 7, 8, 9, 0]; + rand::seeded_rng(seed) + } + + #[bench] + pub fn bench_uint_small(b: &mut BenchHarness) { + let r = rng(); + let mut bitv = 0 as uint; + do b.iter { + bitv |= (1 << ((r.next() as uint) % uint::bits)); + } + } + + #[bench] + pub fn bench_small_bitv_small(b: &mut BenchHarness) { + let r = rng(); + let mut bitv = SmallBitv::new(uint::bits); + do b.iter { + bitv.set((r.next() as uint) % uint::bits, true); + } + } + + #[bench] + pub fn bench_big_bitv_small(b: &mut BenchHarness) { + let r = rng(); + let mut bitv = BigBitv::new(~[0]); + do b.iter { + bitv.set((r.next() as uint) % uint::bits, true); + } + } + + #[bench] + pub fn bench_big_bitv_big(b: &mut BenchHarness) { + let r = rng(); + let mut storage = ~[]; + storage.grow(bench_bits / uint::bits, &0); + let mut bitv = BigBitv::new(storage); + do b.iter { + bitv.set((r.next() as uint) % bench_bits, true); + } + } + + #[bench] + pub fn bench_bitv_big(b: &mut BenchHarness) { + let r = rng(); + let mut bitv = Bitv::new(bench_bits, false); + do b.iter { + bitv.set((r.next() as uint) % bench_bits, true); + } + } + + #[bench] + pub fn bench_bitv_small(b: &mut BenchHarness) { + let r = rng(); + let mut bitv = Bitv::new(uint::bits, false); + do b.iter { + bitv.set((r.next() as uint) % uint::bits, true); + } + } + + #[bench] + pub fn bench_bitv_set_small(b: &mut BenchHarness) { + let r = rng(); + let mut bitv = BitvSet::new(); + do b.iter { + bitv.insert((r.next() as uint) % uint::bits); + } + } + + #[bench] + pub fn bench_bitv_set_big(b: &mut BenchHarness) { + let r = rng(); + let mut bitv = BitvSet::new(); + do b.iter { + bitv.insert((r.next() as uint) % bench_bits); + } + } + + #[bench] + pub fn bench_bitv_big_union(b: &mut BenchHarness) { + let mut b1 = Bitv::new(bench_bits, false); + let mut b2 = Bitv::new(bench_bits, false); + do b.iter { + b1.union(&b2); + } } } diff --git a/src/libstd/c_vec.rs b/src/libstd/c_vec.rs index 696b2753ea44b..5af596c1f84e4 100644 --- a/src/libstd/c_vec.rs +++ b/src/libstd/c_vec.rs @@ -120,7 +120,7 @@ pub unsafe fn c_vec_with_dtor(base: *mut T, len: uint, dtor: fn@()) * * Fails if `ofs` is greater or equal to the length of the vector */ -pub fn get(t: CVec, ofs: uint) -> T { +pub fn get(t: CVec, ofs: uint) -> T { assert ofs < len(t); return unsafe { *ptr::mut_offset(t.base, ofs) }; } @@ -130,7 +130,7 @@ pub fn get(t: CVec, ofs: uint) -> T { * * Fails if `ofs` is greater or equal to the length of the vector */ -pub fn set(t: CVec, ofs: uint, v: T) { +pub fn set(t: CVec, ofs: uint, v: T) { assert ofs < len(t); unsafe { *ptr::mut_offset(t.base, ofs) = v }; } diff --git a/src/libstd/cell.rs b/src/libstd/cell.rs index f0ec3c1b9d767..c8121daddabd0 100644 --- a/src/libstd/cell.rs +++ b/src/libstd/cell.rs @@ -21,7 +21,7 @@ pub struct Cell { /// Creates a new full cell with the given value. pub fn Cell(value: T) -> Cell { - Cell { value: Some(move value) } + Cell { value: Some(value) } } pub pure fn empty_cell() -> Cell { @@ -37,7 +37,7 @@ impl Cell { let mut value = None; value <-> self.value; - return option::unwrap(move value); + return option::unwrap(value); } /// Returns the value, failing if the cell is full. @@ -45,7 +45,7 @@ impl Cell { if !self.is_empty() { fail!(~"attempt to put a value back into a full cell"); } - self.value = Some(move value); + self.value = Some(value); } /// Returns true if the cell is empty and false if the cell is full. @@ -57,8 +57,8 @@ impl Cell { fn with_ref(op: fn(v: &T) -> R) -> R { let v = self.take(); let r = op(&v); - self.put_back(move v); - move r + self.put_back(v); + r } } @@ -69,7 +69,7 @@ fn test_basic() { let value = value_cell.take(); assert value == ~10; assert value_cell.is_empty(); - value_cell.put_back(move value); + value_cell.put_back(value); assert !value_cell.is_empty(); } diff --git a/src/libstd/comm.rs b/src/libstd/comm.rs index 47f3c70352c3b..02875739ebaf9 100644 --- a/src/libstd/comm.rs +++ b/src/libstd/comm.rs @@ -14,8 +14,8 @@ Higher level communication abstractions. */ -use core::pipes::{GenericChan, GenericSmartChan, GenericPort}; -use core::pipes::{Chan, Port, Selectable, Peekable}; +use core::comm::{GenericChan, GenericSmartChan, GenericPort}; +use core::comm::{Chan, Port, Selectable, Peekable}; use core::pipes; use core::prelude::*; @@ -25,19 +25,19 @@ pub struct DuplexStream { priv port: Port, } -impl GenericChan for DuplexStream { +impl GenericChan for DuplexStream { fn send(x: T) { - self.chan.send(move x) + self.chan.send(x) } } -impl GenericSmartChan for DuplexStream { +impl GenericSmartChan for DuplexStream { fn try_send(x: T) -> bool { - self.chan.try_send(move x) + self.chan.try_send(x) } } -impl GenericPort for DuplexStream { +impl GenericPort for DuplexStream { fn recv() -> U { self.port.recv() } @@ -47,31 +47,31 @@ impl GenericPort for DuplexStream { } } -impl Peekable for DuplexStream { +impl Peekable for DuplexStream { pure fn peek() -> bool { self.port.peek() } } -impl Selectable for DuplexStream { +impl Selectable for DuplexStream { pure fn header() -> *pipes::PacketHeader { self.port.header() } } /// Creates a bidirectional stream. -pub fn DuplexStream() +pub fn DuplexStream() -> (DuplexStream, DuplexStream) { - let (p1, c2) = pipes::stream(); - let (p2, c1) = pipes::stream(); + let (p1, c2) = comm::stream(); + let (p2, c1) = comm::stream(); (DuplexStream { - chan: move c1, - port: move p1 + chan: c1, + port: p1 }, DuplexStream { - chan: move c2, - port: move p2 + chan: c2, + port: p2 }) } diff --git a/src/libstd/deque.rs b/src/libstd/deque.rs index 772cacf47a11b..0ac76cefd6b36 100644 --- a/src/libstd/deque.rs +++ b/src/libstd/deque.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. // @@ -8,178 +8,158 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -//! A deque. Untested as of yet. Likely buggy -#[forbid(non_camel_case_types)]; - +use core::container::{Container, Mutable}; use core::cmp::Eq; -use core::dvec::DVec; -use core::dvec; use core::prelude::*; use core::uint; use core::vec; -pub trait Deque { - fn size() -> uint; - fn add_front(v: T); - fn add_back(v: T); - fn pop_front() -> T; - fn pop_back() -> T; - fn peek_front() -> T; - fn peek_back() -> T; - fn get(int) -> T; +const initial_capacity: uint = 32u; // 2^5 + +pub struct Deque { + priv nelts: uint, + priv lo: uint, + priv hi: uint, + priv elts: ~[Option] } -// FIXME (#2343) eventually, a proper datatype plus an exported impl would -// be preferrable. -pub fn create() -> Deque { - type Cell = Option; +impl Container for Deque { + pure fn len(&self) -> uint { self.nelts } + pure fn is_empty(&self) -> bool { self.len() == 0 } +} - let initial_capacity: uint = 32u; // 2^5 - /** - * Grow is only called on full elts, so nelts is also len(elts), unlike - * elsewhere. - */ - fn grow(nelts: uint, lo: uint, elts: ~[Cell]) - -> ~[Cell] { - let mut elts = move elts; - assert (nelts == vec::len(elts)); - let mut rv = ~[]; +impl Mutable for Deque { + fn clear(&mut self) { + for vec::each_mut(self.elts) |x| { *x = None } + self.nelts = 0; + self.lo = 0; + self.hi = 0; + } +} - let mut i = 0u; - let nalloc = uint::next_power_of_two(nelts + 1u); - while i < nalloc { - if i < nelts { - rv.push(elts[(lo + i) % nelts]); - } else { rv.push(None); } - i += 1u; - } +impl Deque { + static pure fn new() -> Deque { + Deque{nelts: 0, lo: 0, hi: 0, + elts: vec::from_fn(initial_capacity, |_| None)} + } + + fn peek_front(&self) -> &self/T { get(self.elts, self.lo) } + fn peek_back(&self) -> &self/T { get(self.elts, self.hi - 1u) } - move rv + fn get(&self, i: int) -> &self/T { + let idx = (self.lo + (i as uint)) % self.elts.len(); + get(self.elts, idx) } - fn get(elts: &DVec>, i: uint) -> T { - match (*elts).get_elt(i) { Some(move t) => t, _ => fail!() } + + fn pop_front(&mut self) -> T { + let mut result = self.elts[self.lo].swap_unwrap(); + self.lo = (self.lo + 1u) % self.elts.len(); + self.nelts -= 1u; + result } - struct Repr { - mut nelts: uint, - mut lo: uint, - mut hi: uint, - elts: DVec>, + fn pop_back(&mut self) -> T { + if self.hi == 0u { + self.hi = self.elts.len() - 1u; + } else { self.hi -= 1u; } + let mut result = self.elts[self.hi].swap_unwrap(); + self.elts[self.hi] = None; + self.nelts -= 1u; + result } - impl Deque for Repr { - fn size() -> uint { return self.nelts; } - fn add_front(t: T) { - let oldlo: uint = self.lo; - if self.lo == 0u { - self.lo = self.elts.len() - 1u; - } else { self.lo -= 1u; } - if self.lo == self.hi { - self.elts.swap(|v| grow(self.nelts, oldlo, move v)); - self.lo = self.elts.len() - 1u; - self.hi = self.nelts; - } - self.elts.set_elt(self.lo, Some(t)); - self.nelts += 1u; - } - fn add_back(t: T) { - if self.lo == self.hi && self.nelts != 0u { - self.elts.swap(|v| grow(self.nelts, self.lo, move v)); - self.lo = 0u; - self.hi = self.nelts; - } - self.elts.set_elt(self.hi, Some(t)); - self.hi = (self.hi + 1u) % self.elts.len(); - self.nelts += 1u; - } - /** - * We actually release (turn to none()) the T we're popping so - * that we don't keep anyone's refcount up unexpectedly. - */ - fn pop_front() -> T { - let t: T = get(&self.elts, self.lo); - self.elts.set_elt(self.lo, None); - self.lo = (self.lo + 1u) % self.elts.len(); - self.nelts -= 1u; - return t; - } - fn pop_back() -> T { - if self.hi == 0u { - self.hi = self.elts.len() - 1u; - } else { self.hi -= 1u; } - let t: T = get(&self.elts, self.hi); - self.elts.set_elt(self.hi, None); - self.nelts -= 1u; - return t; + fn add_front(&mut self, t: T) { + let oldlo = self.lo; + if self.lo == 0u { + self.lo = self.elts.len() - 1u; + } else { self.lo -= 1u; } + if self.lo == self.hi { + self.elts = grow(self.nelts, oldlo, self.elts); + self.lo = self.elts.len() - 1u; + self.hi = self.nelts; } - fn peek_front() -> T { return get(&self.elts, self.lo); } - fn peek_back() -> T { return get(&self.elts, self.hi - 1u); } - fn get(i: int) -> T { - let idx = (self.lo + (i as uint)) % self.elts.len(); - return get(&self.elts, idx); + self.elts[self.lo] = Some(t); + self.nelts += 1u; + } + + fn add_back(&mut self, t: T) { + if self.lo == self.hi && self.nelts != 0u { + self.elts = grow(self.nelts, self.lo, self.elts); + self.lo = 0u; + self.hi = self.nelts; } + self.elts[self.hi] = Some(t); + self.hi = (self.hi + 1u) % self.elts.len(); + self.nelts += 1u; + } +} + +/// Grow is only called on full elts, so nelts is also len(elts), unlike +/// elsewhere. +fn grow(nelts: uint, lo: uint, elts: &mut [Option]) -> ~[Option] { + assert nelts == elts.len(); + let mut rv = ~[]; + + do rv.grow_fn(nelts + 1) |i| { + let mut element = None; + element <-> elts[(lo + i) % nelts]; + element } - let repr: Repr = Repr { - nelts: 0u, - lo: 0u, - hi: 0u, - elts: dvec::from_vec(vec::from_elem(initial_capacity, None)), - }; + rv +} - repr as Deque:: +fn get(elts: &r/[Option], i: uint) -> &r/T { + match elts[i] { Some(ref t) => t, _ => fail!() } } #[cfg(test)] mod tests { - use core::prelude::*; - - use deque::*; - use deque; + use super::*; #[test] fn test_simple() { - let d: deque::Deque = deque::create::(); - assert (d.size() == 0u); + let mut d = Deque::new(); + assert d.len() == 0u; d.add_front(17); d.add_front(42); d.add_back(137); - assert (d.size() == 3u); + assert d.len() == 3u; d.add_back(137); - assert (d.size() == 4u); + assert d.len() == 4u; log(debug, d.peek_front()); - assert (d.peek_front() == 42); + assert *d.peek_front() == 42; log(debug, d.peek_back()); - assert (d.peek_back() == 137); + assert *d.peek_back() == 137; let mut i: int = d.pop_front(); log(debug, i); - assert (i == 42); + assert i == 42; i = d.pop_back(); log(debug, i); - assert (i == 137); + assert i == 137; i = d.pop_back(); log(debug, i); - assert (i == 137); + assert i == 137; i = d.pop_back(); log(debug, i); - assert (i == 17); - assert (d.size() == 0u); + assert i == 17; + assert d.len() == 0u; d.add_back(3); - assert (d.size() == 1u); + assert d.len() == 1u; d.add_front(2); - assert (d.size() == 2u); + assert d.len() == 2u; d.add_back(4); - assert (d.size() == 3u); + assert d.len() == 3u; d.add_front(1); - assert (d.size() == 4u); + assert d.len() == 4u; log(debug, d.get(0)); log(debug, d.get(1)); log(debug, d.get(2)); log(debug, d.get(3)); - assert (d.get(0) == 1); - assert (d.get(1) == 2); - assert (d.get(2) == 3); - assert (d.get(3) == 4); + assert *d.get(0) == 1; + assert *d.get(1) == 2; + assert *d.get(2) == 3; + assert *d.get(3) == 4; } #[test] @@ -189,63 +169,63 @@ mod tests { let c: @int = @64; let d: @int = @175; - let deq: deque::Deque<@int> = deque::create::<@int>(); - assert (deq.size() == 0u); + let mut deq = Deque::new(); + assert deq.len() == 0; deq.add_front(a); deq.add_front(b); deq.add_back(c); - assert (deq.size() == 3u); + assert deq.len() == 3; deq.add_back(d); - assert (deq.size() == 4u); - assert (deq.peek_front() == b); - assert (deq.peek_back() == d); - assert (deq.pop_front() == b); - assert (deq.pop_back() == d); - assert (deq.pop_back() == c); - assert (deq.pop_back() == a); - assert (deq.size() == 0u); + assert deq.len() == 4; + assert *deq.peek_front() == b; + assert *deq.peek_back() == d; + assert deq.pop_front() == b; + assert deq.pop_back() == d; + assert deq.pop_back() == c; + assert deq.pop_back() == a; + assert deq.len() == 0; deq.add_back(c); - assert (deq.size() == 1u); + assert deq.len() == 1; deq.add_front(b); - assert (deq.size() == 2u); + assert deq.len() == 2; deq.add_back(d); - assert (deq.size() == 3u); + assert deq.len() == 3; deq.add_front(a); - assert (deq.size() == 4u); - assert (deq.get(0) == a); - assert (deq.get(1) == b); - assert (deq.get(2) == c); - assert (deq.get(3) == d); + assert deq.len() == 4; + assert *deq.get(0) == a; + assert *deq.get(1) == b; + assert *deq.get(2) == c; + assert *deq.get(3) == d; } - fn test_parameterized(a: T, b: T, c: T, d: T) { - let deq: deque::Deque = deque::create::(); - assert (deq.size() == 0u); + fn test_parameterized(a: T, b: T, c: T, d: T) { + let mut deq = Deque::new(); + assert deq.len() == 0; deq.add_front(a); deq.add_front(b); deq.add_back(c); - assert (deq.size() == 3u); + assert deq.len() == 3; deq.add_back(d); - assert (deq.size() == 4u); - assert deq.peek_front() == b; - assert deq.peek_back() == d; + assert deq.len() == 4; + assert *deq.peek_front() == b; + assert *deq.peek_back() == d; assert deq.pop_front() == b; assert deq.pop_back() == d; assert deq.pop_back() == c; assert deq.pop_back() == a; - assert (deq.size() == 0u); + assert deq.len() == 0; deq.add_back(c); - assert (deq.size() == 1u); + assert deq.len() == 1; deq.add_front(b); - assert (deq.size() == 2u); + assert deq.len() == 2; deq.add_back(d); - assert (deq.size() == 3u); + assert deq.len() == 3; deq.add_front(a); - assert (deq.size() == 4u); - assert deq.get(0) == a; - assert deq.get(1) == b; - assert deq.get(2) == c; - assert deq.get(3) == d; + assert deq.len() == 4; + assert *deq.get(0) == a; + assert *deq.get(1) == b; + assert *deq.get(2) == c; + assert *deq.get(3) == d; } #[deriving_eq] diff --git a/src/libstd/ebml.rs b/src/libstd/ebml.rs index f691dfe6a6273..84df1785503dc 100644 --- a/src/libstd/ebml.rs +++ b/src/libstd/ebml.rs @@ -177,10 +177,12 @@ pub mod reader { } } - pub fn doc_data(d: Doc) -> ~[u8] { vec::slice::(*d.data, d.start, - d.end) } + pub fn doc_data(d: Doc) -> ~[u8] { + vec::slice::(*d.data, d.start, d.end).to_vec() + } + pub fn with_doc_data(d: Doc, f: fn(x: &[u8]) -> T) -> T { - f(vec::view(*d.data, d.start, d.end)) + f(vec::slice(*d.data, d.start, d.end)) } pub fn doc_as_str(d: Doc) -> ~str { str::from_bytes(doc_data(d)) } @@ -259,7 +261,7 @@ pub mod reader { r_doc } - fn push_doc(d: Doc, f: fn() -> T) -> T{ + fn push_doc(d: Doc, f: fn() -> T) -> T { let old_parent = self.parent; let old_pos = self.pos; self.parent = d; @@ -267,7 +269,7 @@ pub mod reader { let r = f(); self.parent = old_parent; self.pos = old_pos; - move r + r } fn _next_uint(exp_tag: EbmlEncoderTag) -> uint { diff --git a/src/libstd/flatpipes.rs b/src/libstd/flatpipes.rs index dad761ac20d7c..13c0bbe1a674c 100644 --- a/src/libstd/flatpipes.rs +++ b/src/libstd/flatpipes.rs @@ -28,7 +28,7 @@ This example sends boxed integers across tasks using serialization. ~~~ let (port, chan) = serial::pipe_stream(); -do task::spawn |move chan| { +do task::spawn || { for int::range(0, 10) |i| { chan.send(@i) } @@ -49,8 +49,8 @@ block the scheduler thread, so will their pipes. // The basic send/recv interface FlatChan and PortChan will implement use core::io; -use core::pipes::GenericChan; -use core::pipes::GenericPort; +use core::comm::GenericChan; +use core::comm::GenericPort; use core::pipes; use core::prelude::*; use core::sys::size_of; @@ -95,8 +95,8 @@ pub mod serial { use flatpipes::{FlatPort, FlatChan}; use core::io::{Reader, Writer}; - use core::pipes::{Port, Chan}; - use core::pipes; + use core::comm::{Port, Chan}; + use core::comm; pub type ReaderPort = FlatPort< T, DeserializingUnflattener, @@ -114,8 +114,8 @@ pub mod serial { let unflat: DeserializingUnflattener = DeserializingUnflattener::new( deserialize_buffer::); - let byte_port = ReaderBytePort::new(move reader); - FlatPort::new(move unflat, move byte_port) + let byte_port = ReaderBytePort::new(reader); + FlatPort::new(unflat, byte_port) } /// Create a `FlatChan` from a `Writer` @@ -124,38 +124,38 @@ pub mod serial { let flat: SerializingFlattener = SerializingFlattener::new( serialize_value::); - let byte_chan = WriterByteChan::new(move writer); - FlatChan::new(move flat, move byte_chan) + let byte_chan = WriterByteChan::new(writer); + FlatChan::new(flat, byte_chan) } /// Create a `FlatPort` from a `Port<~[u8]>` - pub fn pipe_port>( + pub fn pipe_port>( port: Port<~[u8]> ) -> PipePort { let unflat: DeserializingUnflattener = DeserializingUnflattener::new( deserialize_buffer::); - let byte_port = PipeBytePort::new(move port); - FlatPort::new(move unflat, move byte_port) + let byte_port = PipeBytePort::new(port); + FlatPort::new(unflat, byte_port) } /// Create a `FlatChan` from a `Chan<~[u8]>` - pub fn pipe_chan>( + pub fn pipe_chan>( chan: Chan<~[u8]> ) -> PipeChan { let flat: SerializingFlattener = SerializingFlattener::new( serialize_value::); - let byte_chan = PipeByteChan::new(move chan); - FlatChan::new(move flat, move byte_chan) + let byte_chan = PipeByteChan::new(chan); + FlatChan::new(flat, byte_chan) } /// Create a pair of `FlatChan` and `FlatPort`, backed by pipes - pub fn pipe_stream + pub fn pipe_stream + Decodable>( ) -> (PipePort, PipeChan) { - let (port, chan) = pipes::stream(); - return (pipe_port(move port), pipe_chan(move chan)); + let (port, chan) = comm::stream(); + return (pipe_port(port), pipe_chan(chan)); } } @@ -177,8 +177,8 @@ pub mod pod { use flatpipes::{FlatPort, FlatChan}; use core::io::{Reader, Writer}; - use core::pipes::{Port, Chan}; - use core::pipes; + use core::comm::{Port, Chan}; + use core::comm; use core::prelude::*; pub type ReaderPort = @@ -189,41 +189,41 @@ pub mod pod { pub type PipeChan = FlatChan, PipeByteChan>; /// Create a `FlatPort` from a `Reader` - pub fn reader_port( + pub fn reader_port( reader: R ) -> ReaderPort { let unflat: PodUnflattener = PodUnflattener::new(); - let byte_port = ReaderBytePort::new(move reader); - FlatPort::new(move unflat, move byte_port) + let byte_port = ReaderBytePort::new(reader); + FlatPort::new(unflat, byte_port) } /// Create a `FlatChan` from a `Writer` - pub fn writer_chan( + pub fn writer_chan( writer: W ) -> WriterChan { let flat: PodFlattener = PodFlattener::new(); - let byte_chan = WriterByteChan::new(move writer); - FlatChan::new(move flat, move byte_chan) + let byte_chan = WriterByteChan::new(writer); + FlatChan::new(flat, byte_chan) } /// Create a `FlatPort` from a `Port<~[u8]>` - pub fn pipe_port(port: Port<~[u8]>) -> PipePort { + pub fn pipe_port(port: Port<~[u8]>) -> PipePort { let unflat: PodUnflattener = PodUnflattener::new(); - let byte_port = PipeBytePort::new(move port); - FlatPort::new(move unflat, move byte_port) + let byte_port = PipeBytePort::new(port); + FlatPort::new(unflat, byte_port) } /// Create a `FlatChan` from a `Chan<~[u8]>` - pub fn pipe_chan(chan: Chan<~[u8]>) -> PipeChan { + pub fn pipe_chan(chan: Chan<~[u8]>) -> PipeChan { let flat: PodFlattener = PodFlattener::new(); - let byte_chan = PipeByteChan::new(move chan); - FlatChan::new(move flat, move byte_chan) + let byte_chan = PipeByteChan::new(chan); + FlatChan::new(flat, byte_chan) } /// Create a pair of `FlatChan` and `FlatPort`, backed by pipes - pub fn pipe_stream() -> (PipePort, PipeChan) { - let (port, chan) = pipes::stream(); - return (pipe_port(move port), pipe_chan(move chan)); + pub fn pipe_stream() -> (PipePort, PipeChan) { + let (port, chan) = comm::stream(); + return (pipe_port(port), pipe_chan(chan)); } } @@ -258,16 +258,16 @@ pub trait ByteChan { const CONTINUE: [u8 * 4] = [0xAA, 0xBB, 0xCC, 0xDD]; -pub impl,P:BytePort> FlatPort: GenericPort { +pub impl,P:BytePort> GenericPort for FlatPort { fn recv() -> T { match self.try_recv() { - Some(move val) => move val, + Some(val) => val, None => fail!(~"port is closed") } } fn try_recv() -> Option { let command = match self.byte_port.try_recv(CONTINUE.len()) { - Some(move c) => move c, + Some(c) => c, None => { warn!("flatpipe: broken pipe"); return None; @@ -288,8 +288,8 @@ pub impl,P:BytePort> FlatPort: GenericPort { let msg_len = msg_len as uint; match self.byte_port.try_recv(msg_len) { - Some(move bytes) => { - Some(self.unflattener.unflatten(move bytes)) + Some(bytes) => { + Some(self.unflattener.unflatten(bytes)) } None => { warn!("flatpipe: broken pipe"); @@ -306,20 +306,20 @@ pub impl,P:BytePort> FlatPort: GenericPort { impl,C:ByteChan> GenericChan for FlatChan { fn send(val: T) { self.byte_chan.send(CONTINUE.to_vec()); - let bytes = self.flattener.flatten(move val); + let bytes = self.flattener.flatten(val); let len = bytes.len() as u64; do io::u64_to_be_bytes(len, size_of::()) |len_bytes| { self.byte_chan.send(len_bytes.to_vec()); } - self.byte_chan.send(move bytes); + self.byte_chan.send(bytes); } } pub impl,P:BytePort> FlatPort { static fn new(u: U, p: P) -> FlatPort { FlatPort { - unflattener: move u, - byte_port: move p + unflattener: u, + byte_port: p } } } @@ -327,8 +327,8 @@ pub impl,P:BytePort> FlatPort { pub impl,C:ByteChan> FlatChan { static fn new(f: F, c: C) -> FlatChan { FlatChan { - flattener: move f, - byte_chan: move c + flattener: f, + byte_chan: c } } } @@ -358,7 +358,7 @@ pub mod flatteners { bogus: () } - pub impl PodUnflattener: Unflattener { + pub impl Unflattener for PodUnflattener { fn unflatten(&self, buf: ~[u8]) -> T { assert size_of::() != 0; assert size_of::() == buf.len(); @@ -368,7 +368,7 @@ pub mod flatteners { } } - pub impl PodFlattener: Flattener { + pub impl Flattener for PodFlattener { fn flatten(&self, val: T) -> ~[u8] { assert size_of::() != 0; let val: *T = ptr::to_unsafe_ptr(&val); @@ -377,7 +377,7 @@ pub mod flatteners { } } - pub impl PodUnflattener { + pub impl PodUnflattener { static fn new() -> PodUnflattener { PodUnflattener { bogus: () @@ -385,7 +385,7 @@ pub mod flatteners { } } - pub impl PodFlattener { + pub impl PodFlattener { static fn new() -> PodFlattener { PodFlattener { bogus: () @@ -406,38 +406,34 @@ pub mod flatteners { serialize_value: SerializeValue } - pub impl> - DeserializingUnflattener: Unflattener { + pub impl> Unflattener + for DeserializingUnflattener { fn unflatten(&self, buf: ~[u8]) -> T { (self.deserialize_buffer)(buf) } } - pub impl> - SerializingFlattener: Flattener { + pub impl> Flattener + for SerializingFlattener { fn flatten(&self, val: T) -> ~[u8] { (self.serialize_value)(&val) } } - pub impl> - DeserializingUnflattener { - - static fn new(deserialize_buffer: DeserializeBuffer - ) -> DeserializingUnflattener { + pub impl> DeserializingUnflattener { + static fn new(deserialize_buffer: DeserializeBuffer) + -> DeserializingUnflattener { DeserializingUnflattener { - deserialize_buffer: move deserialize_buffer + deserialize_buffer: deserialize_buffer } } } - pub impl> - SerializingFlattener { - - static fn new(serialize_value: SerializeValue - ) -> SerializingFlattener { + pub impl> SerializingFlattener { + static fn new(serialize_value: SerializeValue) + -> SerializingFlattener { SerializingFlattener { - serialize_value: move serialize_value + serialize_value: serialize_value } } } @@ -447,23 +443,23 @@ pub mod flatteners { SerializingFlattener */ - pub fn deserialize_buffer>(buf: &[u8]) -> T { + pub fn deserialize_buffer>(buf: &[u8]) -> T { let buf = vec::from_slice(buf); - let buf_reader = @BufReader::new(move buf); + let buf_reader = @BufReader::new(buf); let reader = buf_reader as @Reader; let deser: D = FromReader::from_reader(reader); Decodable::decode(&deser) } - pub fn serialize_value>(val: &T) -> ~[u8] { + pub fn serialize_value>(val: &T) -> ~[u8] { let bytes_writer = @BytesWriter(); let writer = bytes_writer as @Writer; let ser = FromWriter::from_writer(writer); val.encode(&ser); - let bytes = bytes_writer.bytes.check_out(|bytes| move bytes); - return move bytes; + let bytes = bytes_writer.bytes.check_out(|bytes| bytes); + return bytes; } pub trait FromReader { @@ -477,8 +473,8 @@ pub mod flatteners { impl FromReader for json::Decoder { static fn from_reader(r: Reader) -> json::Decoder { match json::from_reader(r) { - Ok(move json) => { - json::Decoder(move json) + Ok(json) => { + json::Decoder(json) } Err(e) => fail!(fmt!("flatpipe: can't parse json: %?", e)) } @@ -487,7 +483,7 @@ pub mod flatteners { impl FromWriter for json::Encoder { static fn from_writer(w: Writer) -> json::Encoder { - json::Encoder(move w) + json::Encoder(w) } } @@ -495,13 +491,13 @@ pub mod flatteners { static fn from_reader(r: Reader) -> ebml::reader::Decoder { let buf = @r.read_whole_stream(); let doc = ebml::reader::Doc(buf); - ebml::reader::Decoder(move doc) + ebml::reader::Decoder(doc) } } impl FromWriter for ebml::writer::Encoder { static fn from_writer(w: Writer) -> ebml::writer::Encoder { - ebml::writer::Encoder(move w) + ebml::writer::Encoder(w) } } @@ -511,7 +507,7 @@ pub mod bytepipes { use flatpipes::{ByteChan, BytePort}; use core::io::{Writer, Reader, ReaderUtil}; - use core::pipes::{Port, Chan}; + use core::comm::{Port, Chan}; use core::pipes; use core::prelude::*; @@ -523,7 +519,7 @@ pub mod bytepipes { writer: W } - pub impl ReaderBytePort: BytePort { + pub impl BytePort for ReaderBytePort { fn try_recv(&self, count: uint) -> Option<~[u8]> { let mut left = count; let mut bytes = ~[]; @@ -537,7 +533,7 @@ pub mod bytepipes { } if left == 0 { - return Some(move bytes); + return Some(bytes); } else { warn!("flatpipe: dropped %? broken bytes", left); return None; @@ -545,38 +541,38 @@ pub mod bytepipes { } } - pub impl WriterByteChan: ByteChan { + pub impl ByteChan for WriterByteChan { fn send(&self, val: ~[u8]) { self.writer.write(val); } } - pub impl ReaderBytePort { + pub impl ReaderBytePort { static fn new(r: R) -> ReaderBytePort { ReaderBytePort { - reader: move r + reader: r } } } - pub impl WriterByteChan { + pub impl WriterByteChan { static fn new(w: W) -> WriterByteChan { WriterByteChan { - writer: move w + writer: w } } } pub struct PipeBytePort { - port: pipes::Port<~[u8]>, + port: comm::Port<~[u8]>, mut buf: ~[u8] } pub struct PipeByteChan { - chan: pipes::Chan<~[u8]> + chan: comm::Chan<~[u8]> } - pub impl PipeBytePort: BytePort { + pub impl BytePort for PipeBytePort { fn try_recv(&self, count: uint) -> Option<~[u8]> { if self.buf.len() >= count { let mut bytes = ::core::util::replace(&mut self.buf, ~[]); @@ -587,17 +583,17 @@ pub mod bytepipes { let mut bytes = ::core::util::replace(&mut self.buf, ~[]); assert count > bytes.len(); match self.try_recv(count - bytes.len()) { - Some(move rest) => { + Some(rest) => { bytes.push_all(rest); - return Some(move bytes); + return Some(bytes); } None => return None } } else if self.buf.is_empty() { match self.port.try_recv() { - Some(move buf) => { + Some(buf) => { assert !buf.is_empty(); - self.buf = move buf; + self.buf = buf; return self.try_recv(count); } None => return None @@ -608,16 +604,16 @@ pub mod bytepipes { } } - pub impl PipeByteChan: ByteChan { + pub impl ByteChan for PipeByteChan { fn send(&self, val: ~[u8]) { - self.chan.send(move val) + self.chan.send(val) } } pub impl PipeBytePort { static fn new(p: Port<~[u8]>) -> PipeBytePort { PipeBytePort { - port: move p, + port: p, buf: ~[] } } @@ -626,7 +622,7 @@ pub mod bytepipes { pub impl PipeByteChan { static fn new(c: Chan<~[u8]>) -> PipeByteChan { PipeByteChan { - chan: move c + chan: c } } } @@ -661,14 +657,14 @@ mod test { #[test] fn test_serializing_memory_stream() { let writer = BytesWriter(); - let chan = serial::writer_chan(move writer); + let chan = serial::writer_chan(writer); chan.send(10); let bytes = chan.byte_chan.writer.bytes.get(); - let reader = BufReader::new(move bytes); - let port = serial::reader_port(move reader); + let reader = BufReader::new(bytes); + let port = serial::reader_port(reader); let res: int = port.recv(); assert res == 10i; @@ -678,7 +674,7 @@ mod test { fn test_serializing_pipes() { let (port, chan) = serial::pipe_stream(); - do task::spawn |move chan| { + do task::spawn || { for int::range(0, 10) |i| { chan.send(i) } @@ -693,7 +689,7 @@ mod test { fn test_serializing_boxes() { let (port, chan) = serial::pipe_stream(); - do task::spawn |move chan| { + do task::spawn || { for int::range(0, 10) |i| { chan.send(@i) } @@ -707,14 +703,14 @@ mod test { #[test] fn test_pod_memory_stream() { let writer = BytesWriter(); - let chan = pod::writer_chan(move writer); + let chan = pod::writer_chan(writer); chan.send(10); let bytes = chan.byte_chan.writer.bytes.get(); - let reader = BufReader::new(move bytes); - let port = pod::reader_port(move reader); + let reader = BufReader::new(bytes); + let port = pod::reader_port(reader); let res: int = port.recv(); assert res == 10; @@ -724,7 +720,7 @@ mod test { fn test_pod_pipes() { let (port, chan) = pod::pipe_stream(); - do task::spawn |move chan| { + do task::spawn || { for int::range(0, 10) |i| { chan.send(i) } @@ -741,11 +737,11 @@ mod test { fn test_pod_tcp_stream() { fn reader_port(buf: TcpSocketBuf ) -> pod::ReaderPort { - pod::reader_port(move buf) + pod::reader_port(buf) } fn writer_chan(buf: TcpSocketBuf ) -> pod::WriterChan { - pod::writer_chan(move buf) + pod::writer_chan(buf) } test_some_tcp_stream(reader_port, writer_chan, 9666); } @@ -755,11 +751,11 @@ mod test { fn test_serializing_tcp_stream() { fn reader_port(buf: TcpSocketBuf ) -> serial::ReaderPort { - serial::reader_port(move buf) + serial::reader_port(buf) } fn writer_chan(buf: TcpSocketBuf ) -> serial::WriterChan { - serial::writer_chan(move buf) + serial::writer_chan(buf) } test_some_tcp_stream(reader_port, writer_chan, 9667); } @@ -769,7 +765,7 @@ mod test { type WriterChanFactory = ~fn(TcpSocketBuf) -> FlatChan>; - fn test_some_tcp_stream, F: Flattener>( + fn test_some_tcp_stream,F:Flattener>( reader_port: ReaderPortFactory, writer_chan: WriterChanFactory, port: uint) { @@ -781,36 +777,34 @@ mod test { use uv; // Indicate to the client task that the server is listening - let (begin_connect_port, begin_connect_chan) = pipes::stream(); + let (begin_connect_port, begin_connect_chan) = comm::stream(); // The connection is sent from the server task to the receiver task // to handle the connection - let (accept_port, accept_chan) = pipes::stream(); + let (accept_port, accept_chan) = comm::stream(); // The main task will wait until the test is over to proceed - let (finish_port, finish_chan) = pipes::stream(); + let (finish_port, finish_chan) = comm::stream(); let addr0 = ip::v4::parse_addr("127.0.0.1"); - let begin_connect_chan = Cell(move begin_connect_chan); - let accept_chan = Cell(move accept_chan); + let begin_connect_chan = Cell(begin_connect_chan); + let accept_chan = Cell(accept_chan); // The server task let addr = copy addr0; - do task::spawn |move begin_connect_chan, - move accept_chan| { + do task::spawn || { let iotask = &uv::global_loop::get(); let begin_connect_chan = begin_connect_chan.take(); let accept_chan = accept_chan.take(); let listen_res = do tcp::listen( - copy addr, port, 128, iotask, - |move begin_connect_chan, _kill_ch| { + copy addr, port, 128, iotask, |_kill_ch| { // Tell the sender to initiate the connection debug!("listening"); begin_connect_chan.send(()) - }) |move accept_chan, new_conn, kill_ch| { + }) |new_conn, kill_ch| { // Incoming connection. Send it to the receiver task to accept - let (res_port, res_chan) = pipes::stream(); - accept_chan.send((move new_conn, move res_chan)); + let (res_port, res_chan) = comm::stream(); + accept_chan.send((new_conn, res_chan)); // Wait until the connection is accepted res_port.recv(); @@ -823,8 +817,7 @@ mod test { // Client task let addr = copy addr0; - do task::spawn |move begin_connect_port, - move writer_chan| { + do task::spawn || { // Wait for the server to start listening begin_connect_port.recv(); @@ -833,11 +826,11 @@ mod test { let iotask = &uv::global_loop::get(); let connect_result = tcp::connect(copy addr, port, iotask); assert connect_result.is_ok(); - let sock = result::unwrap(move connect_result); - let socket_buf: tcp::TcpSocketBuf = tcp::socket_buf(move sock); + let sock = result::unwrap(connect_result); + let socket_buf: tcp::TcpSocketBuf = tcp::socket_buf(sock); // TcpSocketBuf is a Writer! - let chan = writer_chan(move socket_buf); + let chan = writer_chan(socket_buf); for int::range(0, 10) |i| { debug!("sending %?", i); @@ -846,9 +839,7 @@ mod test { } // Reciever task - do task::spawn |move accept_port, move finish_chan, - move reader_port| { - + do task::spawn || { // Wait for a connection let (conn, res_chan) = accept_port.recv(); @@ -856,13 +847,13 @@ mod test { let accept_result = tcp::accept(conn); debug!("accepted"); assert accept_result.is_ok(); - let sock = result::unwrap(move accept_result); + let sock = result::unwrap(accept_result); res_chan.send(()); - let socket_buf: tcp::TcpSocketBuf = tcp::socket_buf(move sock); + let socket_buf: tcp::TcpSocketBuf = tcp::socket_buf(sock); // TcpSocketBuf is a Reader! - let port = reader_port(move socket_buf); + let port = reader_port(socket_buf); for int::range(0, 10) |i| { let j = port.recv(); @@ -897,22 +888,22 @@ mod test { fn reader_port_loader(bytes: ~[u8] ) -> pod::ReaderPort { - let reader = BufReader::new(move bytes); - pod::reader_port(move reader) + let reader = BufReader::new(bytes); + pod::reader_port(reader) } fn pipe_port_loader(bytes: ~[u8] ) -> pod::PipePort { - let (port, chan) = pipes::stream(); + let (port, chan) = comm::stream(); if !bytes.is_empty() { - chan.send(move bytes); + chan.send(bytes); } - pod::pipe_port(move port) + pod::pipe_port(port) } - fn test_try_recv_none1(loader: PortLoader

) { + fn test_try_recv_none1(loader: PortLoader

) { let bytes = ~[]; - let port = loader(move bytes); + let port = loader(bytes); let res: Option = port.try_recv(); assert res.is_none(); } @@ -926,10 +917,10 @@ mod test { test_try_recv_none1(pipe_port_loader); } - fn test_try_recv_none2(loader: PortLoader

) { + fn test_try_recv_none2(loader: PortLoader

) { // The control word in the protocol is interrupted let bytes = ~[0]; - let port = loader(move bytes); + let port = loader(bytes); let res: Option = port.try_recv(); assert res.is_none(); } @@ -943,11 +934,11 @@ mod test { test_try_recv_none2(pipe_port_loader); } - fn test_try_recv_none3(loader: PortLoader

) { + fn test_try_recv_none3(loader: PortLoader

) { const CONTINUE: [u8 * 4] = [0xAA, 0xBB, 0xCC, 0xDD]; // The control word is followed by garbage let bytes = CONTINUE.to_vec() + ~[0]; - let port = loader(move bytes); + let port = loader(bytes); let res: Option = port.try_recv(); assert res.is_none(); } @@ -961,8 +952,8 @@ mod test { test_try_recv_none3(pipe_port_loader); } - fn test_try_recv_none4(+loader: PortLoader

) { - assert do task::try |move loader| { + fn test_try_recv_none4(+loader: PortLoader

) { + assert do task::try || { const CONTINUE: [u8 * 4] = [0xAA, 0xBB, 0xCC, 0xDD]; // The control word is followed by a valid length, // then undeserializable garbage @@ -972,7 +963,7 @@ mod test { }; let bytes = CONTINUE.to_vec() + len_bytes + ~[0, 0, 0, 0]; - let port = loader(move bytes); + let port = loader(bytes); let _res: Option = port.try_recv(); }.is_err(); diff --git a/src/libstd/fun_treemap.rs b/src/libstd/fun_treemap.rs index d6c2cf5a265ee..0729987958a06 100644 --- a/src/libstd/fun_treemap.rs +++ b/src/libstd/fun_treemap.rs @@ -34,7 +34,7 @@ enum TreeNode { pub fn init() -> Treemap { @Empty } /// Insert a value into the map -pub fn insert(m: Treemap, k: K, v: V) +pub fn insert(m: Treemap, k: K, v: V) -> Treemap { @match m { @Empty => Node(@k, @v, @Empty, @Empty), @@ -49,13 +49,13 @@ pub fn insert(m: Treemap, k: K, v: V) } /// Find a value based on the key -pub fn find(m: Treemap, k: K) -> Option { +pub fn find(m: Treemap, k: K) -> Option { match *m { Empty => None, Node(@ref kk, @copy v, left, right) => { if k == *kk { Some(v) - } else if k < *kk { find(left, move k) } else { find(right, move k) } + } else if k < *kk { find(left, k) } else { find(right, k) } } } } diff --git a/src/libstd/future.rs b/src/libstd/future.rs index 8659e3cbb102c..b6b001727a45a 100644 --- a/src/libstd/future.rs +++ b/src/libstd/future.rs @@ -25,7 +25,8 @@ use core::cast::copy_lifetime; use core::cast; use core::either::Either; use core::option; -use core::pipes::{recv, oneshot, ChanOne, PortOne, send_one, recv_one}; +use core::comm::{oneshot, ChanOne, PortOne, send_one, recv_one}; +use core::pipes::recv; use core::prelude::*; use core::task; @@ -71,10 +72,10 @@ impl Future { let mut state = Evaluating; self.state <-> state; - match move state { + match state { Forced(_) | Evaluating => fail!(~"Logic error."), - Pending(move f) => { - self.state = Forced(move f()); + Pending(f) => { + self.state = Forced(f()); self.get_ref() } } @@ -90,7 +91,7 @@ pub fn from_value(val: A) -> Future { * not block. */ - Future {state: Forced(move val)} + Future {state: Forced(val)} } pub fn from_port(port: PortOne) -> @@ -102,13 +103,13 @@ pub fn from_port(port: PortOne) -> * waiting for the result to be received on the port. */ - let port = ~mut Some(move port); - do from_fn |move port| { + let port = ~mut Some(port); + do from_fn || { let mut port_ = None; port_ <-> *port; - let port = option::unwrap(move port_); - match recv(move port) { - oneshot::send(move data) => move data + let port = option::unwrap(port_); + match recv(port) { + oneshot::send(data) => data } } } @@ -122,7 +123,7 @@ pub fn from_fn(f: ~fn() -> A) -> Future { * function. It is not spawned into another task. */ - Future {state: Pending(move f)} + Future {state: Pending(f)} } pub fn spawn(blk: fn~() -> A) -> Future { @@ -135,13 +136,13 @@ pub fn spawn(blk: fn~() -> A) -> Future { let (chan, port) = oneshot::init(); - let chan = ~mut Some(move chan); - do task::spawn |move blk, move chan| { + let chan = ~mut Some(chan); + do task::spawn || { let chan = option::swap_unwrap(&mut *chan); - send_one(move chan, blk()); + send_one(chan, blk()); } - return from_port(move port); + return from_port(port); } #[allow(non_implicitly_copyable_typarams)] @@ -150,7 +151,7 @@ pub mod test { use future::*; - use core::pipes::oneshot; + use core::comm::oneshot; use core::task; #[test] @@ -162,8 +163,8 @@ pub mod test { #[test] pub fn test_from_port() { let (ch, po) = oneshot::init(); - send_one(move ch, ~"whale"); - let f = from_port(move po); + send_one(ch, ~"whale"); + let f = from_port(po); assert f.get() == ~"whale"; } @@ -202,8 +203,8 @@ pub mod test { #[test] pub fn test_sendable_future() { let expected = ~"schlorf"; - let f = do spawn |copy expected| { copy expected }; - do task::spawn |move f, move expected| { + let f = do spawn { copy expected }; + do task::spawn || { let actual = f.get(); assert actual == expected; } diff --git a/src/libstd/getopts.rs b/src/libstd/getopts.rs index 3d6d0b1bb7d6b..3726943321c35 100644 --- a/src/libstd/getopts.rs +++ b/src/libstd/getopts.rs @@ -35,7 +35,7 @@ * fn do_work(in: &str, out: Option<~str>) { * io::println(in); * io::println(match out { - * Some(move x) => x, + * Some(x) => x, * None => ~"No Output" * }); * } @@ -339,7 +339,7 @@ pub fn getopts(args: &[~str], opts: &[Opt]) -> Result { i += 1; } return Ok(Matches {opts: vec::from_slice(opts), - vals: move vals, + vals: vals, free: free}); } } @@ -1178,7 +1178,7 @@ mod tests { let args = ~[~"-e", ~"foo", ~"--encrypt", ~"foo"]; let opts = ~[optopt(~"e"), optopt(~"encrypt")]; let matches = &match getopts(args, opts) { - result::Ok(move m) => m, + result::Ok(m) => m, result::Err(_) => fail!() }; assert opts_present(matches, ~[~"e"]); @@ -1199,7 +1199,7 @@ mod tests { let args = ~[~"-Lfoo", ~"-M."]; let opts = ~[optmulti(~"L"), optmulti(~"M")]; let matches = &match getopts(args, opts) { - result::Ok(move m) => m, + result::Ok(m) => m, result::Err(_) => fail!() }; assert opts_present(matches, ~[~"L"]); diff --git a/src/libstd/io_util.rs b/src/libstd/io_util.rs index 3cc28563e12eb..b1c6e2d44e572 100644 --- a/src/libstd/io_util.rs +++ b/src/libstd/io_util.rs @@ -20,7 +20,7 @@ pub struct BufReader { pub impl BufReader { static pub fn new(v: ~[u8]) -> BufReader { BufReader { - buf: move v, + buf: v, pos: 0 } } @@ -38,7 +38,7 @@ pub impl BufReader { // FIXME #4429: This isn't correct if f fails self.pos = bytes_reader.pos; - return move res; + return res; } } diff --git a/src/libstd/json.rs b/src/libstd/json.rs index fcdd2de5743a3..d16b1282c7c0b 100644 --- a/src/libstd/json.rs +++ b/src/libstd/json.rs @@ -82,7 +82,7 @@ pub fn Encoder(wr: io::Writer) -> Encoder { Encoder { wr: wr } } -pub impl Encoder: serialize::Encoder { +pub impl serialize::Encoder for Encoder { fn emit_nil(&self) { self.wr.write_str("null") } fn emit_uint(&self, v: uint) { self.emit_float(v as float); } @@ -217,7 +217,7 @@ pub fn PrettyEncoder(wr: io::Writer) -> PrettyEncoder { PrettyEncoder { wr: wr, indent: 0 } } -pub impl PrettyEncoder: serialize::Encoder { +pub impl serialize::Encoder for PrettyEncoder { fn emit_nil(&self) { self.wr.write_str("null") } fn emit_uint(&self, v: uint) { self.emit_float(v as float); } @@ -323,7 +323,7 @@ pub impl PrettyEncoder: serialize::Encoder { } } -pub impl Json: serialize::Encodable { +pub impl serialize::Encodable for Json { fn encode(&self, s: &S) { match *self { Number(v) => v.encode(s), @@ -388,18 +388,18 @@ pub fn Parser(rdr: io::Reader) -> Parser { pub impl Parser { fn parse() -> Result { - match move self.parse_value() { - Ok(move value) => { + match self.parse_value() { + Ok(value) => { // Skip trailing whitespaces. self.parse_whitespace(); // Make sure there is no trailing characters. if self.eof() { - Ok(move value) + Ok(value) } else { self.error(~"trailing characters") } } - Err(move e) => Err(e) + Err(e) => Err(e) } } } @@ -438,9 +438,9 @@ priv impl Parser { 'f' => self.parse_ident(~"alse", Boolean(false)), '0' .. '9' | '-' => self.parse_number(), '"' => - match move self.parse_str() { - Ok(move s) => Ok(String(s)), - Err(move e) => Err(e), + match self.parse_str() { + Ok(s) => Ok(String(s)), + Err(e) => Err(e), }, '[' => self.parse_list(), '{' => self.parse_object(), @@ -455,7 +455,7 @@ priv impl Parser { fn parse_ident(ident: &str, value: Json) -> Result { if str::all(ident, |c| c == self.next_char()) { self.bump(); - Ok(move value) + Ok(value) } else { self.error(~"invalid syntax") } @@ -662,13 +662,13 @@ priv impl Parser { if self.ch == ']' { self.bump(); - return Ok(List(move values)); + return Ok(List(values)); } loop { - match move self.parse_value() { - Ok(move v) => values.push(move v), - Err(move e) => return Err(e) + match self.parse_value() { + Ok(v) => values.push(v), + Err(e) => return Err(e) } self.parse_whitespace(); @@ -678,7 +678,7 @@ priv impl Parser { match self.ch { ',' => self.bump(), - ']' => { self.bump(); return Ok(List(move values)); } + ']' => { self.bump(); return Ok(List(values)); } _ => return self.error(~"expected `,` or `]`") } }; @@ -692,7 +692,7 @@ priv impl Parser { if self.ch == '}' { self.bump(); - return Ok(Object(move values)); + return Ok(Object(values)); } while !self.eof() { @@ -702,9 +702,9 @@ priv impl Parser { return self.error(~"key must be a string"); } - let key = match move self.parse_str() { - Ok(move key) => key, - Err(move e) => return Err(e) + let key = match self.parse_str() { + Ok(key) => key, + Err(e) => return Err(e) }; self.parse_whitespace(); @@ -715,15 +715,15 @@ priv impl Parser { } self.bump(); - match move self.parse_value() { - Ok(move value) => { values.insert(key, move value); } - Err(move e) => return Err(e) + match self.parse_value() { + Ok(value) => { values.insert(key, value); } + Err(e) => return Err(e) } self.parse_whitespace(); match self.ch { ',' => self.bump(), - '}' => { self.bump(); return Ok(Object(move values)); } + '}' => { self.bump(); return Ok(Object(values)); } _ => { if self.eof() { break; } return self.error(~"expected `,` or `}`"); @@ -753,7 +753,7 @@ pub struct Decoder { } pub fn Decoder(json: Json) -> Decoder { - Decoder { json: move json, stack: ~[] } + Decoder { json: json, stack: ~[] } } priv impl Decoder { @@ -768,7 +768,7 @@ priv impl Decoder { } } -pub impl Decoder: serialize::Decoder { +pub impl serialize::Decoder for Decoder { fn read_nil(&self) -> () { debug!("read_nil"); match *self.pop() { @@ -868,7 +868,7 @@ pub impl Decoder: serialize::Decoder { }; let res = f(len); self.pop(); - move res + res } fn read_managed_vec(&self, f: fn(uint) -> T) -> T { @@ -879,7 +879,7 @@ pub impl Decoder: serialize::Decoder { }; let res = f(len); self.pop(); - move res + res } fn read_vec_elt(&self, idx: uint, f: fn() -> T) -> T { @@ -897,14 +897,14 @@ pub impl Decoder: serialize::Decoder { debug!("read_rec()"); let value = f(); self.pop(); - move value + value } fn read_struct(&self, _name: &str, _len: uint, f: fn() -> T) -> T { debug!("read_struct()"); let value = f(); self.pop(); - move value + value } fn read_field(&self, name: &str, idx: uint, f: fn() -> T) -> T { @@ -934,7 +934,7 @@ pub impl Decoder: serialize::Decoder { debug!("read_tup(len=%u)", len); let value = f(); self.pop(); - move value + value } fn read_tup_elt(&self, idx: uint, f: fn() -> T) -> T { @@ -1150,7 +1150,7 @@ impl ToJson for @~str { fn to_json() -> Json { String(copy *self) } } -impl ToJson for (A, B) { +impl ToJson for (A, B) { fn to_json() -> Json { match self { (ref a, ref b) => { @@ -1160,7 +1160,7 @@ impl ToJson for (A, B) { } } -impl ToJson for (A, B, C) { +impl ToJson for (A, B, C) { fn to_json() -> Json { match self { (ref a, ref b, ref c) => { @@ -1170,11 +1170,11 @@ impl ToJson for (A, B, C) { } } -impl ToJson for ~[A] { +impl ToJson for ~[A] { fn to_json() -> Json { List(self.map(|elt| elt.to_json())) } } -impl ToJson for LinearMap<~str, A> { +impl ToJson for LinearMap<~str, A> { fn to_json() -> Json { let mut d = LinearMap::new(); for self.each |&(key, value)| { @@ -1184,7 +1184,7 @@ impl ToJson for LinearMap<~str, A> { } } -impl ToJson for Option { +impl ToJson for Option { fn to_json() -> Json { match self { None => Null, @@ -1219,11 +1219,11 @@ mod tests { for items.each |item| { match *item { - (copy key, copy value) => { d.insert(key, move value); }, + (copy key, copy value) => { d.insert(key, value); }, } }; - Object(move d) + Object(d) } #[test] @@ -1282,23 +1282,21 @@ mod tests { // 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) { + pub pure fn check_equal_ptr (given : &T, expected: &T) { if !((given == expected) && (expected == given )) { - die!(fmt!("given %?, expected %?",given,expected)); + fail!(fmt!("given %?, expected %?",given,expected)); } } - pub pure fn check_equal (given : T, expected: T) { + pub pure fn check_equal (given : T, expected: T) { if !((given == expected) && (expected == given )) { - die!(fmt!("given %?, expected %?",given,expected)); + fail!(fmt!("given %?, expected %?",given,expected)); } } - // testing both auto_encode's calling patterns - // and json... not sure where to put these tests. #[test] fn test_write_enum () { - let bw = @io::BytesWriter {bytes: dvec::DVec(), pos: 0}; + let bw = @io::BytesWriter(); let bww : @io::Writer = (bw as @io::Writer); let encoder = (@Encoder(bww) as @serialize::Encoder); do encoder.emit_enum(~"animal") { @@ -1319,7 +1317,7 @@ mod tests { #[test] fn test_write_some () { - let bw = @io::BytesWriter {bytes: dvec::DVec(), pos: 0}; + let bw = @io::BytesWriter(); let bww : @io::Writer = (bw as @io::Writer); let encoder = (@Encoder(bww) as @serialize::Encoder); do encoder.emit_enum(~"Option") { @@ -1335,7 +1333,7 @@ mod tests { #[test] fn test_write_none () { - let bw = @io::BytesWriter {bytes: dvec::DVec(), pos: 0}; + let bw = @io::BytesWriter(); let bww : @io::Writer = (bw as @io::Writer); let encoder = (@Encoder(bww) as @serialize::Encoder); do encoder.emit_enum(~"Option") { diff --git a/src/libstd/list.rs b/src/libstd/list.rs index 5feac4ad454cd..f6cbd9a099b6a 100644 --- a/src/libstd/list.rs +++ b/src/libstd/list.rs @@ -23,7 +23,7 @@ pub enum List { } /// Create a list from a vector -pub pure fn from_vec(v: &[T]) -> @List { +pub pure fn from_vec(v: &[T]) -> @List { vec::foldr(v, @Nil::, |h, t| @Cons(*h, t)) } @@ -40,7 +40,7 @@ pub pure fn from_vec(v: &[T]) -> @List { * * z - The initial value * * f - The function to apply */ -pub fn foldl(z: T, ls: @List, f: fn(&T, &U) -> T) -> T { +pub fn foldl(z: T, ls: @List, f: fn(&T, &U) -> T) -> T { let mut accum: T = z; do iter(ls) |elt| { accum = f(&accum, elt);} accum @@ -53,7 +53,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 pure fn find(ls: @List, f: fn(&T) -> bool) -> Option { let mut ls = ls; loop { ls = match *ls { @@ -67,7 +67,7 @@ pub pure fn find(ls: @List, f: fn(&T) -> bool) -> Option { } /// Returns true if a list contains an element with the given value -pub fn has(ls: @List, elt: T) -> bool { +pub fn has(ls: @List, elt: T) -> bool { for each(ls) |e| { if *e == elt { return true; } } @@ -75,7 +75,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 pure fn is_empty(ls: @List) -> bool { match *ls { Nil => true, _ => false @@ -90,7 +90,7 @@ pub pure fn len(ls: @List) -> uint { } /// Returns all but the first element of a list -pub pure fn tail(ls: @List) -> @List { +pub pure fn tail(ls: @List) -> @List { match *ls { Cons(_, tl) => return tl, Nil => fail!(~"list empty") @@ -98,7 +98,7 @@ pub pure fn tail(ls: @List) -> @List { } /// Returns the first element of a list -pub pure fn head(ls: @List) -> T { +pub pure fn head(ls: @List) -> T { match *ls { Cons(copy hd, _) => hd, // makes me sad @@ -107,7 +107,7 @@ pub pure fn head(ls: @List) -> T { } /// Appends one list to another -pub pure fn append(l: @List, m: @List) -> @List { +pub pure fn append(l: @List, m: @List) -> @List { match *l { Nil => return m, Cons(copy x, xs) => { @@ -120,7 +120,7 @@ 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) { +pure fn push(ll: &mut @list, vv: T) { ll = &mut @cons(vv, *ll) } */ diff --git a/src/libstd/net_ip.rs b/src/libstd/net_ip.rs index 88bacf53e636b..bc17cb0bfe9b6 100644 --- a/src/libstd/net_ip.rs +++ b/src/libstd/net_ip.rs @@ -12,7 +12,7 @@ use core::libc; use core::prelude::*; -use core::pipes::{stream, SharedChan}; +use core::comm::{stream, SharedChan}; use core::ptr; use core::result; use core::str; @@ -181,7 +181,7 @@ pub mod v4 { */ pub fn parse_addr(ip: &str) -> IpAddr { match try_parse_addr(ip) { - result::Ok(move addr) => move addr, + result::Ok(addr) => addr, result::Err(ref err_data) => fail!(err_data.err_msg) } } @@ -276,7 +276,7 @@ pub mod v6 { */ pub fn parse_addr(ip: &str) -> IpAddr { match try_parse_addr(ip) { - result::Ok(move addr) => move addr, + result::Ok(addr) => addr, result::Err(copy err_data) => fail!(err_data.err_msg) } } @@ -331,7 +331,7 @@ extern fn get_addr_cb(handle: *uv_getaddrinfo_t, status: libc::c_int, result::Err(GetAddrUnknownError)); break; }; - out_vec.push(move new_ip_addr); + out_vec.push(new_ip_addr); let next_addr = ll::get_next_addrinfo(curr_addr); if next_addr == ptr::null::() as *addrinfo { @@ -345,7 +345,7 @@ extern fn get_addr_cb(handle: *uv_getaddrinfo_t, status: libc::c_int, } log(debug, fmt!("successful process addrinfo result, len: %?", vec::len(out_vec))); - output_ch.send(result::Ok(move out_vec)); + output_ch.send(result::Ok(out_vec)); } else { log(debug, ~"addrinfo pointer is NULL"); @@ -427,7 +427,7 @@ mod test { } // note really sure how to realiably test/assert // this.. mostly just wanting to see it work, atm. - let results = result::unwrap(move ga_result); + let results = result::unwrap(ga_result); log(debug, fmt!("test_get_addr: Number of results for %s: %?", localhost_name, vec::len(results))); for vec::each(results) |r| { diff --git a/src/libstd/net_tcp.rs b/src/libstd/net_tcp.rs index 4e0b5494883b0..8835cdfb105eb 100644 --- a/src/libstd/net_tcp.rs +++ b/src/libstd/net_tcp.rs @@ -24,7 +24,7 @@ use core::io::{Reader, ReaderUtil, Writer}; use core::io; use core::libc::size_t; use core::libc; -use core::pipes::{stream, Chan, Port, SharedChan}; +use core::comm::{stream, Chan, Port, SharedChan}; use core::prelude::*; use core::ptr; use core::result::{Result}; @@ -177,7 +177,7 @@ pub fn connect(input_ip: ip::IpAddr, port: uint, // we can send into the interact cb to be handled in libuv.. debug!("stream_handle_ptr outside interact %?", stream_handle_ptr); - do iotask::interact(iotask) |move input_ip, loop_ptr| { + do iotask::interact(iotask) |loop_ptr| { unsafe { debug!("in interact cb for tcp client connect.."); debug!("stream_handle_ptr in interact %?", @@ -629,10 +629,10 @@ pub fn listen(host_ip: ip::IpAddr, port: uint, backlog: uint, new_connect_cb: fn~(TcpNewConnection, SharedChan>)) -> result::Result<(), TcpListenErrData> { - do listen_common(move host_ip, port, backlog, iotask, - move on_establish_cb) + do listen_common(host_ip, port, backlog, iotask, + on_establish_cb) // on_connect_cb - |move new_connect_cb, handle| { + |handle| { unsafe { let server_data_ptr = uv::ll::get_data_for_uv_handle(handle) as *TcpListenFcData; @@ -659,7 +659,7 @@ fn listen_common(host_ip: ip::IpAddr, port: uint, backlog: uint, server_stream_ptr: server_stream_ptr, stream_closed_ch: stream_closed_ch, kill_ch: kill_ch.clone(), - on_connect_cb: move on_connect_cb, + on_connect_cb: on_connect_cb, iotask: iotask.clone(), ipv6: match &host_ip { &ip::Ipv4(_) => { false } @@ -678,7 +678,7 @@ fn listen_common(host_ip: ip::IpAddr, port: uint, backlog: uint, // tcp::connect (because the iotask::interact cb isn't // nested within a core::comm::listen block) let loc_ip = copy(host_ip); - do iotask::interact(iotask) |move loc_ip, loop_ptr| { + do iotask::interact(iotask) |loop_ptr| { unsafe { match uv::ll::tcp_init(loop_ptr, server_stream_ptr) { 0i32 => { @@ -815,7 +815,7 @@ fn listen_common(host_ip: ip::IpAddr, port: uint, backlog: uint, */ pub fn socket_buf(sock: TcpSocket) -> TcpSocketBuf { TcpSocketBuf(@TcpBufferedSocketData { - sock: move sock, mut buf: ~[], buf_off: 0 + sock: sock, mut buf: ~[], buf_off: 0 }) } @@ -851,12 +851,12 @@ impl TcpSocket { let addr = uv::ll::ip6_addr("", 0); uv::ll::tcp_getpeername6(self.socket_data.stream_handle_ptr, ptr::addr_of(&addr)); - ip::Ipv6(move addr) + ip::Ipv6(addr) } else { let addr = uv::ll::ip4_addr("", 0); uv::ll::tcp_getpeername(self.socket_data.stream_handle_ptr, ptr::addr_of(&addr)); - ip::Ipv4(move addr) + ip::Ipv4(addr) } } } @@ -971,7 +971,8 @@ impl io::Writer for TcpSocketBuf { let w_result = write_common_impl(socket_data_ptr, vec::slice(data, 0, - vec::len(data))); + vec::len(data) + ).to_vec()); if w_result.is_err() { let err_data = w_result.get_err(); log(debug, @@ -1047,7 +1048,7 @@ fn read_common_impl(socket_data: *TcpSocketData, timeout_msecs: uint) Some(result::get(&rs_result).recv()) }; log(debug, ~"tcp::read after recv_timeout"); - match move read_result { + match read_result { None => { log(debug, ~"tcp::read: timed out.."); let err_data = TcpErrData { @@ -1057,7 +1058,7 @@ fn read_common_impl(socket_data: *TcpSocketData, timeout_msecs: uint) read_stop_common_impl(socket_data); result::Err(err_data) } - Some(move data_result) => { + Some(data_result) => { log(debug, ~"tcp::read got data"); read_stop_common_impl(socket_data); data_result @@ -1091,7 +1092,7 @@ fn read_stop_common_impl(socket_data: *TcpSocketData) -> } } match stop_po.recv() { - Some(move err_data) => Err(err_data), + Some(err_data) => Err(err_data), None => Ok(()) } } @@ -1183,7 +1184,7 @@ fn write_common_impl(socket_data_ptr: *TcpSocketData, // aftermath, so we don't have to sit here blocking. match result_po.recv() { TcpWriteSuccess => Ok(()), - TcpWriteError(move err_data) => Err(err_data) + TcpWriteError(err_data) => Err(err_data) } } } @@ -1440,7 +1441,7 @@ pub mod test { use uv; use core::io; - use core::pipes::{stream, Chan, Port, SharedChan}; + use core::comm::{stream, Chan, Port, SharedChan}; use core::prelude::*; use core::result; use core::str; @@ -1613,10 +1614,10 @@ pub mod test { debug!("server started, firing up client.."); let server_ip_addr = ip::v4::parse_addr(server_ip); let iotask = uv::global_loop::get(); - let connect_result = connect(move server_ip_addr, server_port, + let connect_result = connect(server_ip_addr, server_port, &iotask); - let sock = result::unwrap(move connect_result); + let sock = result::unwrap(connect_result); debug!("testing peer address"); // This is what we are actually testing! @@ -1784,11 +1785,11 @@ pub mod test { // client debug!("server started, firing up client.."); let server_addr = ip::v4::parse_addr(server_ip); - let conn_result = connect(move server_addr, server_port, hl_loop); + let conn_result = connect(server_addr, server_port, hl_loop); if result::is_err(&conn_result) { assert false; } - let sock_buf = @socket_buf(result::unwrap(move conn_result)); + let sock_buf = @socket_buf(result::unwrap(conn_result)); buf_write(sock_buf, expected_req); let buf_reader = sock_buf as Reader; @@ -1819,7 +1820,7 @@ pub mod test { let (server_po, server_ch) = stream::<~str>(); let server_ch = SharedChan(server_ch); let server_ip_addr = ip::v4::parse_addr(server_ip); - let listen_result = listen(move server_ip_addr, server_port, 128, + let listen_result = listen(server_ip_addr, server_port, 128, iotask, // on_establish_cb -- called when listener is set up |kill_ch| { @@ -1849,15 +1850,15 @@ pub mod test { else { debug!("SERVER/WORKER: send on cont ch"); cont_ch.send(()); - let sock = result::unwrap(move accept_result); + let sock = result::unwrap(accept_result); let peer_addr = sock.get_peer_addr(); debug!("SERVER: successfully accepted \ connection from %s:%u", ip::format_addr(&peer_addr), ip::get_port(&peer_addr)); let received_req_bytes = read(&sock, 0u); - match move received_req_bytes { - result::Ok(move data) => { + match received_req_bytes { + result::Ok(data) => { debug!("SERVER: got REQ str::from_bytes.."); debug!("SERVER: REQ data len: %?", vec::len(data)); @@ -1868,7 +1869,7 @@ pub mod test { debug!("SERVER: after write.. die"); kill_ch.send(None); } - result::Err(move err_data) => { + result::Err(err_data) => { debug!("SERVER: error recvd: %s %s", err_data.err_name, err_data.err_msg); kill_ch.send(Some(err_data)); @@ -1904,7 +1905,7 @@ pub mod test { fn run_tcp_test_server_fail(server_ip: &str, server_port: uint, iotask: &IoTask) -> TcpListenErrData { let server_ip_addr = ip::v4::parse_addr(server_ip); - let listen_result = listen(move server_ip_addr, server_port, 128, + let listen_result = listen(server_ip_addr, server_port, 128, iotask, // on_establish_cb -- called when listener is set up |kill_ch| { @@ -1929,7 +1930,7 @@ pub mod test { let server_ip_addr = ip::v4::parse_addr(server_ip); debug!("CLIENT: starting.."); - let connect_result = connect(move server_ip_addr, server_port, + let connect_result = connect(server_ip_addr, server_port, iotask); if result::is_err(&connect_result) { debug!("CLIENT: failed to connect"); @@ -1937,7 +1938,7 @@ pub mod test { Err(err_data) } else { - let sock = result::unwrap(move connect_result); + let sock = result::unwrap(connect_result); let resp_bytes = str::to_bytes(resp); tcp_write_single(&sock, resp_bytes); let read_result = sock.read(0u); diff --git a/src/libstd/net_url.rs b/src/libstd/net_url.rs index 7874899cb27ac..29cb57c01be45 100644 --- a/src/libstd/net_url.rs +++ b/src/libstd/net_url.rs @@ -253,7 +253,7 @@ pub fn decode_form_urlencoded(s: &[u8]) -> LinearMap<~str, ~[~str]> { '&' | ';' => { if key != ~"" && value != ~"" { let mut values = match m.pop(&key) { - Some(move values) => values, + Some(values) => values, None => ~[], }; @@ -287,7 +287,7 @@ pub fn decode_form_urlencoded(s: &[u8]) -> LinearMap<~str, ~[~str]> { if key != ~"" && value != ~"" { let mut values = match m.pop(&key) { - Some(move values) => values, + Some(values) => values, None => ~[], }; @@ -671,7 +671,7 @@ pub pure fn from_str(rawurl: &str) -> Result { impl FromStr for Url { static pure fn from_str(s: &str) -> Option { match from_str(s) { - Ok(move url) => Some(url), + Ok(url) => Some(url), Err(_) => None } } diff --git a/src/libstd/oldmap.rs b/src/libstd/oldmap.rs index 3ad45cf2d5b30..53692cd3be570 100644 --- a/src/libstd/oldmap.rs +++ b/src/libstd/oldmap.rs @@ -76,7 +76,7 @@ pub mod chained { FoundAfter(@Entry, @Entry) } - priv impl T { + priv impl T { pure fn search_rem(k: &K, h: uint, idx: uint, e_root: @Entry) -> SearchResult { let mut e0 = e_root; @@ -132,7 +132,7 @@ pub mod chained { entry.next = new_chains[idx]; new_chains[idx] = Some(entry); } - self.chains = move new_chains; + self.chains = new_chains; } pure fn each_entry(blk: fn(@Entry) -> bool) { @@ -156,19 +156,19 @@ pub mod chained { } } - impl Container for T { + impl Container for T { pure fn len(&self) -> uint { self.count } pure fn is_empty(&self) -> bool { self.count == 0 } } - impl Mutable for T { + impl Mutable for T { fn clear(&mut self) { self.count = 0u; self.chains = chains(initial_capacity); } } - impl T { + impl T { pure fn contains_key(&self, k: &K) -> bool { let hash = k.hash_keyed(0,0) as uint; match self.search_tbl(k, hash) { @@ -252,7 +252,7 @@ pub mod chained { } } - impl T { + impl T { pure fn find(&self, k: &K) -> Option { match self.search_tbl(k, k.hash_keyed(0,0) as uint) { NotFound => None, @@ -321,11 +321,11 @@ pub mod chained { if opt_v.is_none() { fail!(fmt!("Key not found in table: %?", k)); } - option::unwrap(move opt_v) + option::unwrap(opt_v) } } - impl T { + impl T { fn to_writer(wr: io::Writer) { if self.count == 0u { wr.write_str(~"{}"); @@ -347,7 +347,8 @@ pub mod chained { } } - impl ToStr for T { + impl ToStr + for T { pure fn to_str(&self) -> ~str { unsafe { // Meh -- this should be safe @@ -356,7 +357,7 @@ pub mod chained { } } - impl ops::Index for T { + impl ops::Index for T { pure fn index(&self, k: K) -> V { self.get(&k) } @@ -366,7 +367,7 @@ pub mod chained { vec::from_elem(nchains, None) } - pub fn mk() -> T { + pub fn mk() -> T { let slf: T = @HashMap_ {count: 0u, chains: chains(initial_capacity)}; slf @@ -378,18 +379,19 @@ Function: hashmap Construct a hashmap. */ -pub fn HashMap() +pub fn HashMap() -> HashMap { chained::mk() } /// Convenience function for adding keys to a hashmap with nil type keys -pub fn set_add(set: Set, key: K) -> bool { +pub fn set_add(set: Set, key: K) + -> bool { set.insert(key, ()) } /// Convert a set into a vector. -pub pure fn vec_from_set(s: Set) -> ~[T] { +pub pure fn vec_from_set(s: Set) -> ~[T] { do vec::build_sized(s.len()) |push| { for s.each_key() |&k| { push(k); @@ -398,7 +400,7 @@ pub pure fn vec_from_set(s: Set) -> ~[T] { } /// Construct a hashmap from a vector -pub fn hash_from_vec( +pub fn hash_from_vec( items: &[(K, V)]) -> HashMap { let map = HashMap(); for vec::each(items) |item| { diff --git a/src/libstd/oldsmallintmap.rs b/src/libstd/oldsmallintmap.rs index 5c3477660706e..a31309d7980dc 100644 --- a/src/libstd/oldsmallintmap.rs +++ b/src/libstd/oldsmallintmap.rs @@ -32,7 +32,7 @@ pub enum SmallIntMap { } /// Create a smallintmap -pub fn mk() -> SmallIntMap { +pub fn mk() -> SmallIntMap { let v = DVec(); SmallIntMap_(@SmallIntMap_ { v: v } ) } @@ -42,7 +42,7 @@ pub fn mk() -> SmallIntMap { * the specified key then the original value is replaced. */ #[inline(always)] -pub fn insert(self: SmallIntMap, key: uint, val: T) { +pub fn insert(self: SmallIntMap, key: uint, val: T) { //io::println(fmt!("%?", key)); self.v.grow_set_elt(key, &None, Some(val)); } @@ -51,7 +51,7 @@ pub fn insert(self: SmallIntMap, key: uint, val: T) { * Get the value for the specified key. If the key does not exist * in the map then returns none */ -pub pure fn find(self: SmallIntMap, key: uint) -> Option { +pub pure fn find(self: SmallIntMap, key: uint) -> Option { if key < self.v.len() { return self.v.get_elt(key); } return None::; } @@ -63,18 +63,18 @@ pub pure fn find(self: SmallIntMap, key: uint) -> Option { * * If the key does not exist in the map */ -pub pure fn get(self: SmallIntMap, key: uint) -> T { +pub pure fn get(self: SmallIntMap, key: uint) -> T { match find(self, key) { None => { error!("smallintmap::get(): key not present"); fail!(); } - Some(move v) => return v + Some(v) => return v } } /// Returns true if the map contains a value for the specified key -pub pure fn contains_key(self: SmallIntMap, key: uint) -> bool { +pub pure fn contains_key(self: SmallIntMap, key: uint) -> bool { return !find(self, key).is_none(); } @@ -100,7 +100,7 @@ impl Mutable for SmallIntMap { } /// Implements the map::map interface for smallintmap -impl SmallIntMap { +impl SmallIntMap { #[inline(always)] fn insert(key: uint, value: V) -> bool { let exists = contains_key(self, key); @@ -162,7 +162,7 @@ impl SmallIntMap { } } -impl ops::Index for SmallIntMap { +impl ops::Index for SmallIntMap { pure fn index(&self, key: uint) -> V { unsafe { get(*self, key) diff --git a/src/libstd/par.rs b/src/libstd/par.rs index 8293ff1c2afdf..0839ce1812355 100644 --- a/src/libstd/par.rs +++ b/src/libstd/par.rs @@ -34,7 +34,7 @@ const min_granularity : uint = 1024u; * This is used to build most of the other parallel vector functions, * like map or alli. */ -fn map_slices( +fn map_slices( xs: &[A], f: &fn() -> ~fn(uint, v: &[A]) -> B) -> ~[B] { @@ -58,7 +58,7 @@ fn map_slices( do vec::as_imm_buf(xs) |p, _len| { let f = f(); let base = base; - let f = do future_spawn() |move f| { + let f = do future_spawn() || { unsafe { let len = end - base; let slice = (ptr::offset(p, base), @@ -72,7 +72,7 @@ fn map_slices( f(base, slice) } }; - futures.push(move f); + futures.push(f); }; base += items_per_task; } @@ -90,7 +90,7 @@ fn map_slices( } /// A parallel version of map. -pub fn map( +pub fn map( xs: &[A], fn_factory: &fn() -> ~fn(&A) -> B) -> ~[B] { vec::concat(map_slices(xs, || { let f = fn_factory(); @@ -101,13 +101,13 @@ pub fn map( } /// A parallel version of mapi. -pub fn mapi( +pub fn mapi( xs: &[A], fn_factory: &fn() -> ~fn(uint, &A) -> B) -> ~[B] { let slices = map_slices(xs, || { let f = fn_factory(); - fn~(base: uint, slice : &[A], copy f) -> ~[B] { + fn~(base: uint, slice : &[A]) -> ~[B] { vec::mapi(slice, |i, x| { f(i + base, x) }) @@ -120,13 +120,13 @@ pub fn mapi( } /// Returns true if the function holds for all elements in the vector. -pub fn alli( +pub fn alli( xs: &[A], fn_factory: &fn() -> ~fn(uint, &A) -> bool) -> bool { do vec::all(map_slices(xs, || { let f = fn_factory(); - fn~(base: uint, slice : &[A], copy f) -> bool { + fn~(base: uint, slice : &[A]) -> bool { vec::alli(slice, |i, x| { f(i + base, x) }) @@ -135,12 +135,12 @@ pub fn alli( } /// Returns true if the function holds for any elements in the vector. -pub fn any( +pub fn any( xs: &[A], fn_factory: &fn() -> ~fn(&A) -> bool) -> bool { do vec::any(map_slices(xs, || { let f = fn_factory(); - fn~(_base : uint, slice: &[A], copy f) -> bool { + fn~(_base : uint, slice: &[A]) -> bool { vec::any(slice, |x| f(x)) } })) |x| { *x } diff --git a/src/libstd/prettyprint.rs b/src/libstd/prettyprint.rs index dc2e3d3da2bd4..cb9090225bf1c 100644 --- a/src/libstd/prettyprint.rs +++ b/src/libstd/prettyprint.rs @@ -22,7 +22,7 @@ pub fn Serializer(wr: io::Writer) -> Serializer { Serializer { wr: wr } } -pub impl Serializer: serialize::Encoder { +pub impl serialize::Encoder for Serializer { fn emit_nil(&self) { self.wr.write_str(~"()") } diff --git a/src/libstd/priority_queue.rs b/src/libstd/priority_queue.rs index a25a4196b4cab..f642bf52f659a 100644 --- a/src/libstd/priority_queue.rs +++ b/src/libstd/priority_queue.rs @@ -27,7 +27,7 @@ pub struct PriorityQueue { priv data: ~[T], } -impl BaseIter for PriorityQueue { +impl BaseIter for PriorityQueue { /// Visit all values in the underlying vector. /// /// The values are **not** visited in order. @@ -35,7 +35,7 @@ impl BaseIter for PriorityQueue { pure fn size_hint(&self) -> Option { self.data.size_hint() } } -impl Container for PriorityQueue { +impl Container for PriorityQueue { /// Returns the length of the queue pure fn len(&self) -> uint { self.data.len() } @@ -43,12 +43,12 @@ impl Container for PriorityQueue { pure fn is_empty(&self) -> bool { self.data.is_empty() } } -impl Mutable for PriorityQueue { +impl Mutable for PriorityQueue { /// Drop all items from the queue fn clear(&mut self) { self.data.truncate(0) } } -impl PriorityQueue { +impl PriorityQueue { /// Returns the greatest item in the queue - fails if empty pure fn top(&self) -> &self/T { &self.data[0] } @@ -139,27 +139,27 @@ impl PriorityQueue { priv fn siftup(&mut self, start: uint, mut pos: uint) { unsafe { - let new = move *addr_of(&self.data[pos]); + let new = *addr_of(&self.data[pos]); while pos > start { let parent = (pos - 1) >> 1; if new > self.data[parent] { let mut x = rusti::init(); x <-> self.data[parent]; - rusti::move_val_init(&mut self.data[pos], move x); + rusti::move_val_init(&mut self.data[pos], x); pos = parent; loop } break } - rusti::move_val_init(&mut self.data[pos], move new); + rusti::move_val_init(&mut self.data[pos], new); } } priv fn siftdown_range(&mut self, mut pos: uint, end: uint) { unsafe { let start = pos; - let new = move *addr_of(&self.data[pos]); + let new = *addr_of(&self.data[pos]); let mut child = 2 * pos + 1; while child < end { @@ -169,12 +169,12 @@ impl PriorityQueue { } let mut x = rusti::init(); x <-> self.data[child]; - rusti::move_val_init(&mut self.data[pos], move x); + rusti::move_val_init(&mut self.data[pos], x); pos = child; child = 2 * pos + 1; } - rusti::move_val_init(&mut self.data[pos], move new); + rusti::move_val_init(&mut self.data[pos], new); self.siftup(start, pos); } } diff --git a/src/libstd/rl.rs b/src/libstd/rl.rs index 30baa3cc5f15a..1ee67d76af571 100644 --- a/src/libstd/rl.rs +++ b/src/libstd/rl.rs @@ -71,7 +71,7 @@ fn complete_key(_v: @CompletionCb) {} /// Bind to the main completion callback pub unsafe fn complete(cb: CompletionCb) { unsafe { - task::local_data::local_data_set(complete_key, @(move cb)); + task::local_data::local_data_set(complete_key, @(cb)); extern fn callback(line: *c_char, completions: *()) { unsafe { diff --git a/src/libstd/rope.rs b/src/libstd/rope.rs index 8ff90b940fb56..8e878c8fc2e31 100644 --- a/src/libstd/rope.rs +++ b/src/libstd/rope.rs @@ -848,11 +848,11 @@ pub mod node { offset += 1u; i += 1u; } - cast::forget(move local_buf); + cast::forget(local_buf); } } } - return cast::transmute(move buf); + return cast::transmute(buf); } } diff --git a/src/libstd/semver.rs b/src/libstd/semver.rs new file mode 100644 index 0000000000000..5f96687127cad --- /dev/null +++ b/src/libstd/semver.rs @@ -0,0 +1,395 @@ +// 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. + +//! Semver parsing and logic + +use io; +use io::{ReaderUtil}; +use option::{Option, Some, None}; +use uint; +use str; +use to_str::ToStr; +use char; +use core::cmp; + +#[deriving_eq] +pub enum Identifier { + Numeric(uint), + AlphaNumeric(~str) +} + +impl cmp::Ord for Identifier { + #[inline(always)] + pure fn lt(&self, other: &Identifier) -> bool { + match (self, other) { + (&Numeric(a), &Numeric(b)) => a < b, + (&Numeric(_), _) => true, + (&AlphaNumeric(ref a), &AlphaNumeric(ref b)) => *a < *b, + (&AlphaNumeric(_), _) => false + } + } + #[inline(always)] + pure fn le(&self, other: &Identifier) -> bool { + ! (other < self) + } + #[inline(always)] + pure fn gt(&self, other: &Identifier) -> bool { + other < self + } + #[inline(always)] + pure fn ge(&self, other: &Identifier) -> bool { + ! (self < other) + } +} + +impl ToStr for Identifier { + #[inline(always)] + pure fn to_str(&self) -> ~str { + match self { + &Numeric(n) => n.to_str(), + &AlphaNumeric(ref s) => s.to_str() + } + } +} + + +#[deriving_eq] +pub struct Version { + major: uint, + minor: uint, + patch: uint, + pre: ~[Identifier], + build: ~[Identifier], +} + +impl ToStr for Version { + #[inline(always)] + pure 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 + } else { + s + "-" + str::connect(self.pre.map(|i| i.to_str()), ".") + }; + if self.build.is_empty() { + s + } else { + s + "+" + str::connect(self.build.map(|i| i.to_str()), ".") + } + } +} + +impl cmp::Ord for Version { + #[inline(always)] + pure fn lt(&self, other: &Version) -> bool { + + self.major < other.major || + + (self.major == other.major && + self.minor < other.minor) || + + (self.major == other.major && + self.minor == other.minor && + self.patch < other.patch) || + + (self.major == other.major && + self.minor == other.minor && + self.patch == other.patch && + // NB: semver spec says 0.0.0-pre < 0.0.0 + // but the version of ord defined for vec + // says that [] < [pre], so we alter it + // here. + (match (self.pre.len(), other.pre.len()) { + (0, 0) => false, + (0, _) => false, + (_, 0) => true, + (_, _) => self.pre < other.pre + })) || + + (self.major == other.major && + self.minor == other.minor && + self.patch == other.patch && + self.pre == other.pre && + self.build < other.build) + } + + #[inline(always)] + pure fn le(&self, other: &Version) -> bool { + ! (other < self) + } + #[inline(always)] + pure fn gt(&self, other: &Version) -> bool { + other < self + } + #[inline(always)] + pure fn ge(&self, other: &Version) -> bool { + ! (self < other) + } +} + +condition! { + bad_parse: () -> (); +} + +fn take_nonempty_prefix(rdr: io::Reader, + ch: char, + pred: fn(char) -> bool) -> (~str, char) { + let mut buf = ~""; + let mut ch = ch; + while pred(ch) { + str::push_char(&mut buf, ch); + ch = rdr.read_char(); + } + if buf.is_empty() { + bad_parse::cond.raise(()) + } + debug!("extracted nonempty prefix: %s", buf); + (buf, ch) +} + +fn take_num(rdr: io::Reader, ch: char) -> (uint, char) { + let (s, ch) = take_nonempty_prefix(rdr, ch, char::is_digit); + match uint::from_str(s) { + None => { bad_parse::cond.raise(()); (0, ch) }, + Some(i) => (i, ch) + } +} + +fn take_ident(rdr: io::Reader, ch: char) -> (Identifier, char) { + let (s,ch) = take_nonempty_prefix(rdr, ch, char::is_alphanumeric); + if s.all(char::is_digit) { + match uint::from_str(s) { + None => { bad_parse::cond.raise(()); (Numeric(0), ch) }, + Some(i) => (Numeric(i), ch) + } + } else { + (AlphaNumeric(s), ch) + } +} + +fn expect(ch: char, c: char) { + if ch != c { + bad_parse::cond.raise(()) + } +} + +fn parse_reader(rdr: io::Reader) -> Version { + + let (major, ch) = take_num(rdr, rdr.read_char()); + expect(ch, '.'); + let (minor, ch) = take_num(rdr, rdr.read_char()); + expect(ch, '.'); + let (patch, ch) = take_num(rdr, rdr.read_char()); + + let mut pre = ~[]; + let mut build = ~[]; + + let mut ch = ch; + if ch == '-' { + loop { + let (id, c) = take_ident(rdr, rdr.read_char()); + pre.push(id); + ch = c; + if ch != '.' { break; } + } + } + + if ch == '+' { + loop { + let (id, c) = take_ident(rdr, rdr.read_char()); + build.push(id); + ch = c; + if ch != '.' { break; } + } + } + + Version { + major: major, + minor: minor, + patch: patch, + pre: pre, + build: build, + } +} + + +pub fn parse(s: &str) -> Option { + if ! str::is_ascii(s) { + return None; + } + let s = s.trim(); + let mut bad = false; + 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 { + None + } else { + Some(v) + } + } + } +} + +#[test] +fn test_parse() { + assert parse("") == None; + assert parse(" ") == None; + assert parse("1") == None; + assert parse("1.2") == None; + assert parse("1.2") == None; + assert parse("1") == None; + assert parse("1.2") == None; + assert parse("1.2.3-") == None; + assert parse("a.b.c") == None; + assert parse("1.2.3 abc") == None; + + assert parse("1.2.3") == Some(Version { + major: 1u, + minor: 2u, + patch: 3u, + pre: ~[], + build: ~[], + }); + assert parse(" 1.2.3 ") == Some(Version { + major: 1u, + minor: 2u, + patch: 3u, + pre: ~[], + build: ~[], + }); + assert parse("1.2.3-alpha1") == Some(Version { + major: 1u, + minor: 2u, + patch: 3u, + pre: ~[AlphaNumeric(~"alpha1")], + build: ~[] + }); + assert parse(" 1.2.3-alpha1 ") == Some(Version { + major: 1u, + minor: 2u, + patch: 3u, + pre: ~[AlphaNumeric(~"alpha1")], + build: ~[] + }); + assert parse("1.2.3+build5") == Some(Version { + major: 1u, + minor: 2u, + patch: 3u, + pre: ~[], + build: ~[AlphaNumeric(~"build5")] + }); + assert parse(" 1.2.3+build5 ") == Some(Version { + major: 1u, + minor: 2u, + patch: 3u, + pre: ~[], + build: ~[AlphaNumeric(~"build5")] + }); + assert parse("1.2.3-alpha1+build5") == Some(Version { + major: 1u, + minor: 2u, + patch: 3u, + pre: ~[AlphaNumeric(~"alpha1")], + build: ~[AlphaNumeric(~"build5")] + }); + assert parse(" 1.2.3-alpha1+build5 ") == Some(Version { + major: 1u, + minor: 2u, + patch: 3u, + pre: ~[AlphaNumeric(~"alpha1")], + build: ~[AlphaNumeric(~"build5")] + }); + assert parse("1.2.3-1.alpha1.9+build5.7.3aedf ") == Some(Version { + major: 1u, + minor: 2u, + patch: 3u, + pre: ~[Numeric(1),AlphaNumeric(~"alpha1"),Numeric(9)], + build: ~[AlphaNumeric(~"build5"), + Numeric(7), + AlphaNumeric(~"3aedf")] + }); + +} + +#[test] +fn test_eq() { + assert parse("1.2.3") == parse("1.2.3"); + assert parse("1.2.3-alpha1") == parse("1.2.3-alpha1"); +} + +#[test] +fn test_ne() { + assert parse("0.0.0") != parse("0.0.1"); + assert parse("0.0.0") != parse("0.1.0"); + assert parse("0.0.0") != parse("1.0.0"); + assert parse("1.2.3-alpha") != parse("1.2.3-beta"); +} + +#[test] +fn test_lt() { + assert parse("0.0.0") < parse("1.2.3-alpha2"); + assert parse("1.0.0") < parse("1.2.3-alpha2"); + assert parse("1.2.0") < parse("1.2.3-alpha2"); + assert parse("1.2.3-alpha1") < parse("1.2.3"); + assert parse("1.2.3-alpha1") < parse("1.2.3-alpha2"); + assert !(parse("1.2.3-alpha2") < parse("1.2.3-alpha2")); +} + +#[test] +fn test_le() { + assert parse("0.0.0") <= parse("1.2.3-alpha2"); + assert parse("1.0.0") <= parse("1.2.3-alpha2"); + assert parse("1.2.0") <= parse("1.2.3-alpha2"); + assert parse("1.2.3-alpha1") <= parse("1.2.3-alpha2"); + assert parse("1.2.3-alpha2") <= parse("1.2.3-alpha2"); +} + +#[test] +fn test_gt() { + assert parse("1.2.3-alpha2") > parse("0.0.0"); + assert parse("1.2.3-alpha2") > parse("1.0.0"); + assert parse("1.2.3-alpha2") > parse("1.2.0"); + assert parse("1.2.3-alpha2") > parse("1.2.3-alpha1"); + assert parse("1.2.3") > parse("1.2.3-alpha2"); + assert !(parse("1.2.3-alpha2") > parse("1.2.3-alpha2")); +} + +#[test] +fn test_ge() { + assert parse("1.2.3-alpha2") >= parse("0.0.0"); + assert parse("1.2.3-alpha2") >= parse("1.0.0"); + assert parse("1.2.3-alpha2") >= parse("1.2.0"); + assert parse("1.2.3-alpha2") >= parse("1.2.3-alpha1"); + assert parse("1.2.3-alpha2") >= parse("1.2.3-alpha2"); +} + +#[test] +fn test_spec_order() { + + let vs = ["1.0.0-alpha", + "1.0.0-alpha.1", + "1.0.0-beta.2", + "1.0.0-beta.11", + "1.0.0-rc.1", + "1.0.0-rc.1+build.1", + "1.0.0", + "1.0.0+0.3.7", + "1.3.7+build", + "1.3.7+build.2.b8f12d7", + "1.3.7+build.11.e0f985a"]; + let mut i = 1; + while i < vs.len() { + let a = parse(vs[i-1]).get(); + let b = parse(vs[i]).get(); + assert a < b; + i += 1; + } +} diff --git a/src/libstd/serialize.rs b/src/libstd/serialize.rs index d4afdbf6f3094..3178e141097f9 100644 --- a/src/libstd/serialize.rs +++ b/src/libstd/serialize.rs @@ -105,218 +105,218 @@ pub trait Decoder { fn read_tup_elt(&self, idx: uint, f: fn() -> T) -> T; } -pub trait Encodable { +pub trait Encodable { fn encode(&self, s: &S); } -pub trait Decodable { +pub trait Decodable { static fn decode(&self, d: &D) -> Self; } -pub impl uint: Encodable { +pub impl Encodable for uint { fn encode(&self, s: &S) { s.emit_uint(*self) } } -pub impl uint: Decodable { +pub impl Decodable for uint { static fn decode(&self, d: &D) -> uint { d.read_uint() } } -pub impl u8: Encodable { +pub impl Encodable for u8 { fn encode(&self, s: &S) { s.emit_u8(*self) } } -pub impl u8: Decodable { +pub impl Decodable for u8 { static fn decode(&self, d: &D) -> u8 { d.read_u8() } } -pub impl u16: Encodable { +pub impl Encodable for u16 { fn encode(&self, s: &S) { s.emit_u16(*self) } } -pub impl u16: Decodable { +pub impl Decodable for u16 { static fn decode(&self, d: &D) -> u16 { d.read_u16() } } -pub impl u32: Encodable { +pub impl Encodable for u32 { fn encode(&self, s: &S) { s.emit_u32(*self) } } -pub impl u32: Decodable { +pub impl Decodable for u32 { static fn decode(&self, d: &D) -> u32 { d.read_u32() } } -pub impl u64: Encodable { +pub impl Encodable for u64 { fn encode(&self, s: &S) { s.emit_u64(*self) } } -pub impl u64: Decodable { +pub impl Decodable for u64 { static fn decode(&self, d: &D) -> u64 { d.read_u64() } } -pub impl int: Encodable { +pub impl Encodable for int { fn encode(&self, s: &S) { s.emit_int(*self) } } -pub impl int: Decodable { +pub impl Decodable for int { static fn decode(&self, d: &D) -> int { d.read_int() } } -pub impl i8: Encodable { +pub impl Encodable for i8 { fn encode(&self, s: &S) { s.emit_i8(*self) } } -pub impl i8: Decodable { +pub impl Decodable for i8 { static fn decode(&self, d: &D) -> i8 { d.read_i8() } } -pub impl i16: Encodable { +pub impl Encodable for i16 { fn encode(&self, s: &S) { s.emit_i16(*self) } } -pub impl i16: Decodable { +pub impl Decodable for i16 { static fn decode(&self, d: &D) -> i16 { d.read_i16() } } -pub impl i32: Encodable { +pub impl Encodable for i32 { fn encode(&self, s: &S) { s.emit_i32(*self) } } -pub impl i32: Decodable { +pub impl Decodable for i32 { static fn decode(&self, d: &D) -> i32 { d.read_i32() } } -pub impl i64: Encodable { +pub impl Encodable for i64 { fn encode(&self, s: &S) { s.emit_i64(*self) } } -pub impl i64: Decodable { +pub impl Decodable for i64 { static fn decode(&self, d: &D) -> i64 { d.read_i64() } } -pub impl &str: Encodable { +pub impl Encodable for &str { fn encode(&self, s: &S) { s.emit_borrowed_str(*self) } } -pub impl ~str: Encodable { +pub impl Encodable for ~str { fn encode(&self, s: &S) { s.emit_owned_str(*self) } } -pub impl ~str: Decodable { +pub impl Decodable for ~str { static fn decode(&self, d: &D) -> ~str { d.read_owned_str() } } -pub impl @str: Encodable { +pub impl Encodable for @str { fn encode(&self, s: &S) { s.emit_managed_str(*self) } } -pub impl @str: Decodable { +pub impl Decodable for @str { static fn decode(&self, d: &D) -> @str { d.read_managed_str() } } -pub impl float: Encodable { +pub impl Encodable for float { fn encode(&self, s: &S) { s.emit_float(*self) } } -pub impl float: Decodable { +pub impl Decodable for float { static fn decode(&self, d: &D) -> float { d.read_float() } } -pub impl f32: Encodable { +pub impl Encodable for f32 { fn encode(&self, s: &S) { s.emit_f32(*self) } } -pub impl f32: Decodable { +pub impl Decodable for f32 { static fn decode(&self, d: &D) -> f32 { d.read_f32() } } -pub impl f64: Encodable { +pub impl Encodable for f64 { fn encode(&self, s: &S) { s.emit_f64(*self) } } -pub impl f64: Decodable { +pub impl Decodable for f64 { static fn decode(&self, d: &D) -> f64 { d.read_f64() } } -pub impl bool: Encodable { +pub impl Encodable for bool { fn encode(&self, s: &S) { s.emit_bool(*self) } } -pub impl bool: Decodable { +pub impl Decodable for bool { static fn decode(&self, d: &D) -> bool { d.read_bool() } } -pub impl (): Encodable { +pub impl Encodable for () { fn encode(&self, s: &S) { s.emit_nil() } } -pub impl (): Decodable { +pub impl Decodable for () { static fn decode(&self, d: &D) -> () { d.read_nil() } } -pub impl> &T: Encodable { +pub impl> Encodable for &T { fn encode(&self, s: &S) { s.emit_borrowed(|| (**self).encode(s)) } } -pub impl> ~T: Encodable { +pub impl> Encodable for ~T { fn encode(&self, s: &S) { s.emit_owned(|| (**self).encode(s)) } } -pub impl> ~T: Decodable { +pub impl> Decodable for ~T { static fn decode(&self, d: &D) -> ~T { d.read_owned(|| ~Decodable::decode(d)) } } -pub impl> @T: Encodable { +pub impl> Encodable for @T { fn encode(&self, s: &S) { s.emit_managed(|| (**self).encode(s)) } } -pub impl> @T: Decodable { +pub impl> Decodable for @T { static fn decode(&self, d: &D) -> @T { d.read_managed(|| @Decodable::decode(d)) } } -pub impl> &[T]: Encodable { +pub impl> Encodable for &[T] { fn encode(&self, s: &S) { do s.emit_borrowed_vec(self.len()) { for self.eachi |i, e| { @@ -326,7 +326,7 @@ pub impl> &[T]: Encodable { } } -pub impl> ~[T]: Encodable { +pub impl> Encodable for ~[T] { fn encode(&self, s: &S) { do s.emit_owned_vec(self.len()) { for self.eachi |i, e| { @@ -336,7 +336,7 @@ pub impl> ~[T]: Encodable { } } -pub impl> ~[T]: Decodable { +pub impl> Decodable for ~[T] { static fn decode(&self, d: &D) -> ~[T] { do d.read_owned_vec |len| { do vec::from_fn(len) |i| { @@ -346,7 +346,7 @@ pub impl> ~[T]: Decodable { } } -pub impl> @[T]: Encodable { +pub impl> Encodable for @[T] { fn encode(&self, s: &S) { do s.emit_managed_vec(self.len()) { for self.eachi |i, e| { @@ -356,7 +356,7 @@ pub impl> @[T]: Encodable { } } -pub impl> @[T]: Decodable { +pub impl> Decodable for @[T] { static fn decode(&self, d: &D) -> @[T] { do d.read_managed_vec |len| { do at_vec::from_fn(len) |i| { @@ -366,7 +366,7 @@ pub impl> @[T]: Decodable { } } -pub impl> Option: Encodable { +pub impl> Encodable for Option { fn encode(&self, s: &S) { do s.emit_enum(~"option") { match *self { @@ -381,7 +381,7 @@ pub impl> Option: Encodable { } } -pub impl> Option: Decodable { +pub impl> Decodable for Option { static fn decode(&self, d: &D) -> Option { do d.read_enum(~"option") { do d.read_enum_variant |i| { @@ -396,11 +396,8 @@ pub impl> Option: Decodable { } } -pub impl< - S: Encoder, - T0: Encodable, - T1: Encodable -> (T0, T1): Encodable { +pub impl,T1:Encodable> Encodable + for (T0, T1) { fn encode(&self, s: &S) { match *self { (ref t0, ref t1) => { @@ -413,11 +410,8 @@ pub impl< } } -pub impl< - D: Decoder, - T0: Decodable, - T1: Decodable -> (T0, T1): Decodable { +pub impl,T1:Decodable> Decodable + for (T0, T1) { static fn decode(&self, d: &D) -> (T0, T1) { do d.read_tup(2) { ( @@ -433,7 +427,7 @@ pub impl< T0: Encodable, T1: Encodable, T2: Encodable -> (T0, T1, T2): Encodable { +> Encodable for (T0, T1, T2) { fn encode(&self, s: &S) { match *self { (ref t0, ref t1, ref t2) => { @@ -452,7 +446,7 @@ pub impl< T0: Decodable, T1: Decodable, T2: Decodable -> (T0, T1, T2): Decodable { +> Decodable for (T0, T1, T2) { static fn decode(&self, d: &D) -> (T0, T1, T2) { do d.read_tup(3) { ( @@ -470,7 +464,7 @@ pub impl< T1: Encodable, T2: Encodable, T3: Encodable -> (T0, T1, T2, T3): Encodable { +> Encodable for (T0, T1, T2, T3) { fn encode(&self, s: &S) { match *self { (ref t0, ref t1, ref t2, ref t3) => { @@ -491,7 +485,7 @@ pub impl< T1: Decodable, T2: Decodable, T3: Decodable -> (T0, T1, T2, T3): Decodable { +> Decodable for (T0, T1, T2, T3) { static fn decode(&self, d: &D) -> (T0, T1, T2, T3) { do d.read_tup(4) { ( @@ -511,7 +505,7 @@ pub impl< T2: Encodable, T3: Encodable, T4: Encodable -> (T0, T1, T2, T3, T4): Encodable { +> Encodable for (T0, T1, T2, T3, T4) { fn encode(&self, s: &S) { match *self { (ref t0, ref t1, ref t2, ref t3, ref t4) => { @@ -534,7 +528,7 @@ pub impl< T2: Decodable, T3: Decodable, T4: Decodable -> (T0, T1, T2, T3, T4): Decodable { +> Decodable for (T0, T1, T2, T3, T4) { static fn decode(&self, d: &D) -> (T0, T1, T2, T3, T4) { do d.read_tup(5) { @@ -558,7 +552,7 @@ pub trait EncoderHelpers { fn emit_from_vec(&self, v: &[T], f: fn(v: &T)); } -pub impl S: EncoderHelpers { +pub impl EncoderHelpers for S { fn emit_from_vec(&self, v: &[T], f: fn(v: &T)) { do self.emit_owned_vec(v.len()) { for v.eachi |i, e| { @@ -574,7 +568,7 @@ pub trait DecoderHelpers { fn read_to_vec(&self, f: fn() -> T) -> ~[T]; } -pub impl D: DecoderHelpers { +pub impl DecoderHelpers for D { fn read_to_vec(&self, f: fn() -> T) -> ~[T] { do self.read_owned_vec |len| { do vec::from_fn(len) |i| { diff --git a/src/libstd/sha1.rs b/src/libstd/sha1.rs index 1d91fafa4f962..242e318e8a8f0 100644 --- a/src/libstd/sha1.rs +++ b/src/libstd/sha1.rs @@ -265,7 +265,7 @@ pub fn sha1() -> Sha1 { computed: false, work_buf: @mut vec::from_elem(work_buf_len, 0u32) }; - let mut sh = (move st) as Sha1; + let mut sh = (st) as Sha1; sh.reset(); return sh; } diff --git a/src/libstd/smallintmap.rs b/src/libstd/smallintmap.rs index 382cd658663dc..68d22f7c919a6 100644 --- a/src/libstd/smallintmap.rs +++ b/src/libstd/smallintmap.rs @@ -131,7 +131,7 @@ pub impl SmallIntMap { } } -pub impl SmallIntMap { +pub impl SmallIntMap { fn update_with_key(&mut self, key: uint, val: V, ff: fn(uint, V, V) -> V) -> bool { let new_val = match self.find(&key) { diff --git a/src/libstd/sort.rs b/src/libstd/sort.rs index 98a451dc8abdd..d2515df3e1b40 100644 --- a/src/libstd/sort.rs +++ b/src/libstd/sort.rs @@ -25,12 +25,12 @@ type Le = pure fn(v1: &T, v2: &T) -> bool; * Has worst case O(n log n) performance, best case O(n), but * is not space efficient. This is a stable sort. */ -pub pure fn merge_sort(v: &[const T], le: Le) -> ~[T] { +pub pure fn merge_sort(v: &[const T], le: Le) -> ~[T] { type Slice = (uint, uint); unsafe {return merge_sort_(v, (0u, len(v)), le);} - fn merge_sort_(v: &[const T], slice: Slice, le: Le) + fn merge_sort_(v: &[const T], slice: Slice, le: Le) -> ~[T] { let begin = slice.first(); let end = slice.second(); @@ -45,7 +45,7 @@ pub pure fn merge_sort(v: &[const T], le: Le) -> ~[T] { return merge(le, merge_sort_(v, a, le), merge_sort_(v, b, le)); } - fn merge(le: Le, a: &[T], b: &[T]) -> ~[T] { + fn merge(le: Le, a: &[T], b: &[T]) -> ~[T] { let mut rs = vec::with_capacity(len(a) + len(b)); let a_len = len(a); let mut a_ix = 0; @@ -59,7 +59,7 @@ pub pure fn merge_sort(v: &[const T], le: Le) -> ~[T] { } rs.push_all(vec::slice(a, a_ix, a_len)); rs.push_all(vec::slice(b, b_ix, b_len)); - move rs + rs } } @@ -103,7 +103,7 @@ pub fn quick_sort(arr: &mut [T], compare_func: Le) { qsort::(arr, 0u, len::(arr) - 1u, compare_func); } -fn qsort3(arr: &mut [T], left: int, right: int) { +fn qsort3(arr: &mut [T], left: int, right: int) { if right <= left { return; } let v: T = arr[right]; let mut i: int = left - 1; @@ -160,7 +160,7 @@ fn qsort3(arr: &mut [T], left: int, right: int) { * * This is an unstable sort. */ -pub fn quick_sort3(arr: &mut [T]) { +pub fn quick_sort3(arr: &mut [T]) { if arr.len() <= 1 { return; } qsort3(arr, 0, (arr.len() - 1) as int); } @@ -169,7 +169,7 @@ pub trait Sort { fn qsort(self); } -impl Sort for &mut [T] { +impl Sort for &mut [T] { fn qsort(self) { quick_sort3(self); } } @@ -177,7 +177,7 @@ const MIN_MERGE: uint = 64; const MIN_GALLOP: uint = 7; const INITIAL_TMP_STORAGE: uint = 128; -pub fn tim_sort(array: &mut [T]) { +pub fn tim_sort(array: &mut [T]) { let size = array.len(); if size < 2 { return; @@ -195,12 +195,12 @@ pub fn tim_sort(array: &mut [T]) { let mut idx = 0; let mut remaining = size; loop { - let arr = vec::mut_view(array, idx, size); + let arr = vec::mut_slice(array, idx, size); let mut run_len: uint = count_run_ascending(arr); if run_len < min_run { let force = if remaining <= min_run {remaining} else {min_run}; - let slice = vec::mut_view(arr, 0, force); + let slice = vec::mut_slice(arr, 0, force); binarysort(slice, run_len); run_len = force; } @@ -216,7 +216,7 @@ pub fn tim_sort(array: &mut [T]) { ms.merge_force_collapse(array); } -fn binarysort(array: &mut [T], start: uint) { +fn binarysort(array: &mut [T], start: uint) { let size = array.len(); let mut start = start; assert start <= size; @@ -241,7 +241,7 @@ fn binarysort(array: &mut [T], start: uint) { let mut n = start-left; copy_vec(array, left+1, array, left, n); - array[left] = move pivot; + array[left] = pivot; start += 1; } } @@ -266,7 +266,7 @@ pure fn min_run_length(n: uint) -> uint { return n + r; } -fn count_run_ascending(array: &mut [T]) -> uint { +fn count_run_ascending(array: &mut [T]) -> uint { let size = array.len(); assert size > 0; if size == 1 { return 1; } @@ -286,7 +286,7 @@ fn count_run_ascending(array: &mut [T]) -> uint { return run; } -pure fn gallop_left(key: &const T, array: &[const T], +pure fn gallop_left(key: &const T, array: &[const T], hint: uint) -> uint { let size = array.len(); assert size != 0 && hint < size; @@ -335,7 +335,7 @@ pure fn gallop_left(key: &const T, array: &[const T], return ofs; } -pure fn gallop_right(key: &const T, array: &[const T], +pure fn gallop_right(key: &const T, array: &[const T], hint: uint) -> uint { let size = array.len(); assert size != 0 && hint < size; @@ -404,7 +404,7 @@ fn MergeState() -> MergeState { } } -impl MergeState { +impl MergeState { fn push_run(&self, run_base: uint, run_len: uint) { let tmp = RunState{base: run_base, len: run_len}; self.runs.push(tmp); @@ -431,12 +431,12 @@ impl MergeState { arr[n+1].len = arr[n+2].len; } - let slice = vec::mut_view(array, b1, b1+l1); + let slice = vec::mut_slice(array, b1, b1+l1); let k = gallop_right(&const array[b2], slice, 0); b1 += k; l1 -= k; if l1 != 0 { - let slice = vec::mut_view(array, b2, b2+l2); + let slice = vec::mut_slice(array, b2, b2+l2); let l2 = gallop_left( &const array[b1+l1-1],slice,l2-1); if l2 > 0 { @@ -455,7 +455,8 @@ impl MergeState { base2: uint, len2: uint) { assert len1 != 0 && len2 != 0 && base1+len1 == base2; - let mut tmp = vec::slice(array, base1, base1+len1); + let tmp = vec::cast_to_mut( + vec::slice(array, base1, base1+len1).to_vec()); let mut c1 = 0; let mut c2 = base2; @@ -509,7 +510,7 @@ impl MergeState { loop { assert len1 > 1 && len2 != 0; - let tmp_view = vec::const_view(tmp, c1, c1+len1); + let tmp_view = vec::const_slice(tmp, c1, c1+len1); count1 = gallop_right(&const array[c2], tmp_view, 0); if count1 != 0 { copy_vec(array, dest, tmp, c1, count1); @@ -520,7 +521,7 @@ impl MergeState { dest += 1; c2 += 1; len2 -= 1; if len2 == 0 { break_outer = true; break; } - let tmp_view = vec::const_view(array, c2, c2+len2); + let tmp_view = vec::const_slice(array, c2, c2+len2); count2 = gallop_left(&const tmp[c1], tmp_view, 0); if count2 != 0 { copy_vec(array, dest, array, c2, count2); @@ -558,7 +559,8 @@ impl MergeState { base2: uint, len2: uint) { assert len1 != 1 && len2 != 0 && base1 + len1 == base2; - let mut tmp = vec::slice(array, base2, base2+len2); + let tmp = vec::cast_to_mut( + vec::slice(array, base2, base2+len2).to_vec()); let mut c1 = base1 + len1 - 1; let mut c2 = len2 - 1; @@ -614,7 +616,7 @@ impl MergeState { loop { assert len2 > 1 && len1 != 0; - let tmp_view = vec::mut_view(array, base1, base1+len1); + let tmp_view = vec::mut_slice(array, base1, base1+len1); count1 = len1 - gallop_right( &const tmp[c2], tmp_view, len1-1); @@ -630,7 +632,7 @@ impl MergeState { let count2; { - let tmp_view = vec::mut_view(tmp, 0, len2); + let tmp_view = vec::mut_slice(tmp, 0, len2); count2 = len2 - gallop_left(&const array[c1], tmp_view, len2-1); @@ -706,11 +708,11 @@ impl MergeState { } #[inline(always)] -fn copy_vec(dest: &mut [T], s1: uint, +fn copy_vec(dest: &mut [T], s1: uint, from: &[const T], s2: uint, len: uint) { assert s1+len <= dest.len() && s2+len <= from.len(); - let slice = vec::slice(from, s2, s2+len); + let slice = vec::slice(from, s2, s2+len).to_vec(); for slice.eachi |i, v| { dest[s1+i] = *v; } @@ -816,7 +818,7 @@ mod test_qsort { do quick_sort(names) |x, y| { int::le(*x, *y) }; - let immut_names = move names; + let immut_names = names; let pairs = vec::zip_slice(expected, immut_names); for vec::each(pairs) |p| { @@ -1017,23 +1019,23 @@ mod big_tests { tabulate_managed(low, high); } - fn multiplyVec(arr: &[const T], num: uint) -> ~[T] { + fn multiplyVec(arr: &[const T], num: uint) -> ~[T] { let size = arr.len(); let res = do vec::from_fn(num) |i| { arr[i % size] }; - move res + res } fn makeRange(n: uint) -> ~[uint] { let one = do vec::from_fn(n) |i| { i }; let mut two = copy one; vec::reverse(two); - vec::append(move two, one) + vec::append(two, one) } fn tabulate_unique(lo: uint, hi: uint) { - fn isSorted(arr: &[const T]) { + fn isSorted(arr: &[const T]) { for uint::range(0, arr.len()-1) |i| { if arr[i] > arr[i+1] { fail!(~"Array not sorted"); @@ -1048,7 +1050,7 @@ mod big_tests { let arr = do vec::from_fn(n) |_i| { rng.gen_float() }; - let mut arr = move arr; + let mut arr = arr; tim_sort(arr); // *sort isSorted(arr); @@ -1087,9 +1089,9 @@ mod big_tests { isSorted(arr); let mut arr = if n > 4 { - let part = vec::view(arr, 0, 4); + let part = vec::slice(arr, 0, 4); multiplyVec(part, n) - } else { move arr }; + } else { arr }; tim_sort(arr); // ~sort isSorted(arr); @@ -1105,7 +1107,7 @@ mod big_tests { } fn tabulate_managed(lo: uint, hi: uint) { - fn isSorted(arr: &[const @T]) { + fn isSorted(arr: &[const @T]) { for uint::range(0, arr.len()-1) |i| { if arr[i] > arr[i+1] { fail!(~"Array not sorted"); @@ -1120,7 +1122,7 @@ mod big_tests { let arr = do vec::from_fn(n) |_i| { @rng.gen_float() }; - let mut arr = move arr; + let mut arr = arr; tim_sort(arr); // *sort isSorted(arr); @@ -1159,9 +1161,9 @@ mod big_tests { isSorted(arr); let mut arr = if n > 4 { - let part = vec::view(arr, 0, 4); + let part = vec::slice(arr, 0, 4); multiplyVec(part, n) - } else { move arr }; + } else { arr }; tim_sort(arr); // ~sort isSorted(arr); diff --git a/src/libstd/std.rc b/src/libstd/std.rc index 3c2baae6d57c1..b0756104fe532 100644 --- a/src/libstd/std.rc +++ b/src/libstd/std.rc @@ -99,6 +99,7 @@ pub mod rl; pub mod workcache; pub mod bigint; pub mod stats; +pub mod semver; #[cfg(unicode)] mod unicode; diff --git a/src/libstd/sync.rs b/src/libstd/sync.rs index af773f5bf4e50..016847a5bfd7d 100644 --- a/src/libstd/sync.rs +++ b/src/libstd/sync.rs @@ -30,17 +30,17 @@ use core::vec; // Each waiting task receives on one of these. #[doc(hidden)] -type WaitEnd = pipes::PortOne<()>; +type WaitEnd = comm::PortOne<()>; #[doc(hidden)] -type SignalEnd = pipes::ChanOne<()>; +type SignalEnd = comm::ChanOne<()>; // A doubly-ended queue of waiting tasks. #[doc(hidden)] -struct Waitqueue { head: pipes::Port, - tail: pipes::Chan } +struct Waitqueue { head: comm::Port, + tail: comm::Chan } fn new_waitqueue() -> Waitqueue { - let (block_head, block_tail) = pipes::stream(); - Waitqueue { head: move block_head, tail: move block_tail } + let (block_head, block_tail) = comm::stream(); + Waitqueue { head: block_head, tail: block_tail } } // Signals one live task from the queue. @@ -50,7 +50,7 @@ fn signal_waitqueue(q: &Waitqueue) -> bool { if q.head.peek() { // Pop and send a wakeup signal. If the waiter was killed, its port // will have closed. Keep trying until we get a live task. - if pipes::try_send_one(q.head.recv(), ()) { + if comm::try_send_one(q.head.recv(), ()) { true } else { signal_waitqueue(q) @@ -64,7 +64,7 @@ fn signal_waitqueue(q: &Waitqueue) -> bool { fn broadcast_waitqueue(q: &Waitqueue) -> uint { let mut count = 0; while q.head.peek() { - if pipes::try_send_one(q.head.recv(), ()) { + if comm::try_send_one(q.head.recv(), ()) { count += 1; } } @@ -84,9 +84,9 @@ struct SemInner { enum Sem = Exclusive>; #[doc(hidden)] -fn new_sem(count: int, q: Q) -> Sem { +fn new_sem(count: int, q: Q) -> Sem { Sem(exclusive(SemInner { - mut count: count, waiters: new_waitqueue(), blocked: move q })) + mut count: count, waiters: new_waitqueue(), blocked: q })) } #[doc(hidden)] fn new_sem_and_signal(count: int, num_condvars: uint) @@ -99,7 +99,7 @@ fn new_sem_and_signal(count: int, num_condvars: uint) } #[doc(hidden)] -impl &Sem { +impl &Sem { fn acquire() { let mut waiter_nobe = None; unsafe { @@ -107,11 +107,11 @@ impl &Sem { state.count -= 1; if state.count < 0 { // Create waiter nobe. - let (WaitEnd, SignalEnd) = pipes::oneshot(); + let (WaitEnd, SignalEnd) = comm::oneshot(); // Tell outer scope we need to block. - waiter_nobe = Some(move WaitEnd); + waiter_nobe = Some(WaitEnd); // Enqueue ourself. - state.waiters.tail.send(move SignalEnd); + state.waiters.tail.send(SignalEnd); } } } @@ -119,7 +119,7 @@ impl &Sem { /* for 1000.times { task::yield(); } */ // Need to wait outside the exclusive. if waiter_nobe.is_some() { - let _ = pipes::recv_one(option::unwrap(move waiter_nobe)); + let _ = comm::recv_one(option::unwrap(waiter_nobe)); } } fn release() { @@ -167,7 +167,7 @@ type SemRelease = SemReleaseGeneric<()>; type SemAndSignalRelease = SemReleaseGeneric<~[Waitqueue]>; struct SemReleaseGeneric { sem: &Sem } -impl Drop for SemReleaseGeneric { +impl Drop for SemReleaseGeneric { fn finalize(&self) { self.sem.release(); } @@ -214,9 +214,9 @@ impl &Condvar { */ fn wait_on(condvar_id: uint) { // Create waiter nobe. - let (WaitEnd, SignalEnd) = pipes::oneshot(); - let mut WaitEnd = Some(move WaitEnd); - let mut SignalEnd = Some(move SignalEnd); + let (WaitEnd, SignalEnd) = comm::oneshot(); + let mut WaitEnd = Some(WaitEnd); + let mut SignalEnd = Some(SignalEnd); let mut reacquire = None; let mut out_of_bounds = None; unsafe { @@ -231,7 +231,7 @@ impl &Condvar { } // Enqueue ourself to be woken up by a signaller. let SignalEnd = option::swap_unwrap(&mut SignalEnd); - state.blocked[condvar_id].tail.send(move SignalEnd); + state.blocked[condvar_id].tail.send(SignalEnd); } else { out_of_bounds = Some(vec::len(state.blocked)); } @@ -250,7 +250,7 @@ impl &Condvar { // Unconditionally "block". (Might not actually block if a // signaller already sent -- I mean 'unconditionally' in contrast // with acquire().) - let _ = pipes::recv_one(option::swap_unwrap(&mut WaitEnd)); + let _ = comm::recv_one(option::swap_unwrap(&mut WaitEnd)); } // This is needed for a failing condition variable to reacquire the @@ -737,7 +737,7 @@ mod tests { pub fn test_sem_as_mutex() { let s = ~semaphore(1); let s2 = ~s.clone(); - do task::spawn |move s2| { + do task::spawn || { do s2.access { for 5.times { task::yield(); } } @@ -749,10 +749,10 @@ mod tests { #[test] pub fn test_sem_as_cvar() { /* Child waits and parent signals */ - let (p,c) = pipes::stream(); + let (p,c) = comm::stream(); let s = ~semaphore(0); let s2 = ~s.clone(); - do task::spawn |move s2, move c| { + do task::spawn || { s2.acquire(); c.send(()); } @@ -761,10 +761,10 @@ mod tests { let _ = p.recv(); /* Parent waits and child signals */ - let (p,c) = pipes::stream(); + let (p,c) = comm::stream(); let s = ~semaphore(0); let s2 = ~s.clone(); - do task::spawn |move s2, move p| { + do task::spawn || { for 5.times { task::yield(); } s2.release(); let _ = p.recv(); @@ -778,9 +778,9 @@ mod tests { // time, and shake hands. let s = ~semaphore(2); let s2 = ~s.clone(); - let (p1,c1) = pipes::stream(); - let (p2,c2) = pipes::stream(); - do task::spawn |move s2, move c1, move p2| { + let (p1,c1) = comm::stream(); + let (p2,c2) = comm::stream(); + do task::spawn || { do s2.access { let _ = p2.recv(); c1.send(()); @@ -798,11 +798,11 @@ mod tests { do task::spawn_sched(task::ManualThreads(1)) { let s = ~semaphore(1); let s2 = ~s.clone(); - let (p,c) = pipes::stream(); - let child_data = ~mut Some((move s2, move c)); + let (p,c) = comm::stream(); + let child_data = ~mut Some((s2, c)); do s.access { let (s2,c) = option::swap_unwrap(child_data); - do task::spawn |move c, move s2| { + do task::spawn || { c.send(()); do s2.access { } c.send(()); @@ -820,12 +820,12 @@ mod tests { pub fn test_mutex_lock() { // Unsafely achieve shared state, and do the textbook // "load tmp = move ptr; inc tmp; store ptr <- tmp" dance. - let (p,c) = pipes::stream(); + let (p,c) = comm::stream(); let m = ~Mutex(); let m2 = ~m.clone(); let mut sharedstate = ~0; let ptr = ptr::addr_of(&(*sharedstate)); - do task::spawn |move m2, move c| { + do task::spawn || { let sharedstate: &mut int = unsafe { cast::reinterpret_cast(&ptr) }; access_shared(sharedstate, m2, 10); @@ -854,7 +854,7 @@ mod tests { // Child wakes up parent do m.lock_cond |cond| { let m2 = ~m.clone(); - do task::spawn |move m2| { + do task::spawn || { do m2.lock_cond |cond| { let woken = cond.signal(); assert woken; @@ -863,9 +863,9 @@ mod tests { cond.wait(); } // Parent wakes up child - let (port,chan) = pipes::stream(); + let (port,chan) = comm::stream(); let m3 = ~m.clone(); - do task::spawn |move chan, move m3| { + do task::spawn || { do m3.lock_cond |cond| { chan.send(()); cond.wait(); @@ -886,9 +886,9 @@ mod tests { for num_waiters.times { let mi = ~m.clone(); - let (port, chan) = pipes::stream(); - ports.push(move port); - do task::spawn |move chan, move mi| { + let (port, chan) = comm::stream(); + ports.push(port); + do task::spawn || { do mi.lock_cond |cond| { chan.send(()); cond.wait(); @@ -918,7 +918,7 @@ mod tests { pub fn test_mutex_cond_no_waiter() { let m = ~Mutex(); let m2 = ~m.clone(); - do task::try |move m| { + do task::try || { do m.lock_cond |_x| { } }; do m2.lock_cond |cond| { @@ -931,7 +931,7 @@ mod tests { let m = ~Mutex(); let m2 = ~m.clone(); - let result: result::Result<(),()> = do task::try |move m2| { + let result: result::Result<(),()> = do task::try || { do m2.lock { fail!(); } @@ -947,9 +947,9 @@ mod tests { let m = ~Mutex(); let m2 = ~m.clone(); - let result: result::Result<(),()> = do task::try |move m2| { - let (p,c) = pipes::stream(); - do task::spawn |move p| { // linked + let result: result::Result<(),()> = do task::try || { + let (p,c) = comm::stream(); + do task::spawn || { // linked let _ = p.recv(); // wait for sibling to get in the mutex task::yield(); fail!(); @@ -970,21 +970,21 @@ mod tests { pub fn test_mutex_killed_broadcast() { let m = ~Mutex(); let m2 = ~m.clone(); - let (p,c) = pipes::stream(); + let (p,c) = comm::stream(); - let result: result::Result<(),()> = do task::try |move c, move m2| { + let result: result::Result<(),()> = do task::try || { let mut sibling_convos = ~[]; for 2.times { - let (p,c) = pipes::stream(); - let c = ~mut Some(move c); - sibling_convos.push(move p); + let (p,c) = comm::stream(); + let c = ~mut Some(c); + sibling_convos.push(p); let mi = ~m2.clone(); // spawn sibling task - do task::spawn |move mi, move c| { // linked + do task::spawn || { // linked do mi.lock_cond |cond| { let c = option::swap_unwrap(c); c.send(()); // tell sibling to go ahead - let _z = SendOnFailure(move c); + let _z = SendOnFailure(c); cond.wait(); // block forever } } @@ -993,7 +993,7 @@ mod tests { let _ = p.recv(); // wait for sibling to get in the mutex } do m2.lock { } - c.send(move sibling_convos); // let parent wait on all children + c.send(sibling_convos); // let parent wait on all children fail!(); }; assert result.is_err(); @@ -1004,7 +1004,7 @@ mod tests { assert woken == 0; } struct SendOnFailure { - c: pipes::Chan<()>, + c: comm::Chan<()>, } impl Drop for SendOnFailure { @@ -1013,9 +1013,9 @@ mod tests { } } - fn SendOnFailure(c: pipes::Chan<()>) -> SendOnFailure { + fn SendOnFailure(c: comm::Chan<()>) -> SendOnFailure { SendOnFailure { - c: move c + c: c } } } @@ -1025,7 +1025,7 @@ mod tests { let m = ~Mutex(); do m.lock_cond |cond| { let m2 = ~m.clone(); - do task::spawn |move m2| { + do task::spawn || { do m2.lock_cond |cond| { cond.signal_on(0); } @@ -1038,8 +1038,8 @@ mod tests { let result = do task::try { let m = ~mutex_with_condvars(2); let m2 = ~m.clone(); - let (p,c) = pipes::stream(); - do task::spawn |move m2, move c| { + let (p,c) = comm::stream(); + do task::spawn || { do m2.lock_cond |cond| { c.send(()); cond.wait_on(1); @@ -1088,7 +1088,7 @@ mod tests { }, DowngradeRead => do x.write_downgrade |mode| { - let mode = x.downgrade(move mode); + let mode = x.downgrade(mode); (&mode).read(blk); }, } @@ -1099,11 +1099,11 @@ mod tests { mode2: RWlockMode) { // Test mutual exclusion between readers and writers. Just like the // mutex mutual exclusion test, a ways above. - let (p,c) = pipes::stream(); + let (p,c) = comm::stream(); let x2 = ~x.clone(); let mut sharedstate = ~0; let ptr = ptr::addr_of(&(*sharedstate)); - do task::spawn |move c, move x2| { + do task::spawn || { let sharedstate: &mut int = unsafe { cast::reinterpret_cast(&ptr) }; access_shared(sharedstate, x2, mode1, 10); @@ -1146,9 +1146,9 @@ mod tests { make_mode2_go_first: bool) { // Much like sem_multi_resource. let x2 = ~x.clone(); - let (p1,c1) = pipes::stream(); - let (p2,c2) = pipes::stream(); - do task::spawn |move c1, move x2, move p2| { + let (p1,c1) = comm::stream(); + let (p2,c2) = comm::stream(); + do task::spawn || { if !make_mode2_go_first { let _ = p2.recv(); // parent sends to us once it locks, or ... } @@ -1185,10 +1185,10 @@ mod tests { // Tests that downgrade can unlock the lock in both modes let x = ~RWlock(); do lock_rwlock_in_mode(x, Downgrade) { } - test_rwlock_handshake(move x, Read, Read, false); + test_rwlock_handshake(x, Read, Read, false); let y = ~RWlock(); do lock_rwlock_in_mode(y, DowngradeRead) { } - test_rwlock_exclusion(move y, Write, Write); + test_rwlock_exclusion(y, Write, Write); } #[test] pub fn test_rwlock_read_recursive() { @@ -1203,7 +1203,7 @@ mod tests { // Child wakes up parent do x.write_cond |cond| { let x2 = ~x.clone(); - do task::spawn |move x2| { + do task::spawn || { do x2.write_cond |cond| { let woken = cond.signal(); assert woken; @@ -1212,9 +1212,9 @@ mod tests { cond.wait(); } // Parent wakes up child - let (port,chan) = pipes::stream(); + let (port,chan) = comm::stream(); let x3 = ~x.clone(); - do task::spawn |move x3, move chan| { + do task::spawn || { do x3.write_cond |cond| { chan.send(()); cond.wait(); @@ -1249,9 +1249,9 @@ mod tests { for num_waiters.times { let xi = ~x.clone(); - let (port, chan) = pipes::stream(); - ports.push(move port); - do task::spawn |move chan, move xi| { + let (port, chan) = comm::stream(); + ports.push(port); + do task::spawn || { do lock_cond(xi, dg1) |cond| { chan.send(()); cond.wait(); @@ -1286,7 +1286,7 @@ mod tests { let x = ~RWlock(); let x2 = ~x.clone(); - let result: result::Result<(),()> = do task::try |move x2| { + let result: result::Result<(),()> = do task::try || { do lock_rwlock_in_mode(x2, mode1) { fail!(); } @@ -1332,7 +1332,7 @@ mod tests { let x = ~RWlock(); let y = ~RWlock(); do x.write_downgrade |xwrite| { - let mut xopt = Some(move xwrite); + let mut xopt = Some(xwrite); do y.write_downgrade |_ywrite| { y.downgrade(option::swap_unwrap(&mut xopt)); error!("oops, y.downgrade(x) should have failed!"); diff --git a/src/libstd/task_pool.rs b/src/libstd/task_pool.rs index 5ed2195d2d2ad..6b8ea8a6ef42c 100644 --- a/src/libstd/task_pool.rs +++ b/src/libstd/task_pool.rs @@ -12,7 +12,7 @@ /// parallelism. use core::io; -use core::pipes::{Chan, Port}; +use core::comm::{Chan, Port}; use core::pipes; use core::prelude::*; use core::task::{SchedMode, SingleThreaded}; @@ -47,14 +47,14 @@ pub impl TaskPool { assert n_tasks >= 1; let channels = do vec::from_fn(n_tasks) |i| { - let (port, chan) = pipes::stream::>(); + let (port, chan) = comm::stream::>(); let init_fn = init_fn_factory(); - let task_body: ~fn() = |move port, move init_fn| { + let task_body: ~fn() = || { let local_data = init_fn(i); loop { match port.recv() { - Execute(move f) => f(&local_data), + Execute(f) => f(&local_data), Quit => break } } @@ -64,23 +64,23 @@ pub impl TaskPool { match opt_sched_mode { None => { // Run on this scheduler. - task::spawn(move task_body); + task::spawn(task_body); } Some(sched_mode) => { - task::task().sched_mode(sched_mode).spawn(move task_body); + task::task().sched_mode(sched_mode).spawn(task_body); } } - move chan + chan }; - return TaskPool { channels: move channels, next_index: 0 }; + return TaskPool { channels: channels, next_index: 0 }; } /// Executes the function `f` on a task in the pool. The function /// receives a reference to the local data returned by the `init_fn`. fn execute(&self, f: ~fn(&T)) { - self.channels[self.next_index].send(Execute(move f)); + self.channels[self.next_index].send(Execute(f)); self.next_index += 1; if self.next_index == self.channels.len() { self.next_index = 0; } } @@ -90,9 +90,9 @@ pub impl TaskPool { fn test_task_pool() { let f: ~fn() -> ~fn(uint) -> uint = || { let g: ~fn(uint) -> uint = |i| i; - move g + g }; - let pool = TaskPool::new(4, Some(SingleThreaded), move f); + let pool = TaskPool::new(4, Some(SingleThreaded), f); for 8.times { pool.execute(|i| io::println(fmt!("Hello from thread %u!", *i))); } diff --git a/src/libstd/test.rs b/src/libstd/test.rs index 530761e48a201..e14e9665216f6 100644 --- a/src/libstd/test.rs +++ b/src/libstd/test.rs @@ -27,7 +27,7 @@ use core::either; use core::io::WriterUtil; use core::io; use core::libc::size_t; -use core::pipes::{stream, Chan, Port, SharedChan}; +use core::comm::{stream, Chan, Port, SharedChan}; use core::option; use core::prelude::*; use core::result; @@ -120,8 +120,8 @@ pub struct TestDescAndFn { pub fn test_main(args: &[~str], tests: ~[TestDescAndFn]) { let opts = match parse_opts(args) { - either::Left(move o) => o, - either::Right(move m) => fail!(m) + either::Left(o) => o, + either::Right(m) => fail!(m) }; if !run_tests_console(&opts, tests) { fail!(~"Some tests failed"); } } @@ -143,7 +143,7 @@ pub fn test_main_static(args: &[~str], tests: &[TestDescAndFn]) { TestDescAndFn { testfn: StaticBenchFn(f), desc: copy t.desc }, _ => { - die! (~"non-static tests passed to test::test_main_static"); + fail!(~"non-static tests passed to test::test_main_static"); } } }; @@ -173,8 +173,8 @@ pub fn parse_opts(args: &[~str]) -> OptRes { getopts::optopt(~"logfile")]; let matches = match getopts::getopts(args_, opts) { - Ok(move m) => m, - Err(move f) => return either::Right(getopts::fail_str(f)) + Ok(m) => m, + Err(f) => return either::Right(getopts::fail_str(f)) }; let filter = @@ -260,7 +260,7 @@ pub fn run_tests_console(opts: &TestOpts, st.failed += 1; write_failed(st.out, st.use_color); st.out.write_line(~""); - st.failures.push(move test); + st.failures.push(test); } TrIgnored => { st.ignored += 1; @@ -410,7 +410,7 @@ fn should_sort_failures_before_printing_them() { mut failed: 0u, mut ignored: 0u, mut benchmarked: 0u, - mut failures: ~[move test_b, move test_a] + mut failures: ~[test_b, test_a] }; print_failures(st); @@ -486,7 +486,7 @@ fn run_tests(opts: &TestOpts, callback(TeWait(copy b.desc)); run_test(!opts.run_benchmarks, b, ch.clone()); let (test, result) = p.recv(); - callback(TeResult(move test, result)); + callback(TeResult(test, result)); } } @@ -514,7 +514,7 @@ pub fn filter_tests( // Remove tests that don't match the test filter filtered = if opts.filter.is_none() { - move filtered + filtered } else { let filter_str = match opts.filter { @@ -534,7 +534,7 @@ pub fn filter_tests( // Maybe pull out the ignored test and unignore them filtered = if !opts.run_ignored { - move filtered + filtered } else { fn filter(test: TestDescAndFn) -> Option { if test.desc.ignore { @@ -556,7 +556,7 @@ pub fn filter_tests( } sort::quick_sort(filtered, lteq); - move filtered + filtered } struct TestFuture { @@ -582,9 +582,9 @@ pub fn run_test(force_ignore: bool, do task::spawn { let mut result_future = None; // task::future_result(builder); task::task().unlinked().future_result(|+r| { - result_future = Some(move r); + result_future = Some(r); }).spawn(testfn_cell.take()); - let task_result = option::unwrap(move result_future).recv(); + let task_result = option::unwrap(result_future).recv(); let test_result = calc_result(&desc, task_result == task::Success); monitor_ch.send((desc, test_result)); @@ -794,7 +794,7 @@ mod tests { use test::{TestOpts, run_test}; use core::either; - use core::pipes::{stream, SharedChan}; + use core::comm::{stream, SharedChan}; use core::option; use core::vec; @@ -965,9 +965,9 @@ mod tests { }, testfn: DynTestFn(copy testfn), }; - tests.push(move test); + tests.push(test); } - move tests + tests }; let filtered = filter_tests(&opts, tests); @@ -980,7 +980,7 @@ mod tests { ~"test::parse_ignored_flag", ~"test::sort_tests"]; - let pairs = vec::zip(expected, move filtered); + let pairs = vec::zip(expected, filtered); for vec::each(pairs) |p| { match *p { diff --git a/src/libstd/time.rs b/src/libstd/time.rs index 77e7e3c3054d8..0b8b6c8d34d68 100644 --- a/src/libstd/time.rs +++ b/src/libstd/time.rs @@ -170,7 +170,7 @@ pub fn at_utc(clock: Timespec) -> Tm { let mut Timespec { sec, nsec } = clock; let mut tm = empty_tm(); rustrt::rust_gmtime(sec, nsec, tm); - move tm + tm } } @@ -185,7 +185,7 @@ pub fn at(clock: Timespec) -> Tm { let mut Timespec { sec, nsec } = clock; let mut tm = empty_tm(); rustrt::rust_localtime(sec, nsec, tm); - move tm + tm } } @@ -205,7 +205,7 @@ pub pure fn strptime(s: &str, format: &str) -> Result { pub pure fn strftime(format: &str, tm: &Tm) -> ~str { // unsafe only because do_strftime is annoying to make pure // (it does IO with a str_reader) - move unsafe { do_strftime(format, tm) } + unsafe { do_strftime(format, tm) } } impl Tm { @@ -240,7 +240,7 @@ impl Tm { /// Formats the time according to the format string. pure fn strftime(&self, format: &str) -> ~str { - move strftime(format, self) + strftime(format, self) } /** @@ -689,7 +689,7 @@ priv fn do_strptime(s: &str, format: &str) -> Result { '%' => { match parse_type(s, pos, rdr.read_char(), &mut tm) { Ok(next) => pos = next, - Err(move e) => { result = Err(move e); break; } + Err(e) => { result = Err(e); break; } } }, c => { @@ -714,7 +714,7 @@ priv fn do_strptime(s: &str, format: &str) -> Result { tm_zone: copy tm.tm_zone, tm_nsec: tm.tm_nsec, }) - } else { move result } + } else { result } } } @@ -882,7 +882,7 @@ priv fn do_strftime(format: &str, tm: &Tm) -> ~str { } } - move buf + buf } #[cfg(test)] diff --git a/src/libstd/timer.rs b/src/libstd/timer.rs index 6e1e6a331a296..b711825aecf79 100644 --- a/src/libstd/timer.rs +++ b/src/libstd/timer.rs @@ -18,7 +18,7 @@ use core::either; use core::libc; use core::libc::c_void; use core::cast::transmute; -use core::pipes::{stream, Chan, SharedChan, Port, select2i}; +use core::comm::{stream, Chan, SharedChan, Port, select2i}; use core::prelude::*; use core::ptr; use core; @@ -39,7 +39,7 @@ use core; * * ch - a channel of type T to send a `val` on * * val - a value of type T to send over the provided `ch` */ -pub fn delayed_send(iotask: &IoTask, +pub fn delayed_send(iotask: &IoTask, msecs: uint, ch: &Chan, val: T) { @@ -123,7 +123,7 @@ pub fn sleep(iotask: &IoTask, msecs: uint) { * on the provided port in the allotted timeout period, then the result will * be a `Some(T)`. If not, then `None` will be returned. */ -pub fn recv_timeout(iotask: &IoTask, +pub fn recv_timeout(iotask: &IoTask, msecs: uint, wait_po: &Port) -> Option { diff --git a/src/libstd/treemap.rs b/src/libstd/treemap.rs index 282ecf086e4e8..eb3093a27451f 100644 --- a/src/libstd/treemap.rs +++ b/src/libstd/treemap.rs @@ -39,7 +39,7 @@ pub struct TreeMap { priv length: uint } -impl Eq for TreeMap { +impl Eq for TreeMap { pure fn eq(&self, other: &TreeMap) -> bool { if self.len() != other.len() { false @@ -66,7 +66,7 @@ impl Eq for TreeMap { } // Lexicographical comparison -pure fn lt(a: &TreeMap, b: &TreeMap) -> bool { +pure fn lt(a: &TreeMap, b: &TreeMap) -> bool { let mut x = a.iter(); let mut y = b.iter(); @@ -85,7 +85,7 @@ pure fn lt(a: &TreeMap, b: &TreeMap) -> bool { return a_len < b_len; } -impl Ord for TreeMap { +impl Ord for TreeMap { #[inline(always)] pure fn lt(&self, other: &TreeMap) -> bool { lt(self, other) @@ -104,7 +104,7 @@ impl Ord for TreeMap { } } -impl BaseIter<(&K, &V)> for TreeMap { +impl BaseIter<(&K, &V)> for TreeMap { /// Visit all key-value pairs in order pure fn each(&self, f: fn(&(&self/K, &self/V)) -> bool) { each(&self.root, f) @@ -112,14 +112,14 @@ impl BaseIter<(&K, &V)> for TreeMap { pure fn size_hint(&self) -> Option { Some(self.len()) } } -impl ReverseIter<(&K, &V)> for TreeMap { +impl ReverseIter<(&K, &V)> for TreeMap { /// Visit all key-value pairs in reverse order pure fn each_reverse(&self, f: fn(&(&self/K, &self/V)) -> bool) { each_reverse(&self.root, f); } } -impl Container for TreeMap { +impl Container for TreeMap { /// Return the number of elements in the map pure fn len(&self) -> uint { self.length } @@ -127,7 +127,7 @@ impl Container for TreeMap { pure fn is_empty(&self) -> bool { self.root.is_none() } } -impl Mutable for TreeMap { +impl Mutable for TreeMap { /// Clear the map, removing all key-value pairs. fn clear(&mut self) { self.root = None; @@ -135,7 +135,7 @@ impl Mutable for TreeMap { } } -impl Map 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 { self.find(key).is_some() @@ -184,7 +184,7 @@ impl Map for TreeMap { } } -impl TreeMap { +impl TreeMap { /// Create an empty TreeMap static pure fn new() -> TreeMap { TreeMap{root: None, length: 0} } @@ -212,7 +212,7 @@ pub struct TreeMapIterator { priv current: Option<&~TreeNode> } -impl TreeMapIterator { +impl TreeMapIterator { // Returns the current node, or None if this iterator is at the end. fn get(&const self) -> Option<(&self/K, &self/V)> { match self.current { @@ -224,7 +224,7 @@ impl TreeMapIterator { /// Advance the iterator to the next node (in order). If this iterator /// is finished, does nothing. -pub fn map_next(iter: &mut TreeMapIterator/&a) { +pub fn map_next(iter: &mut TreeMapIterator/&a) { while !iter.stack.is_empty() || iter.node.is_some() { match *iter.node { Some(ref x) => { @@ -246,25 +246,25 @@ pub struct TreeSet { priv map: TreeMap } -impl BaseIter for TreeSet { +impl BaseIter for TreeSet { /// 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()) } } -impl ReverseIter for TreeSet { +impl ReverseIter for TreeSet { /// Visit all values in reverse order pure fn each_reverse(&self, f: fn(&T) -> bool) { self.map.each_key_reverse(f) } } -impl Eq for TreeSet { +impl Eq for TreeSet { pure fn eq(&self, other: &TreeSet) -> bool { self.map == other.map } pure fn ne(&self, other: &TreeSet) -> bool { self.map != other.map } } -impl Ord for TreeSet { +impl Ord for TreeSet { #[inline(always)] pure fn lt(&self, other: &TreeSet) -> bool { self.map < other.map } #[inline(always)] @@ -275,7 +275,7 @@ impl Ord for TreeSet { pure fn gt(&self, other: &TreeSet) -> bool { self.map > other.map } } -impl Container for TreeSet { +impl Container for TreeSet { /// Return the number of elements in the set pure fn len(&self) -> uint { self.map.len() } @@ -283,12 +283,12 @@ impl Container for TreeSet { pure fn is_empty(&self) -> bool { self.map.is_empty() } } -impl Mutable for TreeSet { +impl Mutable for TreeSet { /// Clear the set, removing all values. fn clear(&mut self) { self.map.clear() } } -impl Set for TreeSet { +impl Set for TreeSet { /// Return true if the set contains a value pure fn contains(&self, value: &T) -> bool { self.map.contains_key(value) @@ -510,7 +510,7 @@ impl Set for TreeSet { } } -impl TreeSet { +impl TreeSet { /// Create an empty TreeSet static pure fn new() -> TreeSet { TreeSet{map: TreeMap::new()} } @@ -526,7 +526,7 @@ pub struct TreeSetIterator { priv iter: TreeMapIterator } -impl TreeSetIterator { +impl TreeSetIterator { /// Returns the current node, or None if this iterator is at the end. fn get(&const self) -> Option<&self/T> { match self.iter.get() { @@ -538,7 +538,7 @@ impl TreeSetIterator { /// Advance the iterator to the next node (in order). If this iterator is /// finished, does nothing. -pub fn set_next(iter: &mut TreeSetIterator/&a) { +pub fn set_next(iter: &mut TreeSetIterator/&a) { map_next(&mut iter.iter); } @@ -552,14 +552,14 @@ struct TreeNode { level: uint } -impl TreeNode { +impl TreeNode { #[inline(always)] static pure 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>, +pure fn each(node: &r/Option<~TreeNode>, f: fn(&(&r/K, &r/V)) -> bool) { do node.iter |x| { each(&x.left, f); @@ -567,7 +567,7 @@ pure fn each(node: &r/Option<~TreeNode>, } } -pure fn each_reverse(node: &r/Option<~TreeNode>, +pure fn each_reverse(node: &r/Option<~TreeNode>, f: fn(&(&r/K, &r/V)) -> bool) { do node.iter |x| { each_reverse(&x.right, f); @@ -576,7 +576,7 @@ pure fn each_reverse(node: &r/Option<~TreeNode>, } // Remove left horizontal link by rotating right -fn skew(node: &mut ~TreeNode) { +fn skew(node: &mut ~TreeNode) { if node.left.map_default(false, |x| x.level == node.level) { let mut save = node.left.swap_unwrap(); node.left <-> save.right; // save.right now None @@ -587,7 +587,7 @@ fn skew(node: &mut ~TreeNode) { // Remove dual horizontal link by rotating left and increasing level of // the parent -fn split(node: &mut ~TreeNode) { +fn split(node: &mut ~TreeNode) { if node.right.map_default(false, |x| x.right.map_default(false, |y| y.level == node.level)) { let mut save = node.right.swap_unwrap(); @@ -598,7 +598,7 @@ fn split(node: &mut ~TreeNode) { } } -fn insert(node: &mut Option<~TreeNode>, key: K, +fn insert(node: &mut Option<~TreeNode>, key: K, value: V) -> bool { match *node { Some(ref mut save) => { @@ -625,8 +625,8 @@ fn insert(node: &mut Option<~TreeNode>, key: K, } } -fn remove(node: &mut Option<~TreeNode>, key: &K) -> bool { - fn heir_swap(node: &mut ~TreeNode, +fn remove(node: &mut Option<~TreeNode>, key: &K) -> bool { + fn heir_swap(node: &mut ~TreeNode, child: &mut Option<~TreeNode>) { // *could* be done without recursion, but it won't borrow check do child.mutate |mut child| { @@ -772,7 +772,7 @@ mod test_treemap { assert m.find(&k1) == Some(&v1); } - fn check_equal(ctrl: &[(K, V)], map: &TreeMap) { + fn check_equal(ctrl: &[(K, V)], map: &TreeMap) { assert ctrl.is_empty() == map.is_empty(); for ctrl.each |x| { let &(k, v) = x; @@ -792,7 +792,7 @@ mod test_treemap { } } - fn check_left(node: &Option<~TreeNode>, + fn check_left(node: &Option<~TreeNode>, parent: &~TreeNode) { match *node { Some(ref r) => { @@ -805,7 +805,7 @@ mod test_treemap { } } - fn check_right(node: &Option<~TreeNode>, + fn check_right(node: &Option<~TreeNode>, parent: &~TreeNode, parent_red: bool) { match *node { Some(ref r) => { @@ -820,7 +820,7 @@ mod test_treemap { } } - fn check_structure(map: &TreeMap) { + fn check_structure(map: &TreeMap) { match map.root { Some(ref r) => { check_left(&r.left, r); @@ -838,7 +838,7 @@ mod test_treemap { check_equal(ctrl, &map); assert map.find(&5).is_none(); - let rng = rand::seeded_rng(&~[42]); + let rng = rand::seeded_rng(&[42]); for 3.times { for 90.times { diff --git a/src/libstd/uv_global_loop.rs b/src/libstd/uv_global_loop.rs index 3152f0b540524..401cecf881141 100644 --- a/src/libstd/uv_global_loop.rs +++ b/src/libstd/uv_global_loop.rs @@ -17,7 +17,7 @@ use uv_iotask::{IoTask, spawn_iotask}; use core::either::{Left, Right}; use core::libc; -use core::pipes::{Port, Chan, SharedChan, select2i}; +use core::comm::{Port, Chan, SharedChan, select2i}; use core::private::global::{global_data_clone_create, global_data_clone}; use core::private::weak_task::weaken_task; @@ -98,7 +98,7 @@ fn get_monitor_task_gl() -> IoTask { fn spawn_loop() -> IoTask { let builder = do task().add_wrapper |task_body| { - fn~(move task_body) { + fn~() { // The I/O loop task also needs to be weak so it doesn't keep // the runtime alive unsafe { @@ -116,7 +116,7 @@ fn spawn_loop() -> IoTask { } }; let builder = builder.unlinked(); - spawn_iotask(move builder) + spawn_iotask(builder) } #[cfg(test)] @@ -133,7 +133,7 @@ mod test { use core::task; use core::cast::transmute; use core::libc::c_void; - use core::pipes::{stream, SharedChan, Chan}; + use core::comm::{stream, SharedChan, Chan}; extern fn simple_timer_close_cb(timer_ptr: *ll::uv_timer_t) { unsafe { diff --git a/src/libstd/uv_iotask.rs b/src/libstd/uv_iotask.rs index a93bdf86a6428..52956f152fe2b 100644 --- a/src/libstd/uv_iotask.rs +++ b/src/libstd/uv_iotask.rs @@ -19,7 +19,7 @@ use ll = uv_ll; use core::libc::c_void; use core::libc; -use core::pipes::{stream, Port, Chan, SharedChan}; +use core::comm::{stream, Port, Chan, SharedChan}; use core::prelude::*; use core::ptr::addr_of; use core::task::TaskBuilder; @@ -78,7 +78,7 @@ pub fn spawn_iotask(task: task::TaskBuilder) -> IoTask { */ pub unsafe fn interact(iotask: &IoTask, cb: fn~(*c_void)) { - send_msg(iotask, Interaction(move cb)); + send_msg(iotask, Interaction(cb)); } /** @@ -150,7 +150,7 @@ struct IoTaskLoopData { fn send_msg(iotask: &IoTask, msg: IoTaskMsg) { - iotask.op_chan.send(move msg); + iotask.op_chan.send(msg); unsafe { ll::async_send(iotask.async_handle); } diff --git a/src/libstd/uv_ll.rs b/src/libstd/uv_ll.rs index be6b79059a9f2..dd54620c83d28 100644 --- a/src/libstd/uv_ll.rs +++ b/src/libstd/uv_ll.rs @@ -39,7 +39,7 @@ use core::ptr::to_unsafe_ptr; use core::ptr; use core::str; use core::vec; -use core::pipes::{stream, Chan, SharedChan, Port}; +use core::comm::{stream, Chan, SharedChan, Port}; // libuv struct mappings pub struct uv_ip4_addr { @@ -1252,8 +1252,7 @@ pub mod test { get_data_for_uv_handle(stream as *libc::c_void) as *request_wrapper; let buf_base = get_base_from_buf(buf); - let buf_len = get_len_from_buf(buf); - let bytes = vec::from_buf(buf_base, buf_len as uint); + let bytes = vec::from_buf(buf_base, nread as uint); let read_chan = (*client_data).read_chan.clone(); let msg_from_server = str::from_bytes(bytes); read_chan.send(msg_from_server); @@ -1445,7 +1444,7 @@ pub mod test { buf_base as uint, buf_len as uint, nread)); - let bytes = vec::from_buf(buf_base, buf_len); + let bytes = vec::from_buf(buf_base, nread as uint); let request_str = str::from_bytes(bytes); let client_data = get_data_for_uv_handle( @@ -1453,7 +1452,7 @@ pub mod test { let server_kill_msg = (*client_data).server_kill_msg; let write_req = (*client_data).server_write_req; - if (str::contains(request_str, server_kill_msg)) { + if str::contains(request_str, server_kill_msg) { log(debug, ~"SERVER: client req contains kill_msg!"); log(debug, ~"SERVER: sending response to client"); read_stop(client_stream_ptr); diff --git a/src/libstd/workcache.rs b/src/libstd/workcache.rs index d652b18cfad47..8ce68a41f81bf 100644 --- a/src/libstd/workcache.rs +++ b/src/libstd/workcache.rs @@ -16,11 +16,11 @@ use serialize::{Encoder, Encodable, Decoder, Decodable}; use sort; use core::cmp; -use core::dvec; use core::either::{Either, Left, Right}; use core::io; use core::option; -use core::pipes::{recv, oneshot, PortOne, send_one}; +use core::comm::{oneshot, PortOne, send_one}; +use core::pipes::recv; use core::prelude::*; use core::result; use core::run; @@ -139,19 +139,18 @@ impl WorkKey { type WorkMap = LinearMap; -pub impl WorkMap: Encodable { +pub impl Encodable for WorkMap { fn encode(&self, s: &S) { - let d = dvec::DVec(); + let mut d = ~[]; for self.each |&(k, v)| { d.push((copy *k, copy *v)) } - let mut v = d.get(); - sort::tim_sort(v); - v.encode(s) + sort::tim_sort(d); + d.encode(s) } } -pub impl WorkMap: Decodable { +pub impl Decodable for WorkMap { static fn decode(&self, d: &D) -> WorkMap { let v : ~[(WorkKey,~str)] = Decodable::decode(d); let mut w = LinearMap::new(); @@ -237,7 +236,7 @@ fn json_encode>(t: &T) -> ~str { 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(move j)) + Decodable::decode(&json::Decoder(j)) } } @@ -262,9 +261,7 @@ impl Context { Context{db: db, logger: lg, cfg: cfg, freshness: LinearMap::new()} } - fn prep - Decodable>( + fn prep + Decodable>( @self, fn_name:&str, blk: fn(@Mut)->Work) -> Work { @@ -280,9 +277,8 @@ trait TPrep { fn declare_input(&self, kind:&str, name:&str, val:&str); fn is_fresh(&self, cat:&str, kind:&str, name:&str, val:&str) -> bool; fn all_fresh(&self, cat:&str, map:&WorkMap) -> bool; - fn exec - Decodable>(&self, blk: ~fn(&Exec) -> T) -> Work; + fn exec + Decodable>( + &self, blk: ~fn(&Exec) -> T) -> Work; } impl TPrep for @Mut { @@ -320,25 +316,22 @@ impl TPrep for @Mut { return true; } - fn exec - Decodable>(&self, - blk: ~fn(&Exec) -> T) -> Work { - - let mut bo = Some(move blk); + fn exec + Decodable>( + &self, blk: ~fn(&Exec) -> T) -> Work { + let mut bo = Some(blk); do self.borrow_imm |p| { let cached = do p.ctxt.db.borrow_mut |db| { db.prepare(p.fn_name, &p.declared_inputs) }; - match move cached { + match cached { Some((ref disc_in, ref disc_out, ref res)) if self.all_fresh("declared input", &p.declared_inputs) && self.all_fresh("discovered input", disc_in) && self.all_fresh("discovered output", disc_out) => { - Work::new(*self, move Left(json_decode(*res))) + Work::new(*self, Left(json_decode(*res))) } _ => { @@ -346,48 +339,42 @@ impl TPrep for @Mut { let mut blk = None; blk <-> bo; let blk = blk.unwrap(); - let chan = ~mut Some(move chan); - do task::spawn |move blk, move chan| { + let chan = ~mut Some(chan); + do task::spawn || { let exe = Exec{discovered_inputs: LinearMap::new(), discovered_outputs: LinearMap::new()}; let chan = option::swap_unwrap(&mut *chan); let v = blk(&exe); - send_one(move chan, (move exe, move v)); + send_one(chan, (exe, v)); } - Work::new(*self, move Right(move port)) + Work::new(*self, Right(port)) } } } } } -impl - Decodable> - Work { +impl + Decodable> Work { static fn new(p: @Mut, e: Either>) -> Work { - move Work { prep: p, res: Some(move e) } + Work { prep: p, res: Some(e) } } } // FIXME (#3724): movable self. This should be in impl Work. -fn unwrap - Decodable>(w: Work) -> T { - - let mut ww = move w; +fn unwrap + Decodable>( + w: Work) -> T { + let mut ww = w; let mut s = None; ww.res <-> s; - match move s { + match s { None => fail!(), - Some(Left(move v)) => move v, - Some(Right(move port)) => { - - let (exe, v) = match recv(move port) { - oneshot::send(move data) => move data + Some(Left(v)) => v, + Some(Right(port)) => { + let (exe, v) = match recv(port) { + oneshot::send(data) => data }; let s = json_encode(&v); @@ -401,7 +388,7 @@ fn unwrap ident: Encodable { +pub impl Encodable for ident { fn encode(&self, s: &S) { let intr = match unsafe { task::local_data::local_data_get(interner_key!()) @@ -45,7 +45,7 @@ pub impl ident: Encodable { } } -pub impl ident: Decodable { +pub impl Decodable for ident { static fn decode(d: &D) -> ident { let intr = match unsafe { task::local_data::local_data_get(interner_key!()) @@ -58,7 +58,7 @@ pub impl ident: Decodable { } } -pub impl ident: to_bytes::IterBytes { +pub impl to_bytes::IterBytes for ident { pure fn iter_bytes(&self, +lsb0: bool, f: to_bytes::Cb) { self.repr.iter_bytes(lsb0, f) } @@ -67,6 +67,12 @@ pub impl ident: to_bytes::IterBytes { // Functions may or may not have names. pub type fn_ident = Option; +pub struct Lifetime { + id: node_id, + span: span, + ident: ident +} + #[auto_encode] #[auto_decode] #[deriving_eq] @@ -167,9 +173,9 @@ pub type meta_item = spanned; #[auto_decode] #[deriving_eq] pub enum meta_item_ { - meta_word(~str), - meta_list(~str, ~[@meta_item]), - meta_name_value(~str, lit), + meta_word(@~str), + meta_list(@~str, ~[@meta_item]), + meta_name_value(@~str, lit), } pub type blk = spanned; @@ -211,7 +217,7 @@ pub enum binding_mode { bind_infer } -pub impl binding_mode : to_bytes::IterBytes { +pub impl to_bytes::IterBytes for binding_mode { pure fn iter_bytes(&self, +lsb0: bool, f: to_bytes::Cb) { match *self { bind_by_copy => 0u8.iter_bytes(lsb0, f), @@ -256,7 +262,7 @@ pub enum pat_ { #[deriving_eq] pub enum mutability { m_mutbl, m_imm, m_const, } -pub impl mutability : to_bytes::IterBytes { +pub impl to_bytes::IterBytes for mutability { pure fn iter_bytes(&self, +lsb0: bool, f: to_bytes::Cb) { (*self as u8).iter_bytes(lsb0, f) } @@ -269,13 +275,13 @@ pub enum Abi { RustAbi } -pub impl Abi : to_bytes::IterBytes { +pub impl to_bytes::IterBytes for Abi { pure fn iter_bytes(&self, +lsb0: bool, f: to_bytes::Cb) { (*self as uint).iter_bytes(lsb0, f) } } -pub impl Abi : ToStr { +pub impl ToStr for Abi { pure fn to_str(&self) -> ~str { match *self { RustAbi => ~"\"rust\"" @@ -292,13 +298,13 @@ pub enum Sigil { ManagedSigil } -pub impl Sigil : to_bytes::IterBytes { +pub impl to_bytes::IterBytes for Sigil { pure fn iter_bytes(&self, +lsb0: bool, f: to_bytes::Cb) { (*self as uint).iter_bytes(lsb0, f) } } -pub impl Sigil : ToStr { +pub impl ToStr for Sigil { pure fn to_str(&self) -> ~str { match *self { BorrowedSigil => ~"&", @@ -377,7 +383,7 @@ pub enum inferable { infer(node_id) } -pub impl inferable : to_bytes::IterBytes { +pub impl to_bytes::IterBytes for inferable { pure fn iter_bytes(&self, +lsb0: bool, f: to_bytes::Cb) { match *self { expl(ref t) => @@ -395,7 +401,7 @@ pub impl inferable : to_bytes::IterBytes { #[deriving_eq] pub enum rmode { by_ref, by_val, by_copy } -pub impl rmode : to_bytes::IterBytes { +pub impl to_bytes::IterBytes for rmode { pure fn iter_bytes(&self, +lsb0: bool, f: to_bytes::Cb) { (*self as u8).iter_bytes(lsb0, f) } @@ -736,13 +742,13 @@ pub enum trait_method { #[deriving_eq] pub enum int_ty { ty_i, ty_char, ty_i8, ty_i16, ty_i32, ty_i64, } -pub impl int_ty : ToStr { +pub impl ToStr for int_ty { pure fn to_str(&self) -> ~str { ::ast_util::int_ty_to_str(*self) } } -pub impl int_ty : to_bytes::IterBytes { +pub impl to_bytes::IterBytes for int_ty { pure fn iter_bytes(&self, +lsb0: bool, f: to_bytes::Cb) { (*self as u8).iter_bytes(lsb0, f) } @@ -753,13 +759,13 @@ pub impl int_ty : to_bytes::IterBytes { #[deriving_eq] pub enum uint_ty { ty_u, ty_u8, ty_u16, ty_u32, ty_u64, } -pub impl uint_ty : ToStr { +pub impl ToStr for uint_ty { pure fn to_str(&self) -> ~str { ::ast_util::uint_ty_to_str(*self) } } -pub impl uint_ty : to_bytes::IterBytes { +pub impl to_bytes::IterBytes for uint_ty { pure fn iter_bytes(&self, +lsb0: bool, f: to_bytes::Cb) { (*self as u8).iter_bytes(lsb0, f) } @@ -770,13 +776,13 @@ pub impl uint_ty : to_bytes::IterBytes { #[deriving_eq] pub enum float_ty { ty_f, ty_f32, ty_f64, } -pub impl float_ty : ToStr { +pub impl ToStr for float_ty { pure fn to_str(&self) -> ~str { ::ast_util::float_ty_to_str(*self) } } -pub impl float_ty : to_bytes::IterBytes { +pub impl to_bytes::IterBytes for float_ty { pure fn iter_bytes(&self, +lsb0: bool, f: to_bytes::Cb) { (*self as u8).iter_bytes(lsb0, f) } @@ -830,7 +836,7 @@ pub enum Onceness { Many } -pub impl Onceness : ToStr { +pub impl ToStr for Onceness { pure fn to_str(&self) -> ~str { match *self { Once => ~"once", @@ -839,7 +845,7 @@ pub impl Onceness : ToStr { } } -pub impl Onceness : to_bytes::IterBytes { +pub impl to_bytes::IterBytes for Onceness { pure fn iter_bytes(&self, +lsb0: bool, f: to_bytes::Cb) { (*self as uint).iter_bytes(lsb0, f); } @@ -889,7 +895,7 @@ pub enum ty_ { ty_infer, } -pub impl Ty : to_bytes::IterBytes { +pub impl to_bytes::IterBytes for Ty { pure fn iter_bytes(&self, +lsb0: bool, f: to_bytes::Cb) { to_bytes::iter_bytes_2(&self.span.lo, &self.span.hi, lsb0, f); } @@ -925,7 +931,7 @@ pub enum purity { extern_fn, // declared with "extern fn" } -pub impl purity : ToStr { +pub impl ToStr for purity { pure fn to_str(&self) -> ~str { match *self { impure_fn => ~"impure", @@ -936,7 +942,7 @@ pub impl purity : ToStr { } } -pub impl purity : to_bytes::IterBytes { +pub impl to_bytes::IterBytes for purity { pure fn iter_bytes(&self, +lsb0: bool, f: to_bytes::Cb) { (*self as u8).iter_bytes(lsb0, f) } @@ -951,7 +957,7 @@ pub enum ret_style { return_val, // everything else } -pub impl ret_style : to_bytes::IterBytes { +pub impl to_bytes::IterBytes for ret_style { pure fn iter_bytes(&self, +lsb0: bool, f: to_bytes::Cb) { (*self as u8).iter_bytes(lsb0, f) } @@ -1115,8 +1121,8 @@ pub struct view_item { #[auto_decode] #[deriving_eq] pub enum view_item_ { - view_item_use(ident, ~[@meta_item], node_id), - view_item_import(~[@view_path]), + view_item_extern_mod(ident, ~[@meta_item], node_id), + view_item_use(~[@view_path]), } // Meta-data associated with an item @@ -1232,7 +1238,7 @@ pub enum item_ { #[deriving_eq] pub enum struct_mutability { struct_mutable, struct_immutable } -pub impl struct_mutability : to_bytes::IterBytes { +pub impl to_bytes::IterBytes for struct_mutability { pure fn iter_bytes(&self, +lsb0: bool, f: to_bytes::Cb) { (*self as u8).iter_bytes(lsb0, f) } diff --git a/src/libsyntax/ast_map.rs b/src/libsyntax/ast_map.rs index 9eeee943f8b24..74f67808a5e97 100644 --- a/src/libsyntax/ast_map.rs +++ b/src/libsyntax/ast_map.rs @@ -34,7 +34,7 @@ pub enum path_elt { path_name(ident) } -pub impl path_elt : cmp::Eq { +pub impl cmp::Eq for path_elt { pure fn eq(&self, other: &path_elt) -> bool { match (*self) { path_mod(e0a) => { @@ -193,7 +193,7 @@ pub fn map_fn(fk: visit::fn_kind, decl: fn_decl, body: blk, cx.local_id += 1u; } match fk { - visit::fk_dtor(tps, ref attrs, self_id, parent_id) => { + visit::fk_dtor(ref tps, ref attrs, self_id, parent_id) => { let dt = @spanned { node: ast::struct_dtor_ { id: id, @@ -203,7 +203,7 @@ pub fn map_fn(fk: visit::fn_kind, decl: fn_decl, body: blk, }, span: sp, }; - cx.map.insert(id, node_dtor(/* FIXME (#2543) */ copy tps, dt, + cx.map.insert(id, node_dtor(/* FIXME (#2543) */ copy *tps, dt, parent_id, @/* FIXME (#2543) */ copy cx.path)); } @@ -286,7 +286,7 @@ pub fn map_item(i: @item, &&cx: @mut Ctx, v: vt) { map_struct_def(struct_def, node_item(i, item_path), i.ident, cx, v); } - item_trait(_, traits, ref methods) => { + item_trait(_, ref traits, ref methods) => { for traits.each |p| { cx.map.insert(p.ref_id, node_item(i, item_path)); } diff --git a/src/libsyntax/ast_util.rs b/src/libsyntax/ast_util.rs index 335dd4e3fa247..fec3a961a52a2 100644 --- a/src/libsyntax/ast_util.rs +++ b/src/libsyntax/ast_util.rs @@ -48,10 +48,10 @@ pub pure fn stmt_id(s: stmt) -> node_id { } } -pub fn variant_def_ids(d: def) -> {enm: def_id, var: def_id} { +pub fn variant_def_ids(d: def) -> (def_id, def_id) { match d { def_variant(enum_id, var_id) => { - return {enm: enum_id, var: var_id} + return (enum_id, var_id); } _ => fail!(~"non-variant in variant_def_ids") } @@ -198,7 +198,7 @@ pub pure fn is_call_expr(e: @expr) -> bool { } // This makes def_id hashable -pub impl def_id : to_bytes::IterBytes { +pub impl to_bytes::IterBytes for def_id { #[inline(always)] pure fn iter_bytes(&self, +lsb0: bool, f: to_bytes::Cb) { to_bytes::iter_bytes_2(&self.crate, &self.node, lsb0, f); @@ -303,7 +303,7 @@ pub trait inlined_item_utils { fn accept(&self, e: E, v: visit::vt); } -pub impl inlined_item: inlined_item_utils { +pub impl inlined_item_utils for inlined_item { fn ident(&self) -> ident { match *self { ii_item(i) => /* FIXME (#2543) */ copy i.ident, @@ -327,8 +327,8 @@ pub impl inlined_item: inlined_item_utils { ii_item(i) => (v.visit_item)(i, e, v), ii_foreign(i) => (v.visit_foreign_item)(i, e, v), ii_method(_, m) => visit::visit_method_helper(m, e, v), - ii_dtor(ref dtor, _, tps, parent_id) => { - visit::visit_struct_dtor_helper((*dtor), tps, parent_id, e, v); + ii_dtor(/*bad*/ copy dtor, _, /*bad*/ copy tps, parent_id) => { + visit::visit_struct_dtor_helper(dtor, tps, parent_id, e, v); } } } @@ -395,8 +395,8 @@ pub fn id_visitor(vfn: fn@(node_id)) -> visit::vt<()> { visit_view_item: fn@(vi: @view_item) { match vi.node { - view_item_use(_, _, id) => vfn(id), - view_item_import(vps) => { + view_item_extern_mod(_, _, id) => vfn(id), + view_item_use(vps) => { for vec::each(vps) |vp| { match vp.node { view_path_simple(_, _, _, id) => vfn(id), diff --git a/src/libsyntax/attr.rs b/src/libsyntax/attr.rs index e3d1fb9781b2e..14ffb1cab5da4 100644 --- a/src/libsyntax/attr.rs +++ b/src/libsyntax/attr.rs @@ -29,24 +29,24 @@ use std; /* Constructors */ -pub fn mk_name_value_item_str(name: ~str, value: ~str) +pub fn mk_name_value_item_str(name: @~str, value: @~str) -> @ast::meta_item { - let value_lit = dummy_spanned(ast::lit_str(@value)); - return mk_name_value_item(name, value_lit); + let value_lit = dummy_spanned(ast::lit_str(value)); + mk_name_value_item(name, value_lit) } -pub fn mk_name_value_item(name: ~str, +value: ast::lit) +pub fn mk_name_value_item(name: @~str, +value: ast::lit) -> @ast::meta_item { - return @dummy_spanned(ast::meta_name_value(name, value)); + @dummy_spanned(ast::meta_name_value(name, value)) } -pub fn mk_list_item(name: ~str, +items: ~[@ast::meta_item]) -> +pub fn mk_list_item(name: @~str, +items: ~[@ast::meta_item]) -> @ast::meta_item { - return @dummy_spanned(ast::meta_list(name, items)); + @dummy_spanned(ast::meta_list(name, items)) } -pub fn mk_word_item(name: ~str) -> @ast::meta_item { - return @dummy_spanned(ast::meta_word(name)); +pub fn mk_word_item(name: @~str) -> @ast::meta_item { + @dummy_spanned(ast::meta_word(name)) } pub fn mk_attr(item: @ast::meta_item) -> ast::attribute { @@ -60,7 +60,7 @@ pub fn mk_sugared_doc_attr(text: ~str, let lit = spanned(lo, hi, ast::lit_str(@text)); let attr = ast::attribute_ { style: doc_comment_style(text), - value: spanned(lo, hi, ast::meta_name_value(~"doc", lit)), + value: spanned(lo, hi, ast::meta_name_value(@~"doc", lit)), is_sugared_doc: true }; spanned(lo, hi, attr) @@ -80,9 +80,9 @@ pub fn attr_metas(attrs: ~[ast::attribute]) -> ~[@ast::meta_item] { pub fn desugar_doc_attr(attr: &ast::attribute) -> ast::attribute { if attr.node.is_sugared_doc { let comment = get_meta_item_value_str(@attr.node.value).get(); - let meta = mk_name_value_item_str(~"doc", - strip_doc_comment_decoration(comment)); - return mk_attr(meta); + let meta = mk_name_value_item_str(@~"doc", + @strip_doc_comment_decoration(*comment)); + mk_attr(meta) } else { *attr } @@ -90,15 +90,15 @@ pub fn desugar_doc_attr(attr: &ast::attribute) -> ast::attribute { /* Accessors */ -pub fn get_attr_name(attr: ast::attribute) -> ~str { +pub pure fn get_attr_name(attr: &ast::attribute) -> @~str { get_meta_item_name(@attr.node.value) } -pub fn get_meta_item_name(meta: @ast::meta_item) -> ~str { +pub pure fn get_meta_item_name(meta: @ast::meta_item) -> @~str { match meta.node { - ast::meta_word(ref n) => (*n), - ast::meta_name_value(ref n, _) => (*n), - ast::meta_list(ref n, _) => (*n) + ast::meta_word(n) => n, + ast::meta_name_value(n, _) => n, + ast::meta_list(n, _) => n, } } @@ -106,13 +106,15 @@ pub fn get_meta_item_name(meta: @ast::meta_item) -> ~str { * Gets the string value if the meta_item is a meta_name_value variant * containing a string, otherwise none */ -pub fn get_meta_item_value_str(meta: @ast::meta_item) -> Option<~str> { +pub fn get_meta_item_value_str(meta: @ast::meta_item) -> Option<@~str> { match meta.node { - ast::meta_name_value(_, v) => match v.node { - ast::lit_str(s) => option::Some(*s), - _ => option::None + ast::meta_name_value(_, v) => { + match v.node { + ast::lit_str(s) => Some(s), + _ => None, + } }, - _ => option::None + _ => None } } @@ -130,11 +132,11 @@ pub fn get_meta_item_list(meta: @ast::meta_item) * a tuple containing the name and string value, otherwise `none` */ pub fn get_name_value_str_pair(item: @ast::meta_item) - -> Option<(~str, ~str)> { + -> Option<(@~str, @~str)> { match attr::get_meta_item_value_str(item) { - Some(ref value) => { + Some(value) => { let name = attr::get_meta_item_name(item); - Some((name, (*value))) + Some((name, value)) } None => None } @@ -146,14 +148,13 @@ pub fn get_name_value_str_pair(item: @ast::meta_item) /// Search a list of attributes and return only those with a specific name pub fn find_attrs_by_name(attrs: &[ast::attribute], name: &str) -> ~[ast::attribute] { - let filter: &fn(a: &ast::attribute) -> Option = |a| { - if name == get_attr_name(*a) { - option::Some(*a) + do vec::filter_mapped(attrs) |a| { + if name == *get_attr_name(a) { + Some(*a) } else { - option::None + None } - }; - return vec::filter_mapped(attrs, filter); + } } /// Search a list of meta items and return only those with a specific name @@ -161,7 +162,7 @@ pub fn find_meta_items_by_name(metas: &[@ast::meta_item], name: &str) -> ~[@ast::meta_item] { let mut rs = ~[]; for metas.each |mi| { - if name == get_meta_item_name(*mi) { + if name == *get_meta_item_name(*mi) { rs.push(*mi) } } @@ -192,13 +193,15 @@ fn eq(a: @ast::meta_item, b: @ast::meta_item) -> bool { } _ => false }, - ast::meta_list(*) => { - - // ~[Fixme-sorting] - // FIXME (#607): Needs implementing - // This involves probably sorting the list by name and - // meta_item variant - fail!(~"unimplemented meta_item variant") + ast::meta_list(ref na, misa) => match b.node { + ast::meta_list(ref nb, misb) => { + if na != nb { return false; } + for misa.each |&mi| { + if !contains(misb, mi) { return false; } + } + true + } + _ => false } } } @@ -212,36 +215,39 @@ pub fn attrs_contains_name(attrs: &[ast::attribute], name: &str) -> bool { !find_attrs_by_name(attrs, name).is_empty() } -pub fn first_attr_value_str_by_name(attrs: ~[ast::attribute], name: ~str) - -> Option<~str> { +pub fn first_attr_value_str_by_name(attrs: ~[ast::attribute], name: &str) + -> Option<@~str> { let mattrs = find_attrs_by_name(attrs, name); - if vec::len(mattrs) > 0u { - return get_meta_item_value_str(attr_meta(mattrs[0])); + if mattrs.len() > 0 { + get_meta_item_value_str(attr_meta(mattrs[0])) + } else { + None } - return option::None; } -fn last_meta_item_by_name(items: ~[@ast::meta_item], name: ~str) +fn last_meta_item_by_name(items: ~[@ast::meta_item], name: &str) -> Option<@ast::meta_item> { let items = attr::find_meta_items_by_name(items, name); vec::last_opt(items) } -pub fn last_meta_item_value_str_by_name(items: ~[@ast::meta_item], name: ~str) - -> Option<~str> { +pub fn last_meta_item_value_str_by_name(items: ~[@ast::meta_item], name: &str) + -> Option<@~str> { match last_meta_item_by_name(items, name) { - Some(item) => match attr::get_meta_item_value_str(item) { - Some(ref value) => Some((*value)), + Some(item) => { + match attr::get_meta_item_value_str(item) { + Some(value) => Some(value), + None => None + } + }, None => None - }, - None => None } } -pub fn last_meta_item_list_by_name(items: ~[@ast::meta_item], name: ~str) +pub fn last_meta_item_list_by_name(items: ~[@ast::meta_item], name: &str) -> Option<~[@ast::meta_item]> { match last_meta_item_by_name(items, name) { @@ -253,34 +259,33 @@ pub fn last_meta_item_list_by_name(items: ~[@ast::meta_item], name: ~str) /* Higher-level applications */ -// FIXME (#607): This needs to sort by meta_item variant in addition to -// the item name (See [Fixme-sorting]) pub fn sort_meta_items(+items: ~[@ast::meta_item]) -> ~[@ast::meta_item] { - pure fn lteq(ma: &@ast::meta_item, mb: &@ast::meta_item) -> bool { - pure fn key(m: &ast::meta_item) -> ~str { - match m.node { - ast::meta_word(ref name) => (*name), - ast::meta_name_value(ref name, _) => (*name), - ast::meta_list(ref name, _) => (*name) - } - } - key(*ma) <= key(*mb) + // This is sort of stupid here, converting to a vec of mutables and back + let mut v = items; + do std::sort::quick_sort(v) |ma, mb| { + get_meta_item_name(*ma) <= get_meta_item_name(*mb) } - // This is sort of stupid here, converting to a vec of mutables and back - let mut v: ~[@ast::meta_item] = items; - std::sort::quick_sort(v, lteq); - move v + // There doesn't seem to be a more optimal way to do this + do v.map |&m| { + match m.node { + ast::meta_list(n, mis) => @spanned { + node: ast::meta_list(n, sort_meta_items(mis)), + .. *m + }, + _ => m + } + } } -pub fn remove_meta_items_by_name(items: ~[@ast::meta_item], name: ~str) -> +pub fn remove_meta_items_by_name(items: ~[@ast::meta_item], name: &str) -> ~[@ast::meta_item] { return vec::filter_mapped(items, |item| { - if get_meta_item_name(*item) != name { - option::Some(*item) + if name != *get_meta_item_name(*item) { + Some(*item) } else { - option::None + None } }); } @@ -301,21 +306,21 @@ pub fn find_linkage_metas(attrs: &[ast::attribute]) -> ~[@ast::meta_item] { pub fn foreign_abi(attrs: ~[ast::attribute]) -> Either<~str, ast::foreign_abi> { return match attr::first_attr_value_str_by_name(attrs, ~"abi") { - option::None => { - either::Right(ast::foreign_abi_cdecl) - } - option::Some(~"rust-intrinsic") => { - either::Right(ast::foreign_abi_rust_intrinsic) - } - option::Some(~"cdecl") => { - either::Right(ast::foreign_abi_cdecl) - } - option::Some(~"stdcall") => { - either::Right(ast::foreign_abi_stdcall) - } - option::Some(ref t) => { - either::Left(~"unsupported abi: " + (*t)) - } + None => { + Right(ast::foreign_abi_cdecl) + } + Some(@~"rust-intrinsic") => { + Right(ast::foreign_abi_rust_intrinsic) + } + Some(@~"cdecl") => { + Right(ast::foreign_abi_cdecl) + } + Some(@~"stdcall") => { + Right(ast::foreign_abi_stdcall) + } + Some(t) => { + Left(~"unsupported abi: " + *t) + } }; } @@ -338,8 +343,8 @@ pub fn find_inline_attr(attrs: &[ast::attribute]) -> inline_attr { // FIXME (#2809)---validate the usage of #[inline] and #[inline(always)] do vec::foldl(ia_none, attrs) |ia,attr| { match attr.node.value.node { - ast::meta_word(~"inline") => ia_hint, - ast::meta_list(~"inline", items) => { + ast::meta_word(@~"inline") => ia_hint, + ast::meta_list(@~"inline", items) => { if !vec::is_empty(find_meta_items_by_name(items, ~"always")) { ia_always } else if !vec::is_empty( @@ -364,7 +369,7 @@ pub fn require_unique_names(diagnostic: span_handler, // FIXME: How do I silence the warnings? --pcw (#2619) if !set.insert(name) { diagnostic.span_fatal(meta.span, - fmt!("duplicate meta item `%s`", name)); + fmt!("duplicate meta item `%s`", *name)); } } } diff --git a/src/libsyntax/codemap.rs b/src/libsyntax/codemap.rs index 10a4e12bef4fc..1ab55fe9035bc 100644 --- a/src/libsyntax/codemap.rs +++ b/src/libsyntax/codemap.rs @@ -46,71 +46,71 @@ pub enum CharPos = uint; // XXX: Lots of boilerplate in these impls, but so far my attempts to fix // have been unsuccessful -pub impl BytePos: Pos { +pub impl Pos for BytePos { static pure fn from_uint(n: uint) -> BytePos { BytePos(n) } pure fn to_uint(&self) -> uint { **self } } -pub impl BytePos: cmp::Eq { +pub impl cmp::Eq for BytePos { pure fn eq(&self, other: &BytePos) -> bool { **self == **other } pure fn ne(&self, other: &BytePos) -> bool { !(*self).eq(other) } } -pub impl BytePos: cmp::Ord { +pub 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 } } -pub impl BytePos: Add { +pub impl Add for BytePos { pure fn add(&self, rhs: &BytePos) -> BytePos { BytePos(**self + **rhs) } } -pub impl BytePos: Sub { +pub impl Sub for BytePos { pure fn sub(&self, rhs: &BytePos) -> BytePos { BytePos(**self - **rhs) } } -pub impl BytePos: to_bytes::IterBytes { +pub impl to_bytes::IterBytes for BytePos { pure fn iter_bytes(&self, +lsb0: bool, &&f: to_bytes::Cb) { (**self).iter_bytes(lsb0, f) } } -pub impl CharPos: Pos { +pub impl Pos for CharPos { static pure fn from_uint(n: uint) -> CharPos { CharPos(n) } pure fn to_uint(&self) -> uint { **self } } -pub impl CharPos: cmp::Eq { +pub impl cmp::Eq for CharPos { pure fn eq(&self, other: &CharPos) -> bool { **self == **other } pure fn ne(&self, other: &CharPos) -> bool { !(*self).eq(other) } } -pub impl CharPos: cmp::Ord { +pub 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 } } -pub impl CharPos: to_bytes::IterBytes { +pub impl to_bytes::IterBytes for CharPos { pure fn iter_bytes(&self, +lsb0: bool, &&f: to_bytes::Cb) { (**self).iter_bytes(lsb0, f) } } -pub impl CharPos: Add { +pub impl Add for CharPos { pure fn add(&self, rhs: &CharPos) -> CharPos { CharPos(**self + **rhs) } } -pub impl CharPos: Sub { +pub impl Sub for CharPos { pure fn sub(&self, rhs: &CharPos) -> CharPos { CharPos(**self - **rhs) } @@ -133,26 +133,26 @@ pub struct span { #[deriving_eq] pub struct spanned { node: T, span: span } -pub impl span : cmp::Eq { +pub impl cmp::Eq for span { pure 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) } } -pub impl span: Encodable { +pub impl Encodable for span { /* Note #1972 -- spans are encoded but not decoded */ fn encode(&self, _s: &S) { } } -pub impl span: Decodable { +pub impl Decodable for span { static fn decode(_d: &D) -> span { dummy_sp() } } pub pure fn spanned(+lo: BytePos, +hi: BytePos, +t: T) -> spanned { - respan(mk_sp(lo, hi), move t) + respan(mk_sp(lo, hi), t) } pub pure fn respan(sp: span, +t: T) -> spanned { @@ -160,7 +160,7 @@ pub pure fn respan(sp: span, +t: T) -> spanned { } pub pure fn dummy_spanned(+t: T) -> spanned { - respan(dummy_sp(), move t) + respan(dummy_sp(), t) } /* assuming that we're not in macro expansion */ @@ -196,11 +196,16 @@ pub struct LocWithOpt { // used to be structural records. Better names, anyone? pub struct FileMapAndLine {fm: @FileMap, line: uint} pub struct FileMapAndBytePos {fm: @FileMap, pos: BytePos} +pub struct NameAndSpan {name: ~str, span: Option} + +pub struct CallInfo { + call_site: span, + callee: NameAndSpan +} /// Extra information for tracking macro expansion of spans pub enum ExpnInfo { - ExpandedFrom({call_site: span, - callie: {name: ~str, span: Option}}) + ExpandedFrom(CallInfo) } pub type FileName = ~str; @@ -237,7 +242,7 @@ pub struct FileMap { /// The start position of this source in the CodeMap start_pos: BytePos, /// Locations of lines beginnings in the source code - mut lines: ~[BytePos], + lines: @mut ~[BytePos], /// Locations of multi-byte characters in the source code multibyte_chars: DVec } @@ -307,7 +312,7 @@ pub impl CodeMap { let filemap = @FileMap { name: filename, substr: substr, src: src, start_pos: BytePos(start_pos), - mut lines: ~[], + lines: @mut ~[], multibyte_chars: DVec() }; @@ -434,7 +439,7 @@ priv impl CodeMap { let idx = self.lookup_filemap_idx(pos); let f = self.files[idx]; let mut a = 0u; - let mut b = vec::len(f.lines); + let mut b = f.lines.len(); while b - a > 1u { let m = (a + b) / 2u; if f.lines[m] > pos { b = m; } else { a = m; } diff --git a/src/libsyntax/diagnostic.rs b/src/libsyntax/diagnostic.rs index 2b24d03f8e9e5..27483ae94a5bd 100644 --- a/src/libsyntax/diagnostic.rs +++ b/src/libsyntax/diagnostic.rs @@ -26,17 +26,9 @@ use std::term; pub type Emitter = fn@(cmsp: Option<(@codemap::CodeMap, span)>, msg: &str, lvl: level); - -pub trait span_handler { - fn span_fatal(@mut self, sp: span, msg: &str) -> !; - fn span_err(@mut self, sp: span, msg: &str); - fn span_warn(@mut self, sp: span, msg: &str); - fn span_note(@mut self, sp: span, msg: &str); - fn span_bug(@mut self, sp: span, msg: &str) -> !; - fn span_unimpl(@mut self, sp: span, msg: &str) -> !; - fn handler(@mut self) -> handler; -} - +// a handler deals with errors; certain errors +// (fatal, bug, unimpl) may cause immediate exit, +// others log errors for later reporting. pub trait handler { fn fatal(@mut self, msg: &str) -> !; fn err(@mut self, msg: &str); @@ -45,6 +37,7 @@ pub trait handler { fn abort_if_errors(@mut self); fn warn(@mut self, msg: &str); fn note(@mut self, msg: &str); + // used to indicate a bug in the compiler: fn bug(@mut self, msg: &str) -> !; fn unimpl(@mut self, msg: &str) -> !; fn emit(@mut self, @@ -53,6 +46,19 @@ pub trait handler { lvl: level); } +// a span-handler is like a handler but also +// accepts span information for source-location +// reporting. +pub trait span_handler { + fn span_fatal(@mut self, sp: span, msg: &str) -> !; + fn span_err(@mut self, sp: span, msg: &str); + fn span_warn(@mut self, sp: span, msg: &str); + fn span_note(@mut self, sp: span, msg: &str); + fn span_bug(@mut self, sp: span, msg: &str) -> !; + fn span_unimpl(@mut self, sp: span, msg: &str) -> !; + fn handler(@mut self) -> handler; +} + struct HandlerT { err_count: uint, emit: Emitter, @@ -152,7 +158,7 @@ pub fn mk_handler(emitter: Option) -> @handler { } }; - @mut HandlerT { mut err_count: 0, emit: emit } as @handler + @mut HandlerT { err_count: 0, emit: emit } as @handler } #[deriving_eq] @@ -231,7 +237,7 @@ fn highlight_lines(cm: @codemap::CodeMap, let mut elided = false; let mut display_lines = /* FIXME (#2543) */ copy lines.lines; if vec::len(display_lines) > max_lines { - display_lines = vec::slice(display_lines, 0u, max_lines); + display_lines = vec::slice(display_lines, 0u, max_lines).to_vec(); elided = true; } // Print the offending lines @@ -290,17 +296,17 @@ fn highlight_lines(cm: @codemap::CodeMap, fn print_macro_backtrace(cm: @codemap::CodeMap, sp: span) { do option::iter(&sp.expn_info) |ei| { - let ss = option::map_default(&ei.callie.span, @~"", + let ss = option::map_default(&ei.callee.span, @~"", |span| @cm.span_to_str(*span)); print_diagnostic(*ss, note, - fmt!("in expansion of %s!", ei.callie.name)); + fmt!("in expansion of %s!", ei.callee.name)); let ss = cm.span_to_str(ei.call_site); print_diagnostic(ss, note, ~"expansion site"); print_macro_backtrace(cm, ei.call_site); } } -pub fn expect(diag: span_handler, +pub fn expect(diag: span_handler, opt: Option, msg: fn() -> ~str) -> T { match opt { diff --git a/src/libsyntax/ext/auto_encode.rs b/src/libsyntax/ext/auto_encode.rs index 9c0550c987527..7fbba987cc7df 100644 --- a/src/libsyntax/ext/auto_encode.rs +++ b/src/libsyntax/ext/auto_encode.rs @@ -23,7 +23,7 @@ For example, a type like: would generate two implementations like: -impl Encodable for Node { +impl Encodable for Node { fn encode(&self, s: &S) { do s.emit_struct("Node", 1) { s.emit_field("id", 0, || s.emit_uint(self.id)) @@ -31,7 +31,7 @@ impl Encodable for Node { } } -impl Decodable for node_id { +impl Decodable for node_id { static fn decode(d: &D) -> Node { do d.read_struct("Node", 1) { Node { @@ -54,7 +54,7 @@ would yield functions like: S: Encoder, T: Encodable > spanned: Encodable { - fn encode(s: &S) { + fn encode(s: &S) { do s.emit_rec { s.emit_field("node", 0, || self.node.encode(s)); s.emit_field("span", 1, || self.span.encode(s)); @@ -114,7 +114,7 @@ pub fn expand_auto_encode( in_items: ~[@ast::item] ) -> ~[@ast::item] { fn is_auto_encode(a: &ast::attribute) -> bool { - attr::get_attr_name(*a) == ~"auto_encode" + *attr::get_attr_name(a) == ~"auto_encode" } fn filter_attrs(item: @ast::item) -> @ast::item { @@ -127,24 +127,24 @@ pub fn expand_auto_encode( do vec::flat_map(in_items) |item| { if item.attrs.any(is_auto_encode) { match item.node { - ast::item_struct(@ast::struct_def { fields, _}, tps) => { + ast::item_struct(ref struct_def, ref tps) => { let ser_impl = mk_struct_ser_impl( cx, item.span, item.ident, - fields, - tps + struct_def.fields, + *tps ); ~[filter_attrs(*item), ser_impl] }, - ast::item_enum(ref enum_def, tps) => { + ast::item_enum(ref enum_def, ref tps) => { let ser_impl = mk_enum_ser_impl( cx, item.span, item.ident, - (*enum_def), - tps + *enum_def, + *tps ); ~[filter_attrs(*item), ser_impl] @@ -169,7 +169,7 @@ pub fn expand_auto_decode( in_items: ~[@ast::item] ) -> ~[@ast::item] { fn is_auto_decode(a: &ast::attribute) -> bool { - attr::get_attr_name(*a) == ~"auto_decode" + *attr::get_attr_name(a) == ~"auto_decode" } fn filter_attrs(item: @ast::item) -> @ast::item { @@ -182,24 +182,24 @@ pub fn expand_auto_decode( do vec::flat_map(in_items) |item| { if item.attrs.any(is_auto_decode) { match item.node { - ast::item_struct(@ast::struct_def { fields, _}, tps) => { + ast::item_struct(ref struct_def, ref tps) => { let deser_impl = mk_struct_deser_impl( cx, item.span, item.ident, - fields, - tps + struct_def.fields, + *tps ); ~[filter_attrs(*item), deser_impl] }, - ast::item_enum(ref enum_def, tps) => { + ast::item_enum(ref enum_def, ref tps) => { let deser_impl = mk_enum_deser_impl( cx, item.span, item.ident, - (*enum_def), - tps + *enum_def, + *tps ); ~[filter_attrs(*item), deser_impl] @@ -410,7 +410,7 @@ fn mk_impl( ident: ast::ident, ty_param: ast::ty_param, path: @ast::path, - tps: ~[ast::ty_param], + tps: &[ast::ty_param], f: fn(@ast::Ty) -> @ast::method ) -> @ast::item { // All the type parameters need to bound to the trait. @@ -458,7 +458,7 @@ fn mk_ser_impl( cx: ext_ctxt, span: span, ident: ast::ident, - tps: ~[ast::ty_param], + tps: &[ast::ty_param], body: @ast::expr ) -> @ast::item { // Make a path to the std::serialize::Encodable typaram. @@ -666,8 +666,8 @@ fn mk_struct_ser_impl( cx: ext_ctxt, span: span, ident: ast::ident, - fields: ~[@ast::struct_field], - tps: ~[ast::ty_param] + fields: &[@ast::struct_field], + tps: &[ast::ty_param] ) -> @ast::item { let fields = do mk_struct_fields(fields).mapi |idx, field| { // ast for `|| self.$(name).encode(__s)` @@ -808,7 +808,7 @@ struct field { mutbl: ast::mutability, } -fn mk_struct_fields(fields: ~[@ast::struct_field]) -> ~[field] { +fn mk_struct_fields(fields: &[@ast::struct_field]) -> ~[field] { do fields.map |field| { let (ident, mutbl) = match field.node.kind { ast::named_field(ident, mutbl, _) => (ident, mutbl), diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs index 951e350f8b290..f3a74302400c9 100644 --- a/src/libsyntax/ext/base.rs +++ b/src/libsyntax/ext/base.rs @@ -13,6 +13,7 @@ use core::prelude::*; use ast; use codemap; use codemap::{CodeMap, span, ExpnInfo, ExpandedFrom, dummy_sp}; +use codemap::{CallInfo, NameAndSpan}; use diagnostic::span_handler; use ext; use parse; @@ -75,9 +76,11 @@ pub enum SyntaxExtension { ItemTT(SyntaxExpanderTTItem), } +type SyntaxExtensions = HashMap<@~str, SyntaxExtension>; + // A temporary hard-coded map of methods for expanding syntax extension // AST nodes into full ASTs -pub fn syntax_expander_table() -> HashMap<~str, SyntaxExtension> { +pub fn syntax_expander_table() -> SyntaxExtensions { // utility function to simplify creating NormalTT syntax extensions fn builtin_normal_tt(f: SyntaxExpanderTTFun) -> SyntaxExtension { NormalTT(SyntaxExpanderTT{expander: f, span: None}) @@ -87,74 +90,74 @@ pub fn syntax_expander_table() -> HashMap<~str, SyntaxExtension> { ItemTT(SyntaxExpanderTTItem{expander: f, span: None}) } let syntax_expanders = HashMap(); - syntax_expanders.insert(~"macro_rules", + syntax_expanders.insert(@~"macro_rules", builtin_item_tt( ext::tt::macro_rules::add_new_extension)); - syntax_expanders.insert(~"fmt", + syntax_expanders.insert(@~"fmt", builtin_normal_tt(ext::fmt::expand_syntax_ext)); syntax_expanders.insert( - ~"auto_encode", + @~"auto_encode", ItemDecorator(ext::auto_encode::expand_auto_encode)); syntax_expanders.insert( - ~"auto_decode", + @~"auto_decode", ItemDecorator(ext::auto_encode::expand_auto_decode)); - syntax_expanders.insert(~"env", + syntax_expanders.insert(@~"env", builtin_normal_tt(ext::env::expand_syntax_ext)); - syntax_expanders.insert(~"concat_idents", + syntax_expanders.insert(@~"concat_idents", builtin_normal_tt( ext::concat_idents::expand_syntax_ext)); - syntax_expanders.insert(~"log_syntax", + syntax_expanders.insert(@~"log_syntax", builtin_normal_tt( ext::log_syntax::expand_syntax_ext)); - syntax_expanders.insert(~"deriving_eq", + syntax_expanders.insert(@~"deriving_eq", ItemDecorator( ext::deriving::expand_deriving_eq)); - syntax_expanders.insert(~"deriving_iter_bytes", + syntax_expanders.insert(@~"deriving_iter_bytes", ItemDecorator( ext::deriving::expand_deriving_iter_bytes)); // Quasi-quoting expanders - syntax_expanders.insert(~"quote_tokens", + syntax_expanders.insert(@~"quote_tokens", builtin_normal_tt(ext::quote::expand_quote_tokens)); - syntax_expanders.insert(~"quote_expr", + syntax_expanders.insert(@~"quote_expr", builtin_normal_tt(ext::quote::expand_quote_expr)); - syntax_expanders.insert(~"quote_ty", + syntax_expanders.insert(@~"quote_ty", builtin_normal_tt(ext::quote::expand_quote_ty)); - syntax_expanders.insert(~"quote_item", + syntax_expanders.insert(@~"quote_item", builtin_normal_tt(ext::quote::expand_quote_item)); - syntax_expanders.insert(~"quote_pat", + syntax_expanders.insert(@~"quote_pat", builtin_normal_tt(ext::quote::expand_quote_pat)); - syntax_expanders.insert(~"quote_stmt", + syntax_expanders.insert(@~"quote_stmt", builtin_normal_tt(ext::quote::expand_quote_stmt)); - syntax_expanders.insert(~"line", + syntax_expanders.insert(@~"line", builtin_normal_tt( ext::source_util::expand_line)); - syntax_expanders.insert(~"col", + syntax_expanders.insert(@~"col", builtin_normal_tt( ext::source_util::expand_col)); - syntax_expanders.insert(~"file", + syntax_expanders.insert(@~"file", builtin_normal_tt( ext::source_util::expand_file)); - syntax_expanders.insert(~"stringify", + syntax_expanders.insert(@~"stringify", builtin_normal_tt( ext::source_util::expand_stringify)); - syntax_expanders.insert(~"include", + syntax_expanders.insert(@~"include", builtin_normal_tt( ext::source_util::expand_include)); - syntax_expanders.insert(~"include_str", + syntax_expanders.insert(@~"include_str", builtin_normal_tt( ext::source_util::expand_include_str)); - syntax_expanders.insert(~"include_bin", + syntax_expanders.insert(@~"include_bin", builtin_normal_tt( ext::source_util::expand_include_bin)); - syntax_expanders.insert(~"module_path", + syntax_expanders.insert(@~"module_path", builtin_normal_tt( ext::source_util::expand_mod)); - syntax_expanders.insert(~"proto", + syntax_expanders.insert(@~"proto", builtin_item_tt(ext::pipes::expand_proto)); syntax_expanders.insert( - ~"trace_macros", + @~"trace_macros", builtin_normal_tt(ext::trace_macros::expand_trace_macros)); return syntax_expanders; } @@ -164,7 +167,7 @@ pub fn syntax_expander_table() -> HashMap<~str, SyntaxExtension> { // -> expn_info of their expansion context stored into their span. pub trait ext_ctxt { fn codemap(@mut self) -> @CodeMap; - fn parse_sess(@mut self) -> parse::parse_sess; + fn parse_sess(@mut self) -> @mut parse::ParseSess; fn cfg(@mut self) -> ast::crate_cfg; fn call_site(@mut self) -> span; fn print_backtrace(@mut self); @@ -188,47 +191,47 @@ pub trait ext_ctxt { fn ident_of(@mut self, st: ~str) -> ast::ident; } -pub fn mk_ctxt(parse_sess: parse::parse_sess, +pub fn mk_ctxt(parse_sess: @mut parse::ParseSess, cfg: ast::crate_cfg) -> ext_ctxt { struct CtxtRepr { - parse_sess: parse::parse_sess, + parse_sess: @mut parse::ParseSess, cfg: ast::crate_cfg, - backtrace: Option<@ExpnInfo>, + backtrace: @mut Option<@ExpnInfo>, mod_path: ~[ast::ident], trace_mac: bool } impl ext_ctxt for CtxtRepr { fn codemap(@mut self) -> @CodeMap { self.parse_sess.cm } - fn parse_sess(@mut self) -> parse::parse_sess { self.parse_sess } + fn parse_sess(@mut self) -> @mut parse::ParseSess { self.parse_sess } fn cfg(@mut self) -> ast::crate_cfg { self.cfg } fn call_site(@mut self) -> span { - match self.backtrace { - Some(@ExpandedFrom({call_site: cs, _})) => cs, + match *self.backtrace { + Some(@ExpandedFrom(CallInfo {call_site: cs, _})) => cs, None => self.bug(~"missing top span") } } fn print_backtrace(@mut self) { } - fn backtrace(@mut self) -> Option<@ExpnInfo> { self.backtrace } + fn backtrace(@mut self) -> Option<@ExpnInfo> { *self.backtrace } fn mod_push(@mut self, i: ast::ident) { self.mod_path.push(i); } fn mod_pop(@mut self) { self.mod_path.pop(); } fn mod_path(@mut self) -> ~[ast::ident] { return self.mod_path; } fn bt_push(@mut self, ei: codemap::ExpnInfo) { match ei { - ExpandedFrom({call_site: cs, callie: ref callie}) => { - self.backtrace = - Some(@ExpandedFrom({ + ExpandedFrom(CallInfo {call_site: cs, callee: ref callee}) => { + *self.backtrace = + Some(@ExpandedFrom(CallInfo { call_site: span {lo: cs.lo, hi: cs.hi, - expn_info: self.backtrace}, - callie: (*callie)})); + expn_info: *self.backtrace}, + callee: (*callee)})); } } } fn bt_pop(@mut self) { - match self.backtrace { - Some(@ExpandedFrom({ + match *self.backtrace { + Some(@ExpandedFrom(CallInfo { call_site: span {expn_info: prev, _}, _ })) => { - self.backtrace = prev + *self.backtrace = prev } _ => self.bug(~"tried to pop without a push") } @@ -277,11 +280,11 @@ pub fn mk_ctxt(parse_sess: parse::parse_sess, let imp: @mut CtxtRepr = @mut CtxtRepr { parse_sess: parse_sess, cfg: cfg, - backtrace: None, + backtrace: @mut None, mod_path: ~[], trace_mac: false }; - move ((move imp) as @ext_ctxt) + ((imp) as @ext_ctxt) } pub fn expr_to_str(cx: ext_ctxt, expr: @ast::expr, err_msg: ~str) -> ~str { @@ -336,7 +339,7 @@ pub fn get_exprs_from_tts(cx: ext_ctxt, tts: ~[ast::token_tree]) cx.cfg(), tts); let mut es = ~[]; - while p.token != token::EOF { + while *p.token != token::EOF { if es.len() != 0 { p.eat(token::COMMA); } diff --git a/src/libsyntax/ext/build.rs b/src/libsyntax/ext/build.rs index a050b2316e873..55e5d5fbe17cc 100644 --- a/src/libsyntax/ext/build.rs +++ b/src/libsyntax/ext/build.rs @@ -19,6 +19,11 @@ use ext::build; use core::dvec; use core::option; +pub struct Field { + ident: ast::ident, + ex: @ast::expr +} + pub fn mk_expr(cx: ext_ctxt, sp: codemap::span, expr: ast::expr_) @@ -73,7 +78,7 @@ pub fn mk_raw_path_(sp: span, global: false, idents: idents, rp: None, - types: move types } + types: types } } pub fn mk_raw_path_global(sp: span, idents: ~[ast::ident]) -> @ast::path { @ast::path { span: sp, @@ -147,52 +152,42 @@ pub fn mk_base_str(cx: ext_ctxt, sp: span, s: ~str) -> @ast::expr { pub fn mk_uniq_str(cx: ext_ctxt, sp: span, s: ~str) -> @ast::expr { mk_vstore_e(cx, sp, mk_base_str(cx, sp, s), ast::expr_vstore_uniq) } -pub fn mk_field(sp: span, f: &{ident: ast::ident, ex: @ast::expr}) - -> ast::field { +pub fn mk_field(sp: span, f: &Field) -> ast::field { codemap::spanned { node: ast::field_ { mutbl: ast::m_imm, ident: f.ident, expr: f.ex }, span: sp, } } -pub fn mk_fields(sp: span, fields: ~[{ident: ast::ident, ex: @ast::expr}]) - -> ~[ast::field] { - move fields.map(|f| mk_field(sp, f)) +pub fn mk_fields(sp: span, fields: ~[Field]) -> ~[ast::field] { + fields.map(|f| mk_field(sp, f)) } -pub fn mk_rec_e(cx: ext_ctxt, - sp: span, - fields: ~[{ident: ast::ident, ex: @ast::expr}]) - -> @ast::expr { +pub fn mk_rec_e(cx: ext_ctxt, sp: span, fields: ~[Field]) -> @ast::expr { mk_expr(cx, sp, ast::expr_rec(mk_fields(sp, fields), option::None::<@ast::expr>)) } -pub fn mk_struct_e(cx: ext_ctxt, - sp: span, - ctor_path: ~[ast::ident], - fields: ~[{ident: ast::ident, ex: @ast::expr}]) - -> @ast::expr { +pub fn mk_struct_e(cx: ext_ctxt, sp: span, ctor_path: ~[ast::ident], + fields: ~[Field]) -> @ast::expr { mk_expr(cx, sp, ast::expr_struct(mk_raw_path(sp, ctor_path), mk_fields(sp, fields), option::None::<@ast::expr>)) } -pub fn mk_global_struct_e(cx: ext_ctxt, - sp: span, +pub fn mk_global_struct_e(cx: ext_ctxt, sp: span, ctor_path: ~[ast::ident], - fields: ~[{ident: ast::ident, ex: @ast::expr}]) + fields: ~[Field]) -> @ast::expr { mk_expr(cx, sp, ast::expr_struct(mk_raw_path_global(sp, ctor_path), mk_fields(sp, fields), option::None::<@ast::expr>)) } -pub fn mk_glob_use(cx: ext_ctxt, - sp: span, - path: ~[ast::ident]) -> @ast::view_item { +pub fn mk_glob_use(cx: ext_ctxt, sp: span, path: ~[ast::ident]) + -> @ast::view_item { let glob = @codemap::spanned { node: ast::view_path_glob(mk_raw_path(sp, path), cx.next_id()), span: sp, }; - @ast::view_item { node: ast::view_item_import(~[glob]), + @ast::view_item { node: ast::view_item_use(~[glob]), attrs: ~[], vis: ast::private, span: sp } @@ -288,33 +283,33 @@ pub fn mk_pat_ident_with_binding_mode(cx: ext_ctxt, bm: ast::binding_mode) -> @ast::pat { let path = mk_raw_path(span, ~[ ident ]); let pat = ast::pat_ident(bm, path, None); - mk_pat(cx, span, move pat) + mk_pat(cx, span, pat) } pub fn mk_pat_enum(cx: ext_ctxt, span: span, path: @ast::path, +subpats: ~[@ast::pat]) -> @ast::pat { - let pat = ast::pat_enum(path, Some(move subpats)); - mk_pat(cx, span, move pat) + let pat = ast::pat_enum(path, Some(subpats)); + mk_pat(cx, span, pat) } pub fn mk_pat_struct(cx: ext_ctxt, span: span, path: @ast::path, +field_pats: ~[ast::field_pat]) -> @ast::pat { - let pat = ast::pat_struct(path, move field_pats, false); - mk_pat(cx, span, move pat) + let pat = ast::pat_struct(path, field_pats, false); + mk_pat(cx, span, pat) } pub fn mk_bool(cx: ext_ctxt, span: span, value: bool) -> @ast::expr { let lit_expr = ast::expr_lit(@codemap::spanned { node: ast::lit_bool(value), span: span }); - build::mk_expr(cx, span, move lit_expr) + build::mk_expr(cx, span, lit_expr) } pub fn mk_stmt(cx: ext_ctxt, span: span, expr: @ast::expr) -> @ast::stmt { let stmt_ = ast::stmt_semi(expr, cx.next_id()); - @codemap::spanned { node: move stmt_, span: span } + @codemap::spanned { node: stmt_, span: span } } pub fn mk_ty_path(cx: ext_ctxt, span: span, @@ -322,7 +317,7 @@ pub fn mk_ty_path(cx: ext_ctxt, -> @ast::Ty { let ty = build::mk_raw_path(span, idents); let ty = ast::ty_path(ty, cx.next_id()); - let ty = @ast::Ty { id: cx.next_id(), node: move ty, span: span }; + let ty = @ast::Ty { id: cx.next_id(), node: ty, span: span }; ty } pub fn mk_ty_path_global(cx: ext_ctxt, @@ -331,7 +326,7 @@ pub fn mk_ty_path_global(cx: ext_ctxt, -> @ast::Ty { let ty = build::mk_raw_path_global(span, idents); let ty = ast::ty_path(ty, cx.next_id()); - let ty = @ast::Ty { id: cx.next_id(), node: move ty, span: span }; + let ty = @ast::Ty { id: cx.next_id(), node: ty, span: span }; ty } pub fn mk_simple_ty_path(cx: ext_ctxt, diff --git a/src/libsyntax/ext/deriving.rs b/src/libsyntax/ext/deriving.rs index 8e87357f8b5b9..094eea81fd2fd 100644 --- a/src/libsyntax/ext/deriving.rs +++ b/src/libsyntax/ext/deriving.rs @@ -95,19 +95,19 @@ fn expand_deriving(cx: ext_ctxt, span, struct_def, item.ident, - move ty_params)); + ty_params)); } item_enum(ref enum_definition, copy ty_params) => { result.push(expand_deriving_enum_def(cx, span, enum_definition, item.ident, - move ty_params)); + ty_params)); } _ => () } } - dvec::unwrap(move result) + dvec::unwrap(result) } fn create_impl_item(cx: ext_ctxt, span: span, +item: item_) -> @item { @@ -115,7 +115,7 @@ fn create_impl_item(cx: ext_ctxt, span: span, +item: item_) -> @item { ident: clownshoes_extensions, attrs: ~[], id: cx.next_id(), - node: move item, + node: item, vis: public, span: span, } @@ -161,7 +161,7 @@ fn create_eq_method(cx: ext_ctxt, }; // Create the function declaration. - let fn_decl = build::mk_fn_decl(~[ move arg ], output_type); + let fn_decl = build::mk_fn_decl(~[ arg ], output_type); // Create the body block. let body_block = build::mk_simple_block(cx, span, body); @@ -174,8 +174,8 @@ fn create_eq_method(cx: ext_ctxt, tps: ~[], self_ty: self_ty, purity: pure_fn, - decl: move fn_decl, - body: move body_block, + decl: fn_decl, + body: body_block, id: cx.next_id(), span: span, self_id: cx.next_id(), @@ -194,14 +194,14 @@ fn create_self_type_with_params(cx: ext_ctxt, let self_ty_param = build::mk_simple_ty_path(cx, span, ty_param.ident); - self_ty_params.push(move self_ty_param); + self_ty_params.push(self_ty_param); } - let self_ty_params = dvec::unwrap(move self_ty_params); + let self_ty_params = dvec::unwrap(self_ty_params); // Create the type of `self`. let self_type = build::mk_raw_path_(span, ~[ type_ident ], - move self_ty_params); + self_ty_params); let self_type = ty_path(self_type, cx.next_id()); @ast::Ty { id: cx.next_id(), node: self_type, span: span } } @@ -221,9 +221,9 @@ fn create_derived_impl(cx: ext_ctxt, trait_path.map(|x| *x)); let bounds = @~[ TraitTyParamBound(bound) ]; let impl_ty_param = build::mk_ty_param(cx, ty_param.ident, bounds); - impl_ty_params.push(move impl_ty_param); + impl_ty_params.push(impl_ty_param); } - let impl_ty_params = dvec::unwrap(move impl_ty_params); + let impl_ty_params = dvec::unwrap(impl_ty_params); // Create the reference to the trait. let trait_path = ast::path { @@ -233,12 +233,12 @@ fn create_derived_impl(cx: ext_ctxt, rp: None, types: ~[] }; - let trait_path = @move trait_path; + let trait_path = @trait_path; let trait_ref = ast::trait_ref { path: trait_path, ref_id: cx.next_id() }; - let trait_ref = @move trait_ref; + let trait_ref = @trait_ref; // Create the type of `self`. let self_type = create_self_type_with_params(cx, @@ -247,11 +247,11 @@ fn create_derived_impl(cx: ext_ctxt, ty_params); // Create the impl item. - let impl_item = item_impl(move impl_ty_params, + let impl_item = item_impl(impl_ty_params, Some(trait_ref), self_type, methods.map(|x| *x)); - return create_impl_item(cx, span, move impl_item); + return create_impl_item(cx, span, impl_item); } fn create_derived_eq_impl(cx: ext_ctxt, @@ -310,11 +310,11 @@ fn create_iter_bytes_method(cx: ext_ctxt, let output_type = @ast::Ty { id: cx.next_id(), node: ty_nil, span: span }; // Create the function declaration. - let inputs = ~[ move lsb0_arg, move f_arg ]; - let fn_decl = build::mk_fn_decl(move inputs, output_type); + 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, move statements); + let body_block = build::mk_block_(cx, span, statements); // Create the method. let self_ty = spanned { node: sty_region(m_imm), span: span }; @@ -325,8 +325,8 @@ fn create_iter_bytes_method(cx: ext_ctxt, tps: ~[], self_ty: self_ty, purity: pure_fn, - decl: move fn_decl, - body: move body_block, + decl: fn_decl, + body: body_block, id: cx.next_id(), span: span, self_id: cx.next_id(), @@ -348,10 +348,10 @@ fn create_subpatterns(cx: ext_ctxt, // 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, move subpat); + let subpat = build::mk_pat(cx, span, subpat); subpats.push(subpat); } - return dvec::unwrap(move subpats); + return dvec::unwrap(subpats); } fn create_enum_variant_pattern(cx: ext_ctxt, @@ -373,7 +373,7 @@ fn create_enum_variant_pattern(cx: ext_ctxt, prefix, variant_args.len()); - return build::mk_pat_enum(cx, span, matching_path, move subpats); + 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 ]); @@ -489,26 +489,42 @@ fn expand_deriving_eq_struct_def(cx: ext_ctxt, // Create the methods. let eq_ident = cx.ident_of(~"eq"); let ne_ident = cx.ident_of(~"ne"); - let eq_method = expand_deriving_eq_struct_method(cx, - span, - struct_def, - eq_ident, - type_ident, - ty_params, - Conjunction); - let ne_method = expand_deriving_eq_struct_method(cx, - span, - struct_def, - ne_ident, - type_ident, - ty_params, - Disjunction); + + let is_struct_tuple = + struct_def.fields.len() > 0 && struct_def.fields.all(|f| { + match f.node.kind { + named_field(*) => false, + unnamed_field => true + } + }); + + let derive_struct_fn = if is_struct_tuple { + 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, + ty_params, + Conjunction); + let ne_method = derive_struct_fn(cx, + span, + struct_def, + ne_ident, + type_ident, + ty_params, + Disjunction); // Create the implementation. return create_derived_eq_impl(cx, span, type_ident, - move ty_params, + ty_params, eq_method, ne_method); } @@ -541,7 +557,7 @@ fn expand_deriving_eq_enum_def(cx: ext_ctxt, return create_derived_eq_impl(cx, span, type_ident, - move ty_params, + ty_params, eq_method, ne_method); } @@ -561,7 +577,7 @@ fn expand_deriving_iter_bytes_struct_def(cx: ext_ctxt, return create_derived_iter_bytes_impl(cx, span, type_ident, - move ty_params, + ty_params, method); } @@ -580,7 +596,7 @@ fn expand_deriving_iter_bytes_enum_def(cx: ext_ctxt, return create_derived_iter_bytes_impl(cx, span, type_ident, - move ty_params, + ty_params, method); } @@ -671,8 +687,8 @@ fn expand_deriving_iter_bytes_struct_method(cx: ext_ctxt, } // Create the method itself. - let statements = dvec::unwrap(move statements); - return create_iter_bytes_method(cx, span, move statements); + let statements = dvec::unwrap(statements); + return create_iter_bytes_method(cx, span, statements); } fn expand_deriving_eq_enum_method(cx: ext_ctxt, @@ -738,9 +754,9 @@ fn expand_deriving_eq_enum_method(cx: ext_ctxt, let matching_arm = ast::arm { pats: ~[ matching_pat ], guard: None, - body: move matching_body_block + body: matching_body_block }; - other_arms.push(move matching_arm); + other_arms.push(matching_arm); // Maybe generate a non-matching case. If there is only one // variant then there will always be a match. @@ -777,11 +793,11 @@ fn expand_deriving_eq_enum_method(cx: ext_ctxt, // 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_arms = dvec::unwrap(move other_arms); - let other_match_expr = expr_match(other_expr, move other_arms); + let other_arms = dvec::unwrap(other_arms); + let other_match_expr = expr_match(other_expr, other_arms); let other_match_expr = build::mk_expr(cx, span, - move other_match_expr); + other_match_expr); let other_match_body_block = build::mk_simple_block(cx, span, other_match_expr); @@ -792,15 +808,15 @@ fn expand_deriving_eq_enum_method(cx: ext_ctxt, guard: None, body: other_match_body_block, }; - self_arms.push(move self_arm); + 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_arms = dvec::unwrap(move self_arms); - let self_match_expr = expr_match(self_expr, move self_arms); - let self_match_expr = build::mk_expr(cx, span, move self_match_expr); + let self_arms = dvec::unwrap(self_arms); + 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, @@ -811,6 +827,65 @@ fn expand_deriving_eq_enum_method(cx: ext_ctxt, 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, + ty_params: &[ty_param], + junction: Junction) + -> @method { + let self_str = ~"self"; + let other_str = ~"__other"; + let type_path = build::mk_raw_path(span, ~[type_ident]); + let fields = 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, ty_params, self_match_expr) +} + fn expand_deriving_iter_bytes_enum_method(cx: ext_ctxt, span: span, enum_definition: &enum_def) @@ -848,8 +923,8 @@ fn expand_deriving_iter_bytes_enum_method(cx: ext_ctxt, } // Create the pattern body. - let stmts = dvec::unwrap(move stmts); - let match_body_block = build::mk_block_(cx, span, move stmts); + let stmts = dvec::unwrap(stmts); + let match_body_block = build::mk_block_(cx, span, stmts); // Create the arm. ast::arm { diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index 17197f64c5556..0b2aaa89d9b3a 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -13,7 +13,8 @@ use core::prelude::*; use ast::{crate, expr_, expr_mac, mac_invoc_tt}; use ast::{tt_delim, tt_tok, item_mac, stmt_, stmt_mac, stmt_expr, stmt_semi}; use ast; -use codemap::{span, ExpandedFrom}; +use attr; +use codemap::{span, CallInfo, ExpandedFrom, NameAndSpan}; use ext::base::*; use fold::*; use parse::{parser, parse_expr_from_source_str, new_parser_from_tts}; @@ -22,7 +23,7 @@ use core::option; use core::vec; use std::oldmap::HashMap; -pub fn expand_expr(exts: HashMap<~str, SyntaxExtension>, cx: ext_ctxt, +pub fn expand_expr(exts: SyntaxExtensions, cx: ext_ctxt, e: expr_, s: span, fld: ast_fold, orig: fn@(expr_, span, ast_fold) -> (expr_, span)) -> (expr_, span) { @@ -40,15 +41,19 @@ pub fn expand_expr(exts: HashMap<~str, SyntaxExtension>, cx: ext_ctxt, /* using idents and token::special_idents would make the the macro names be hygienic */ let extname = cx.parse_sess().interner.get(pth.idents[0]); - match exts.find(extname) { + match exts.find(&extname) { None => { cx.span_fatal(pth.span, fmt!("macro undefined: '%s'", *extname)) } Some(NormalTT(SyntaxExpanderTT{expander: exp, span: exp_sp})) => { - cx.bt_push(ExpandedFrom({call_site: s, - callie: {name: *extname, span: exp_sp}})); + cx.bt_push(ExpandedFrom(CallInfo{ + call_site: s, + callee: NameAndSpan { + name: *extname, span: exp_sp + } + })); let expanded = match exp(cx, (*mac).span, (*tts)) { MRExpr(e) => e, @@ -87,7 +92,7 @@ pub fn expand_expr(exts: HashMap<~str, SyntaxExtension>, cx: ext_ctxt, // // NB: there is some redundancy between this and expand_item, below, and // they might benefit from some amount of semantic and language-UI merger. -pub fn expand_mod_items(exts: HashMap<~str, SyntaxExtension>, cx: ext_ctxt, +pub fn expand_mod_items(exts: SyntaxExtensions, cx: ext_ctxt, module_: ast::_mod, fld: ast_fold, orig: fn@(ast::_mod, ast_fold) -> ast::_mod) -> ast::_mod { @@ -99,17 +104,18 @@ pub fn expand_mod_items(exts: HashMap<~str, SyntaxExtension>, cx: ext_ctxt, // the item into a new set of items. let new_items = do vec::flat_map(module_.items) |item| { do vec::foldr(item.attrs, ~[*item]) |attr, items| { - let mname = match attr.node.value.node { - ast::meta_word(ref n) => (*n), - ast::meta_name_value(ref n, _) => (*n), - ast::meta_list(ref n, _) => (*n) - }; + let mname = attr::get_attr_name(attr); + match exts.find(&mname) { None | Some(NormalTT(_)) | Some(ItemTT(*)) => items, Some(ItemDecorator(dec_fn)) => { - cx.bt_push(ExpandedFrom({call_site: attr.span, - callie: {name: copy mname, - span: None}})); + cx.bt_push(ExpandedFrom(CallInfo { + call_site: attr.span, + callee: NameAndSpan { + name: /*bad*/ copy *mname, + span: None + } + })); let r = dec_fn(cx, attr.span, attr.node.value, items); cx.bt_pop(); r @@ -123,7 +129,7 @@ pub fn expand_mod_items(exts: HashMap<~str, SyntaxExtension>, cx: ext_ctxt, // When we enter a module, record it, for the sake of `module!` -pub fn expand_item(exts: HashMap<~str, SyntaxExtension>, +pub fn expand_item(exts: SyntaxExtensions, cx: ext_ctxt, &&it: @ast::item, fld: ast_fold, orig: fn@(&&v: @ast::item, ast_fold) -> Option<@ast::item>) -> Option<@ast::item> { @@ -149,7 +155,7 @@ pub fn expand_item(exts: HashMap<~str, SyntaxExtension>, // Support for item-position macro invocations, exactly the same // logic as for expression-position macro invocations. -pub fn expand_item_mac(exts: HashMap<~str, SyntaxExtension>, +pub fn expand_item_mac(exts: SyntaxExtensions, cx: ext_ctxt, &&it: @ast::item, fld: ast_fold) -> Option<@ast::item> { @@ -161,7 +167,7 @@ pub fn expand_item_mac(exts: HashMap<~str, SyntaxExtension>, }; let extname = cx.parse_sess().interner.get(pth.idents[0]); - let expanded = match exts.find(extname) { + let expanded = match exts.find(&extname) { None => cx.span_fatal(pth.span, fmt!("macro undefined: '%s!'", *extname)), @@ -172,9 +178,13 @@ pub fn expand_item_mac(exts: HashMap<~str, SyntaxExtension>, given '%s'", *extname, *cx.parse_sess().interner.get(it.ident))); } - cx.bt_push(ExpandedFrom({call_site: it.span, - callie: {name: *extname, - span: (*expand).span}})); + cx.bt_push(ExpandedFrom(CallInfo { + call_site: it.span, + callee: NameAndSpan { + name: *extname, + span: (*expand).span + } + })); ((*expand).expander)(cx, it.span, tts) } Some(ItemTT(ref expand)) => { @@ -183,9 +193,13 @@ pub fn expand_item_mac(exts: HashMap<~str, SyntaxExtension>, fmt!("macro %s! expects an ident argument", *extname)); } - cx.bt_push(ExpandedFrom({call_site: it.span, - callie: {name: *extname, - span: (*expand).span}})); + cx.bt_push(ExpandedFrom(CallInfo { + call_site: it.span, + callee: NameAndSpan { + name: *extname, + span: (*expand).span + } + })); ((*expand).expander)(cx, it.span, it.ident, tts) } _ => cx.span_fatal( @@ -200,7 +214,7 @@ pub fn expand_item_mac(exts: HashMap<~str, SyntaxExtension>, MRAny(_, item_maker, _) => option::chain(item_maker(), |i| {fld.fold_item(i)}), MRDef(ref mdef) => { - exts.insert((*mdef).name, (*mdef).ext); + exts.insert(@/*bad*/ copy mdef.name, (*mdef).ext); None } }; @@ -208,7 +222,7 @@ pub fn expand_item_mac(exts: HashMap<~str, SyntaxExtension>, return maybe_it; } -pub fn expand_stmt(exts: HashMap<~str, SyntaxExtension>, cx: ext_ctxt, +pub fn expand_stmt(exts: SyntaxExtensions, cx: ext_ctxt, && s: stmt_, sp: span, fld: ast_fold, orig: fn@(&&s: stmt_, span, ast_fold) -> (stmt_, span)) -> (stmt_, span) { @@ -224,14 +238,16 @@ pub fn expand_stmt(exts: HashMap<~str, SyntaxExtension>, cx: ext_ctxt, assert(vec::len(pth.idents) == 1u); let extname = cx.parse_sess().interner.get(pth.idents[0]); - let (fully_expanded, sp) = match exts.find(extname) { + let (fully_expanded, sp) = match exts.find(&extname) { None => cx.span_fatal(pth.span, fmt!("macro undefined: '%s'", *extname)), Some(NormalTT( SyntaxExpanderTT{expander: exp, span: exp_sp})) => { - cx.bt_push(ExpandedFrom( - {call_site: sp, callie: {name: *extname, span: exp_sp}})); + cx.bt_push(ExpandedFrom(CallInfo { + call_site: sp, + callee: NameAndSpan { name: *extname, span: exp_sp } + })); let expanded = match exp(cx, mac.span, tts) { MRExpr(e) => @codemap::spanned { node: stmt_expr(e, cx.next_id()), @@ -287,15 +303,6 @@ pub fn core_macros() -> ~str { macro_rules! debug ( ($( $arg:expr ),+) => ( log(::core::debug, fmt!( $($arg),+ )) )) - macro_rules! die( - ($msg: expr) => ( - ::core::sys::begin_unwind($msg, file!().to_owned(), line!()) - ); - () => ( - fail!(~\"explicit failure\") - ) - ) - macro_rules! fail( ($msg: expr) => ( ::core::sys::begin_unwind($msg, file!().to_owned(), line!()) @@ -332,7 +339,7 @@ pub fn core_macros() -> ~str { }"; } -pub fn expand_crate(parse_sess: parse::parse_sess, +pub fn expand_crate(parse_sess: @mut parse::ParseSess, cfg: ast::crate_cfg, c: @crate) -> @crate { let exts = syntax_expander_table(); let afp = default_ast_fold(); diff --git a/src/libsyntax/ext/fmt.rs b/src/libsyntax/ext/fmt.rs index d967912221dfa..937bcef5c253b 100644 --- a/src/libsyntax/ext/fmt.rs +++ b/src/libsyntax/ext/fmt.rs @@ -23,7 +23,7 @@ use codemap::span; use ext::base::*; use ext::base; use ext::build::*; -use extfmt::ct::*; +use private::extfmt::ct::*; pub fn expand_syntax_ext(cx: ext_ctxt, sp: span, tts: ~[ast::token_tree]) -> base::MacResult { @@ -56,8 +56,8 @@ fn pieces_to_expr(cx: ext_ctxt, sp: span, -> @ast::expr { fn make_path_vec(cx: ext_ctxt, ident: @~str) -> ~[ast::ident] { let intr = cx.parse_sess().interner; - return ~[intr.intern(@~"extfmt"), intr.intern(@~"rt"), - intr.intern(ident)]; + return ~[intr.intern(@~"private"), intr.intern(@~"extfmt"), + intr.intern(@~"rt"), intr.intern(ident)]; } fn make_rt_path_expr(cx: ext_ctxt, sp: span, nm: @~str) -> @ast::expr { let path = make_path_vec(cx, nm); @@ -118,10 +118,18 @@ fn pieces_to_expr(cx: ext_ctxt, sp: span, sp, make_path_vec(cx, @~"Conv"), ~[ - {ident: intr.intern(@~"flags"), ex: flags_expr}, - {ident: intr.intern(@~"width"), ex: width_expr}, - {ident: intr.intern(@~"precision"), ex: precision_expr}, - {ident: intr.intern(@~"ty"), ex: ty_expr}, + build::Field { + ident: intr.intern(@~"flags"), ex: flags_expr + }, + build::Field { + ident: intr.intern(@~"width"), ex: width_expr + }, + build::Field { + ident: intr.intern(@~"precision"), ex: precision_expr + }, + build::Field { + ident: intr.intern(@~"ty"), ex: ty_expr + }, ] ) } diff --git a/src/libsyntax/ext/pipes/ast_builder.rs b/src/libsyntax/ext/pipes/ast_builder.rs index 58ab05987a600..49f7fe5853e7b 100644 --- a/src/libsyntax/ext/pipes/ast_builder.rs +++ b/src/libsyntax/ext/pipes/ast_builder.rs @@ -54,7 +54,7 @@ pub trait append_types { fn add_tys(+tys: ~[@ast::Ty]) -> @ast::path; } -pub impl @ast::path: append_types { +pub impl append_types for @ast::path { fn add_ty(ty: @ast::Ty) -> @ast::path { @ast::path { types: vec::append_one(self.types, ty), .. *self} @@ -67,53 +67,60 @@ pub impl @ast::path: append_types { } pub trait ext_ctxt_ast_builder { - fn ty_param(id: ast::ident, +bounds: ~[ast::ty_param_bound]) + fn ty_param(&self, id: ast::ident, +bounds: ~[ast::ty_param_bound]) -> ast::ty_param; - fn arg(name: ident, ty: @ast::Ty) -> ast::arg; - fn expr_block(e: @ast::expr) -> ast::blk; - fn fn_decl(+inputs: ~[ast::arg], output: @ast::Ty) -> ast::fn_decl; - fn item(name: ident, span: span, +node: ast::item_) -> @ast::item; - fn item_fn_poly(name: ident, + fn arg(&self, name: ident, ty: @ast::Ty) -> ast::arg; + fn expr_block(&self, e: @ast::expr) -> ast::blk; + fn fn_decl(&self, +inputs: ~[ast::arg], output: @ast::Ty) -> ast::fn_decl; + fn item(&self, name: ident, span: span, +node: ast::item_) -> @ast::item; + fn item_fn_poly(&self, name: ident, +inputs: ~[ast::arg], output: @ast::Ty, +ty_params: ~[ast::ty_param], +body: ast::blk) -> @ast::item; - fn item_fn(name: ident, + fn item_fn(&self, name: ident, +inputs: ~[ast::arg], output: @ast::Ty, +body: ast::blk) -> @ast::item; - fn item_enum_poly(name: ident, + fn item_enum_poly(&self, name: ident, span: span, +enum_definition: ast::enum_def, +ty_params: ~[ast::ty_param]) -> @ast::item; - fn item_enum(name: ident, span: span, + fn item_enum(&self, name: ident, span: span, +enum_definition: ast::enum_def) -> @ast::item; - fn variant(name: ident, span: span, +tys: ~[@ast::Ty]) -> ast::variant; - fn item_mod(name: ident, span: span, +items: ~[@ast::item]) -> @ast::item; - fn ty_path_ast_builder(path: @ast::path) -> @ast::Ty; - fn item_ty_poly(name: ident, + fn item_struct_poly(&self, name: ident, span: span, + struct_def: ast::struct_def, + ty_params: ~[ast::ty_param]) -> @ast::item; + fn item_struct(&self, name: ident, span: span, + struct_def: ast::struct_def) -> @ast::item; + fn struct_expr(&self, path: @ast::path, + fields: ~[ast::field]) -> @ast::expr; + fn variant(&self, name: ident, span: span, + +tys: ~[@ast::Ty]) -> ast::variant; + fn item_mod(&self, name: ident, span: span, + +items: ~[@ast::item]) -> @ast::item; + fn ty_path_ast_builder(&self, path: @ast::path) -> @ast::Ty; + fn item_ty_poly(&self, name: ident, span: span, ty: @ast::Ty, +params: ~[ast::ty_param]) -> @ast::item; - fn item_ty(name: ident, span: span, ty: @ast::Ty) -> @ast::item; - fn ty_vars(+ty_params: ~[ast::ty_param]) -> ~[@ast::Ty]; - fn ty_vars_global(+ty_params: ~[ast::ty_param]) -> ~[@ast::Ty]; - fn ty_field_imm(name: ident, ty: @ast::Ty) -> ast::ty_field; - fn ty_rec(+v: ~[ast::ty_field]) -> @ast::Ty; - fn field_imm(name: ident, e: @ast::expr) -> ast::field; - fn rec(+v: ~[ast::field]) -> @ast::expr; - fn block(+stmts: ~[@ast::stmt], e: @ast::expr) -> ast::blk; - fn stmt_let(ident: ident, e: @ast::expr) -> @ast::stmt; - fn stmt_expr(e: @ast::expr) -> @ast::stmt; - fn block_expr(b: ast::blk) -> @ast::expr; - fn ty_option(ty: @ast::Ty) -> @ast::Ty; - fn ty_infer() -> @ast::Ty; - fn ty_nil_ast_builder() -> @ast::Ty; - fn strip_bounds(bounds: &[ast::ty_param]) -> ~[ast::ty_param]; + fn item_ty(&self, name: ident, span: span, ty: @ast::Ty) -> @ast::item; + fn ty_vars(&self, +ty_params: ~[ast::ty_param]) -> ~[@ast::Ty]; + fn ty_vars_global(&self, +ty_params: ~[ast::ty_param]) -> ~[@ast::Ty]; + fn ty_field_imm(&self, name: ident, ty: @ast::Ty) -> ast::ty_field; + fn field_imm(&self, name: ident, e: @ast::expr) -> ast::field; + fn block(&self, +stmts: ~[@ast::stmt], e: @ast::expr) -> ast::blk; + fn stmt_let(&self, ident: ident, e: @ast::expr) -> @ast::stmt; + fn stmt_expr(&self, e: @ast::expr) -> @ast::stmt; + fn block_expr(&self, b: ast::blk) -> @ast::expr; + fn ty_option(&self, ty: @ast::Ty) -> @ast::Ty; + fn ty_infer(&self) -> @ast::Ty; + fn ty_nil_ast_builder(&self) -> @ast::Ty; + fn strip_bounds(&self, bounds: &[ast::ty_param]) -> ~[ast::ty_param]; } -pub impl ext_ctxt: ext_ctxt_ast_builder { - fn ty_option(ty: @ast::Ty) -> @ast::Ty { +pub impl ext_ctxt_ast_builder for ext_ctxt { + fn ty_option(&self, ty: @ast::Ty) -> @ast::Ty { self.ty_path_ast_builder(path_global(~[ self.ident_of(~"core"), self.ident_of(~"option"), @@ -121,7 +128,7 @@ pub impl ext_ctxt: ext_ctxt_ast_builder { ], dummy_sp()).add_ty(ty)) } - fn block_expr(b: ast::blk) -> @ast::expr { + fn block_expr(&self, b: ast::blk) -> @ast::expr { @expr { id: self.next_id(), callee_id: self.next_id(), @@ -130,33 +137,24 @@ pub impl ext_ctxt: ext_ctxt_ast_builder { } } - fn stmt_expr(e: @ast::expr) -> @ast::stmt { + fn stmt_expr(&self, e: @ast::expr) -> @ast::stmt { @spanned { node: ast::stmt_expr(e, self.next_id()), span: dummy_sp()} } - fn stmt_let(ident: ident, e: @ast::expr) -> @ast::stmt { - let ext_cx = self; + fn stmt_let(&self, ident: ident, e: @ast::expr) -> @ast::stmt { + let ext_cx = *self; quote_stmt!( let $ident = $e; ) } - fn field_imm(name: ident, e: @ast::expr) -> ast::field { + fn field_imm(&self, name: ident, e: @ast::expr) -> ast::field { spanned { node: ast::field_ { mutbl: ast::m_imm, ident: name, expr: e }, span: dummy_sp(), } } - fn rec(+fields: ~[ast::field]) -> @ast::expr { - @expr { - id: self.next_id(), - callee_id: self.next_id(), - node: ast::expr_rec(fields, None), - span: dummy_sp(), - } - } - - fn ty_field_imm(name: ident, ty: @ast::Ty) -> ast::ty_field { + fn ty_field_imm(&self, name: ident, ty: @ast::Ty) -> ast::ty_field { spanned { node: ast::ty_field_ { ident: name, @@ -166,15 +164,7 @@ pub impl ext_ctxt: ext_ctxt_ast_builder { } } - fn ty_rec(+fields: ~[ast::ty_field]) -> @ast::Ty { - @ast::Ty { - id: self.next_id(), - node: ast::ty_rec(fields), - span: dummy_sp(), - } - } - - fn ty_infer() -> @ast::Ty { + fn ty_infer(&self) -> @ast::Ty { @ast::Ty { id: self.next_id(), node: ast::ty_infer, @@ -182,13 +172,13 @@ pub impl ext_ctxt: ext_ctxt_ast_builder { } } - fn ty_param(id: ast::ident, +bounds: ~[ast::ty_param_bound]) + fn ty_param(&self, id: ast::ident, +bounds: ~[ast::ty_param_bound]) -> ast::ty_param { ast::ty_param { ident: id, id: self.next_id(), bounds: @bounds } } - fn arg(name: ident, ty: @ast::Ty) -> ast::arg { + fn arg(&self, name: ident, ty: @ast::Ty) -> ast::arg { ast::arg { mode: ast::infer(self.next_id()), is_mutbl: false, @@ -205,7 +195,7 @@ pub impl ext_ctxt: ext_ctxt_ast_builder { } } - fn block(+stmts: ~[@ast::stmt], e: @ast::expr) -> ast::blk { + fn block(&self, +stmts: ~[@ast::stmt], e: @ast::expr) -> ast::blk { let blk = ast::blk_ { view_items: ~[], stmts: stmts, @@ -217,11 +207,11 @@ pub impl ext_ctxt: ext_ctxt_ast_builder { spanned { node: blk, span: dummy_sp() } } - fn expr_block(e: @ast::expr) -> ast::blk { + fn expr_block(&self, e: @ast::expr) -> ast::blk { self.block(~[], e) } - fn fn_decl(+inputs: ~[ast::arg], + fn fn_decl(&self, +inputs: ~[ast::arg], output: @ast::Ty) -> ast::fn_decl { ast::fn_decl { inputs: inputs, @@ -230,8 +220,7 @@ pub impl ext_ctxt: ext_ctxt_ast_builder { } } - fn item(name: ident, - span: span, + fn item(&self, name: ident, span: span, +node: ast::item_) -> @ast::item { // XXX: Would be nice if our generated code didn't violate @@ -239,9 +228,10 @@ pub impl ext_ctxt: ext_ctxt_ast_builder { let non_camel_case_attribute = respan(dummy_sp(), ast::attribute_ { style: ast::attr_outer, value: respan(dummy_sp(), - ast::meta_list(~"allow", ~[ + ast::meta_list(@~"allow", ~[ @respan(dummy_sp(), - ast::meta_word(~"non_camel_case_types")) + ast::meta_word( + @~"non_camel_case_types")) ])), is_sugared_doc: false }); @@ -254,7 +244,7 @@ pub impl ext_ctxt: ext_ctxt_ast_builder { span: span } } - fn item_fn_poly(name: ident, + fn item_fn_poly(&self, name: ident, +inputs: ~[ast::arg], output: @ast::Ty, +ty_params: ~[ast::ty_param], @@ -267,27 +257,46 @@ pub impl ext_ctxt: ext_ctxt_ast_builder { body)) } - fn item_fn(name: ident, + fn item_fn(&self, name: ident, +inputs: ~[ast::arg], output: @ast::Ty, +body: ast::blk) -> @ast::item { self.item_fn_poly(name, inputs, output, ~[], body) } - fn item_enum_poly(name: ident, - span: span, + fn item_enum_poly(&self, name: ident, span: span, +enum_definition: ast::enum_def, +ty_params: ~[ast::ty_param]) -> @ast::item { self.item(name, span, ast::item_enum(enum_definition, ty_params)) } - fn item_enum(name: ident, span: span, + fn item_enum(&self, name: ident, span: span, +enum_definition: ast::enum_def) -> @ast::item { self.item_enum_poly(name, span, enum_definition, ~[]) } - fn variant(name: ident, - span: span, + fn item_struct(&self, name: ident, span: span, + struct_def: ast::struct_def) -> @ast::item { + self.item_struct_poly(name, span, struct_def, ~[]) + } + + fn item_struct_poly(&self, name: ident, span: span, + struct_def: ast::struct_def, + ty_params: ~[ast::ty_param]) -> @ast::item { + self.item(name, span, ast::item_struct(@struct_def, ty_params)) + } + + fn struct_expr(&self, path: @ast::path, + fields: ~[ast::field]) -> @ast::expr { + @ast::expr { + id: self.next_id(), + callee_id: self.next_id(), + node: ast::expr_struct(path, fields, None), + span: dummy_sp() + } + } + + fn variant(&self, name: ident, span: span, +tys: ~[@ast::Ty]) -> ast::variant { let args = do tys.map |ty| { ast::variant_arg { ty: *ty, id: self.next_id() } @@ -300,17 +309,18 @@ pub impl ext_ctxt: ext_ctxt_ast_builder { kind: ast::tuple_variant_kind(args), id: self.next_id(), disr_expr: None, - vis: ast::public}, + vis: ast::public + }, span: span, } } - fn item_mod(name: ident, - span: span, + fn item_mod(&self, name: ident, span: span, +items: ~[@ast::item]) -> @ast::item { + // XXX: Total hack: import `core::kinds::Owned` to work around a - // parser bug whereby `fn f` doesn't parse. - let vi = ast::view_item_import(~[ + // parser bug whereby `fn f` doesn't parse. + let vi = ast::view_item_use(~[ @codemap::spanned { node: ast::view_path_simple( self.ident_of(~"Owned"), @@ -345,7 +355,7 @@ pub impl ext_ctxt: ext_ctxt_ast_builder { ) } - fn ty_path_ast_builder(path: @ast::path) -> @ast::Ty { + fn ty_path_ast_builder(&self, path: @ast::path) -> @ast::Ty { @ast::Ty { id: self.next_id(), node: ast::ty_path(path, self.next_id()), @@ -353,7 +363,7 @@ pub impl ext_ctxt: ext_ctxt_ast_builder { } } - fn ty_nil_ast_builder() -> @ast::Ty { + fn ty_nil_ast_builder(&self) -> @ast::Ty { @ast::Ty { id: self.next_id(), node: ast::ty_nil, @@ -361,29 +371,27 @@ pub impl ext_ctxt: ext_ctxt_ast_builder { } } - fn strip_bounds(bounds: &[ast::ty_param]) -> ~[ast::ty_param] { + fn strip_bounds(&self, bounds: &[ast::ty_param]) -> ~[ast::ty_param] { do bounds.map |ty_param| { ast::ty_param { bounds: @~[], ..copy *ty_param } } } - fn item_ty_poly(name: ident, - span: span, - ty: @ast::Ty, + fn item_ty_poly(&self, name: ident, span: span, ty: @ast::Ty, +params: ~[ast::ty_param]) -> @ast::item { self.item(name, span, ast::item_ty(ty, params)) } - fn item_ty(name: ident, span: span, ty: @ast::Ty) -> @ast::item { + fn item_ty(&self, name: ident, span: span, ty: @ast::Ty) -> @ast::item { self.item_ty_poly(name, span, ty, ~[]) } - fn ty_vars(+ty_params: ~[ast::ty_param]) -> ~[@ast::Ty] { + fn ty_vars(&self, +ty_params: ~[ast::ty_param]) -> ~[@ast::Ty] { ty_params.map(|p| self.ty_path_ast_builder( path(~[p.ident], dummy_sp()))) } - fn ty_vars_global(+ty_params: ~[ast::ty_param]) -> ~[@ast::Ty] { + fn ty_vars_global(&self, +ty_params: ~[ast::ty_param]) -> ~[@ast::Ty] { ty_params.map(|p| self.ty_path_ast_builder( path(~[p.ident], dummy_sp()))) } diff --git a/src/libsyntax/ext/pipes/check.rs b/src/libsyntax/ext/pipes/check.rs index cde6a581dced0..cc42a0992cbed 100644 --- a/src/libsyntax/ext/pipes/check.rs +++ b/src/libsyntax/ext/pipes/check.rs @@ -37,11 +37,11 @@ use ext::base::ext_ctxt; use ext::pipes::proto::{state, protocol, next_state}; use ext::pipes::proto; -pub impl ext_ctxt: proto::visitor<(), (), ()> { - fn visit_proto(_proto: protocol, +pub impl proto::visitor<(), (), ()> for ext_ctxt { + fn visit_proto(&self, _proto: protocol, _states: &[()]) { } - fn visit_state(state: state, _m: &[()]) { + fn visit_state(&self, state: state, _m: &[()]) { if state.messages.len() == 0 { self.span_warn( state.span, // use a real span! @@ -51,30 +51,30 @@ pub impl ext_ctxt: proto::visitor<(), (), ()> { } } - fn visit_message(name: ~str, _span: span, _tys: &[@ast::Ty], + fn visit_message(&self, name: ~str, _span: span, _tys: &[@ast::Ty], this: state, next: Option) { match next { - Some(next_state { state: ref next, tys: next_tys }) => { + Some(ref next_state) => { let proto = this.proto; - if !proto.has_state((*next)) { + if !proto.has_state(next_state.state) { // This should be a span fatal, but then we need to // track span information. self.span_err( - proto.get_state((*next)).span, + proto.get_state(next_state.state).span, fmt!("message %s steps to undefined state, %s", - name, (*next))); + name, next_state.state)); } else { - let next = proto.get_state((*next)); + let next = proto.get_state(next_state.state); - if next.ty_params.len() != next_tys.len() { + if next.ty_params.len() != next_state.tys.len() { self.span_err( next.span, // use a real span fmt!("message %s target (%s) \ needs %u type parameters, but got %u", name, next.name, next.ty_params.len(), - next_tys.len())); + next_state.tys.len())); } } } diff --git a/src/libsyntax/ext/pipes/liveness.rs b/src/libsyntax/ext/pipes/liveness.rs index b0a8f49c7a243..a7f01d7564859 100644 --- a/src/libsyntax/ext/pipes/liveness.rs +++ b/src/libsyntax/ext/pipes/liveness.rs @@ -43,17 +43,17 @@ use ext::base::ext_ctxt; use ext::pipes::proto::protocol; use core::str; -use std::bitv::{Bitv}; +use std::bitv::Bitv; pub fn analyze(proto: protocol, _cx: ext_ctxt) { debug!("initializing colive analysis"); let num_states = proto.num_states(); - let colive = do (copy proto.states).map_to_vec |state| { - let bv = ~Bitv(num_states, false); + let mut colive = do (copy proto.states).map_to_vec |state| { + let mut bv = ~Bitv::new(num_states, false); for state.reachable |s| { bv.set(s.id, true); } - move bv + bv }; let mut i = 0; @@ -61,15 +61,19 @@ pub fn analyze(proto: protocol, _cx: ext_ctxt) { while changed { changed = false; debug!("colive iteration %?", i); + let mut new_colive = ~[]; for colive.eachi |i, this_colive| { + let mut result = ~this_colive.clone(); let this = proto.get_state_by_id(i); for this_colive.ones |j| { let next = proto.get_state_by_id(j); if this.dir == next.dir { - changed = changed || this_colive.union(colive[j]); + changed = result.union(colive[j]) || changed; } } + new_colive.push(result) } + colive = new_colive; i += 1; } diff --git a/src/libsyntax/ext/pipes/mod.rs b/src/libsyntax/ext/pipes/mod.rs index 8f0f00f42c015..8b8e48bd5229b 100644 --- a/src/libsyntax/ext/pipes/mod.rs +++ b/src/libsyntax/ext/pipes/mod.rs @@ -68,12 +68,12 @@ pub fn expand_proto(cx: ext_ctxt, _sp: span, id: ast::ident, tt: ~[ast::token_tree]) -> base::MacResult { let sess = cx.parse_sess(); let cfg = cx.cfg(); - let tt_rdr = new_tt_reader(cx.parse_sess().span_diagnostic, + let tt_rdr = new_tt_reader(copy cx.parse_sess().span_diagnostic, cx.parse_sess().interner, None, tt); let rdr = tt_rdr as reader; let rust_parser = Parser(sess, cfg, rdr.dup()); - let proto = rust_parser.parse_proto(cx.str_of(id)); + let mut proto = rust_parser.parse_proto(cx.str_of(id)); // check for errors visit(proto, cx); diff --git a/src/libsyntax/ext/pipes/parse_proto.rs b/src/libsyntax/ext/pipes/parse_proto.rs index 6a1708b8e2b51..66feb7cc753cf 100644 --- a/src/libsyntax/ext/pipes/parse_proto.rs +++ b/src/libsyntax/ext/pipes/parse_proto.rs @@ -11,34 +11,36 @@ // Parsing pipes protocols from token trees. use ext::pipes::pipec::*; +use parse::common::SeqSep; use parse::parser; use parse::token; use core::prelude::*; pub trait proto_parser { - fn parse_proto(id: ~str) -> protocol; - fn parse_state(proto: protocol); - fn parse_message(state: state); + fn parse_proto(&self, id: ~str) -> protocol; + fn parse_state(&self, proto: protocol); + fn parse_message(&self, state: state); } -pub impl parser::Parser: proto_parser { - fn parse_proto(id: ~str) -> protocol { - let proto = protocol(id, self.span); +pub impl proto_parser for parser::Parser { + fn parse_proto(&self, id: ~str) -> protocol { + let proto = protocol(id, *self.span); - self.parse_seq_to_before_end(token::EOF, - {sep: None, trailing_sep_allowed: false}, - |self| self.parse_state(proto)); + self.parse_seq_to_before_end(token::EOF, SeqSep { + sep: None, + trailing_sep_allowed: false + }, |self| self.parse_state(proto)); return proto; } - fn parse_state(proto: protocol) { + fn parse_state(&self, proto: protocol) { let id = self.parse_ident(); let name = *self.interner.get(id); self.expect(token::COLON); - let dir = match copy self.token { + let dir = match *self.token { token::IDENT(n, _) => self.interner.get(n), _ => fail!() }; @@ -49,43 +51,45 @@ pub impl parser::Parser: proto_parser { _ => fail!() }; - let typarms = if self.token == token::LT { + let typarms = if *self.token == token::LT { self.parse_ty_params() - } - else { ~[] }; + } else { + ~[] + }; let state = proto.add_state_poly(name, id, dir, typarms); // parse the messages self.parse_unspanned_seq( - token::LBRACE, token::RBRACE, - {sep: Some(token::COMMA), trailing_sep_allowed: true}, - |self| self.parse_message(state)); + token::LBRACE, token::RBRACE, SeqSep { + sep: Some(token::COMMA), + trailing_sep_allowed: true + }, |self| self.parse_message(state)); } - fn parse_message(state: state) { + fn parse_message(&self, state: state) { let mname = *self.interner.get(self.parse_ident()); - let args = if self.token == token::LPAREN { + let args = if *self.token == token::LPAREN { self.parse_unspanned_seq(token::LPAREN, - token::RPAREN, - {sep: Some(token::COMMA), - trailing_sep_allowed: true}, - |p| p.parse_ty(false)) + token::RPAREN, SeqSep { + sep: Some(token::COMMA), + trailing_sep_allowed: true + }, |p| p.parse_ty(false)) } else { ~[] }; self.expect(token::RARROW); - let next = match copy self.token { + let next = match *self.token { token::IDENT(_, _) => { let name = *self.interner.get(self.parse_ident()); - let ntys = if self.token == token::LT { + let ntys = if *self.token == token::LT { self.parse_unspanned_seq(token::LT, - token::GT, - {sep: Some(token::COMMA), - trailing_sep_allowed: true}, - |p| p.parse_ty(false)) + token::GT, SeqSep { + sep: Some(token::COMMA), + trailing_sep_allowed: true + }, |p| p.parse_ty(false)) } else { ~[] }; Some(next_state {state: name, tys: ntys}) @@ -98,7 +102,7 @@ pub impl parser::Parser: proto_parser { _ => self.fatal(~"invalid next state") }; - state.add_message(mname, copy self.span, args, next); + state.add_message(mname, *self.span, args, next); } } diff --git a/src/libsyntax/ext/pipes/pipec.rs b/src/libsyntax/ext/pipes/pipec.rs index da0ac4e08ab06..444b09d9ae458 100644 --- a/src/libsyntax/ext/pipes/pipec.rs +++ b/src/libsyntax/ext/pipes/pipec.rs @@ -27,38 +27,39 @@ use core::to_str::ToStr; use core::vec; pub trait gen_send { - fn gen_send(cx: ext_ctxt, try: bool) -> @ast::item; - fn to_ty(cx: ext_ctxt) -> @ast::Ty; + fn gen_send(&mut self, cx: ext_ctxt, try: bool) -> @ast::item; + fn to_ty(&mut self, cx: ext_ctxt) -> @ast::Ty; } pub trait to_type_decls { - fn to_type_decls(cx: ext_ctxt) -> ~[@ast::item]; - fn to_endpoint_decls(cx: ext_ctxt, dir: direction) -> ~[@ast::item]; + fn to_type_decls(&self, cx: ext_ctxt) -> ~[@ast::item]; + fn to_endpoint_decls(&self, cx: ext_ctxt, + dir: direction) -> ~[@ast::item]; } pub trait gen_init { - fn gen_init(cx: ext_ctxt) -> @ast::item; - fn compile(cx: ext_ctxt) -> @ast::item; - fn buffer_ty_path(cx: ext_ctxt) -> @ast::Ty; - fn gen_buffer_type(cx: ext_ctxt) -> @ast::item; - fn gen_buffer_init(ext_cx: ext_ctxt) -> @ast::expr; - fn gen_init_bounded(ext_cx: ext_ctxt) -> @ast::expr; + fn gen_init(&self, cx: ext_ctxt) -> @ast::item; + fn compile(&self, cx: ext_ctxt) -> @ast::item; + fn buffer_ty_path(&self, cx: ext_ctxt) -> @ast::Ty; + fn gen_buffer_type(&self, cx: ext_ctxt) -> @ast::item; + fn gen_buffer_init(&self, ext_cx: ext_ctxt) -> @ast::expr; + fn gen_init_bounded(&self, ext_cx: ext_ctxt) -> @ast::expr; } -pub impl message: gen_send { - fn gen_send(cx: ext_ctxt, try: bool) -> @ast::item { +pub impl gen_send for message { + fn gen_send(&mut self, cx: ext_ctxt, try: bool) -> @ast::item { debug!("pipec: gen_send"); - match self { - message(ref _id, span, tys, this, - Some(next_state {state: ref next, tys: next_tys})) => { + let name = self.name(); + let params = self.get_params(); + + match *self { + message(ref _id, span, ref tys, this, Some(ref next_state)) => { debug!("pipec: next state exists"); - let next = this.proto.get_state((*next)); - assert next_tys.len() == next.ty_params.len(); + let next = this.proto.get_state(next_state.state); + assert next_state.tys.len() == next.ty_params.len(); let arg_names = tys.mapi(|i, _ty| cx.ident_of(~"x_"+i.to_str())); - let args_ast = (arg_names, tys).map( - |n, t| cx.arg(*n, *t) - ); + let args_ast = (arg_names, *tys).map(|n, t| cx.arg(*n, *t)); let pipe_ty = cx.ty_path_ast_builder( path(~[this.data_name()], span) @@ -69,77 +70,76 @@ pub impl message: gen_send { args_ast); let mut body = ~"{\n"; - body += fmt!("use super::%s;\n", self.name()); + body += fmt!("use super::%s;\n", name); if this.proto.is_bounded() { let (sp, rp) = match (this.dir, next.dir) { - (send, send) => (~"move c", ~"move s"), + (send, send) => (~"c", ~"s"), (send, recv) => (~"s", ~"c"), (recv, send) => (~"s", ~"c"), - (recv, recv) => (~"move c", ~"move s") + (recv, recv) => (~"c", ~"s") }; body += ~"let b = pipe.reuse_buffer();\n"; - body += fmt!("let %s = ::pipes::SendPacketBuffered(\ + body += fmt!("let %s = ::core::pipes::SendPacketBuffered(\ ::ptr::addr_of(&(b.buffer.data.%s)));\n", sp, next.name); - body += fmt!("let %s = ::pipes::RecvPacketBuffered(\ + body += fmt!("let %s = ::core::pipes::RecvPacketBuffered(\ ::ptr::addr_of(&(b.buffer.data.%s)));\n", rp, next.name); } else { let pat = match (this.dir, next.dir) { - (send, send) => "(move c, move s)", + (send, send) => "(c, s)", (send, recv) => "(s, c)", (recv, send) => "(s, c)", - (recv, recv) => "(move c, move s)" + (recv, recv) => "(c, s)" }; - body += fmt!("let %s = ::pipes::entangle();\n", pat); + body += fmt!("let %s = ::core::pipes::entangle();\n", pat); } body += fmt!("let message = %s(%s);\n", - self.name(), + name, str::connect(vec::append_one( - arg_names.map(|x| ~"move " + cx.str_of(*x)), - ~"move s"), ~", ")); + arg_names.map(|x| cx.str_of(*x)), + ~"s"), ~", ")); if !try { - body += fmt!("::pipes::send(move pipe, move message);\n"); + body += fmt!("::core::pipes::send(pipe, message);\n"); // return the new channel - body += ~"move c }"; + body += ~"c }"; } else { - body += fmt!("if ::pipes::send(move pipe, move message) {\n \ - ::pipes::rt::make_some(move c) \ - } else { ::pipes::rt::make_none() } }"); + body += fmt!("if ::core::pipes::send(pipe, message) {\n \ + ::core::pipes::rt::make_some(c) \ + } else { ::core::pipes::rt::make_none() } }"); } let body = cx.parse_expr(body); let mut rty = cx.ty_path_ast_builder(path(~[next.data_name()], span) - .add_tys(next_tys)); + .add_tys(next_state.tys)); if try { rty = cx.ty_option(rty); } - let name = cx.ident_of(if try { ~"try_" + self.name() - } else { self.name() } ); + let name = cx.ident_of(if try { ~"try_" + name } else { name } ); cx.item_fn_poly(name, args_ast, rty, - self.get_params(), + params, cx.expr_block(body)) } - message(ref _id, span, tys, this, None) => { + message(ref _id, span, ref tys, this, None) => { debug!("pipec: no next state"); let arg_names = tys.mapi(|i, _ty| (~"x_" + i.to_str())); - let args_ast = (arg_names, tys).map( - |n, t| cx.arg(cx.ident_of(*n), *t) - ); + let args_ast = do (arg_names, *tys).map |n, t| { + cx.arg(cx.ident_of(*n), *t) + }; let args_ast = vec::append( ~[cx.arg(cx.ident_of(~"pipe"), @@ -153,34 +153,29 @@ pub impl message: gen_send { ~"" } else { - ~"(" + str::connect(arg_names.map(|x| ~"move " + *x), + ~"(" + str::connect(arg_names.map(|x| *x), ~", ") + ~")" }; let mut body = ~"{ "; - body += fmt!("use super::%s;\n", self.name()); - body += fmt!("let message = %s%s;\n", - self.name(), - message_args); + body += fmt!("use super::%s;\n", name); + body += fmt!("let message = %s%s;\n", name, message_args); if !try { - body += fmt!("::pipes::send(move pipe, move message);\n"); + body += fmt!("::core::pipes::send(pipe, message);\n"); body += ~" }"; } else { - body += fmt!("if ::pipes::send(move pipe, move message) \ + body += fmt!("if ::core::pipes::send(pipe, message) \ { \ - ::pipes::rt::make_some(()) \ + ::core::pipes::rt::make_some(()) \ } else { \ - ::pipes::rt::make_none() \ + ::core::pipes::rt::make_none() \ } }"); } let body = cx.parse_expr(body); - let name = if try { - ~"try_" + self.name() - } - else { self.name() }; + let name = if try { ~"try_" + name } else { name }; cx.item_fn_poly(cx.ident_of(name), args_ast, @@ -189,20 +184,20 @@ pub impl message: gen_send { } else { cx.ty_nil_ast_builder() }, - self.get_params(), + params, cx.expr_block(body)) } } } - fn to_ty(cx: ext_ctxt) -> @ast::Ty { + fn to_ty(&mut self, cx: ext_ctxt) -> @ast::Ty { cx.ty_path_ast_builder(path(~[cx.ident_of(self.name())], self.span()) .add_tys(cx.ty_vars_global(self.get_params()))) } } -pub impl state: to_type_decls { - fn to_type_decls(cx: ext_ctxt) -> ~[@ast::item] { +pub impl to_type_decls for state { + fn to_type_decls(&self, cx: ext_ctxt) -> ~[@ast::item] { debug!("pipec: to_type_decls"); // This compiles into two different type declarations. Say the // state is called ping. This will generate both `ping` and @@ -218,8 +213,8 @@ pub impl state: to_type_decls { let message(name, span, tys, this, next) = *m; let tys = match next { - Some(next_state { state: ref next, tys: next_tys }) => { - let next = this.proto.get_state((*next)); + Some(ref next_state) => { + let next = this.proto.get_state((next_state.state)); let next_name = cx.str_of(next.data_name()); let dir = match this.dir { @@ -231,7 +226,7 @@ pub impl state: to_type_decls { cx.ty_path_ast_builder( path(~[cx.ident_of(dir), cx.ident_of(next_name)], span) - .add_tys(next_tys))) + .add_tys(next_state.tys))) } None => tys }; @@ -253,17 +248,22 @@ pub impl state: to_type_decls { ] } - fn to_endpoint_decls(cx: ext_ctxt, dir: direction) -> ~[@ast::item] { + fn to_endpoint_decls(&self, cx: ext_ctxt, + dir: direction) -> ~[@ast::item] { debug!("pipec: to_endpoint_decls"); let dir = match dir { send => (*self).dir, recv => (*self).dir.reverse() }; let mut items = ~[]; - for self.messages.each |m| { - if dir == send { - items.push(m.gen_send(cx, true)); - items.push(m.gen_send(cx, false)); + + { + let messages = &mut *self.messages; + for vec::each_mut(*messages) |m| { + if dir == send { + items.push(m.gen_send(cx, true)); + items.push(m.gen_send(cx, false)); + } } } @@ -273,7 +273,8 @@ pub impl state: to_type_decls { self.data_name(), self.span, cx.ty_path_ast_builder( - path_global(~[cx.ident_of(~"pipes"), + path_global(~[cx.ident_of(~"core"), + cx.ident_of(~"pipes"), cx.ident_of(dir.to_str() + ~"Packet")], dummy_sp()) .add_ty(cx.ty_path_ast_builder( @@ -289,7 +290,8 @@ pub impl state: to_type_decls { self.data_name(), self.span, cx.ty_path_ast_builder( - path_global(~[cx.ident_of(~"pipes"), + path_global(~[cx.ident_of(~"core"), + cx.ident_of(~"pipes"), cx.ident_of(dir.to_str() + ~"PacketBuffered")], dummy_sp()) @@ -305,9 +307,8 @@ pub impl state: to_type_decls { } } -pub impl protocol: gen_init { - - fn gen_init(cx: ext_ctxt) -> @ast::item { +pub impl gen_init for protocol { + fn gen_init(&self, cx: ext_ctxt) -> @ast::item { let ext_cx = cx; debug!("gen_init"); @@ -315,11 +316,11 @@ pub impl protocol: gen_init { let body = if !self.is_bounded() { match start_state.dir { - send => quote_expr!( ::pipes::entangle() ), + send => quote_expr!( ::core::pipes::entangle() ), recv => { quote_expr!({ - let (s, c) = ::pipes::entangle(); - (move c, move s) + let (s, c) = ::core::pipes::entangle(); + (c, s) }) } } @@ -331,35 +332,37 @@ pub impl protocol: gen_init { recv => { quote_expr!({ let (s, c) = $body; - (move c, move s) + (c, s) }) } } }; cx.parse_item(fmt!("pub fn init%s() -> (client::%s, server::%s)\ - { use pipes::HasBuffer; %s }", + { use core::pipes::HasBuffer; %s }", start_state.ty_params.to_source(cx), start_state.to_ty(cx).to_source(cx), start_state.to_ty(cx).to_source(cx), body.to_source(cx))) } - fn gen_buffer_init(ext_cx: ext_ctxt) -> @ast::expr { - ext_cx.rec(self.states.map_to_vec(|s| { + fn gen_buffer_init(&self, ext_cx: ext_ctxt) -> @ast::expr { + ext_cx.struct_expr(path(~[ext_cx.ident_of(~"__Buffer")], + dummy_sp()), + self.states.map_to_vec(|s| { let fty = s.to_ty(ext_cx); ext_cx.field_imm(ext_cx.ident_of(s.name), quote_expr!( - ::pipes::mk_packet::<$fty>() + ::core::pipes::mk_packet::<$fty>() )) })) } - fn gen_init_bounded(ext_cx: ext_ctxt) -> @ast::expr { + fn gen_init_bounded(&self, ext_cx: ext_ctxt) -> @ast::expr { debug!("gen_init_bounded"); let buffer_fields = self.gen_buffer_init(ext_cx); - let buffer = quote_expr!(~::pipes::Buffer { - header: ::pipes::BufferHeader(), + let buffer = quote_expr!(~::core::pipes::Buffer { + header: ::core::pipes::BufferHeader(), data: $buffer_fields, }); @@ -375,13 +378,13 @@ pub impl protocol: gen_init { quote_expr!({ let buffer = $buffer; - do ::pipes::entangle_buffer(move buffer) |buffer, data| { + do ::core::pipes::entangle_buffer(buffer) |buffer, data| { $entangle_body } }) } - fn buffer_ty_path(cx: ext_ctxt) -> @ast::Ty { + fn buffer_ty_path(&self, cx: ext_ctxt) -> @ast::Ty { let mut params: ~[ast::ty_param] = ~[]; for (copy self.states).each |s| { for s.ty_params.each |tp| { @@ -393,11 +396,12 @@ pub impl protocol: gen_init { } cx.ty_path_ast_builder(path(~[cx.ident_of(~"super"), - cx.ident_of(~"__Buffer")], self.span) + cx.ident_of(~"__Buffer")], + copy self.span) .add_tys(cx.ty_vars_global(params))) } - fn gen_buffer_type(cx: ext_ctxt) -> @ast::item { + fn gen_buffer_type(&self, cx: ext_ctxt) -> @ast::item { let ext_cx = cx; let mut params: ~[ast::ty_param] = ~[]; let fields = do (copy self.states).map_to_vec |s| { @@ -408,19 +412,33 @@ pub impl protocol: gen_init { } } let ty = s.to_ty(cx); - let fty = quote_ty!( ::pipes::Packet<$ty> ); - - cx.ty_field_imm(cx.ident_of(s.name), fty) + let fty = quote_ty!( ::core::pipes::Packet<$ty> ); + + @spanned { + node: ast::struct_field_ { + kind: ast::named_field( + cx.ident_of(s.name), + ast::struct_immutable, + ast::inherited), + id: cx.next_id(), + ty: fty + }, + span: dummy_sp() + } }; - cx.item_ty_poly( + cx.item_struct_poly( cx.ident_of(~"__Buffer"), dummy_sp(), - cx.ty_rec(fields), + ast::struct_def { + fields: fields, + dtor: None, + ctor_id: None + }, cx.strip_bounds(params)) } - fn compile(cx: ext_ctxt) -> @ast::item { + fn compile(&self, cx: ext_ctxt) -> @ast::item { let mut items = ~[self.gen_init(cx)]; let mut client_states = ~[]; let mut server_states = ~[]; @@ -437,12 +455,12 @@ pub impl protocol: gen_init { } items.push(cx.item_mod(cx.ident_of(~"client"), - self.span, + copy self.span, client_states)); items.push(cx.item_mod(cx.ident_of(~"server"), - self.span, + copy self.span, server_states)); - cx.item_mod(cx.ident_of(self.name), self.span, items) + cx.item_mod(cx.ident_of(self.name), copy self.span, items) } } diff --git a/src/libsyntax/ext/pipes/proto.rs b/src/libsyntax/ext/pipes/proto.rs index 6a1d93576941d..7c6dc1f937dca 100644 --- a/src/libsyntax/ext/pipes/proto.rs +++ b/src/libsyntax/ext/pipes/proto.rs @@ -16,24 +16,12 @@ use ext::base::ext_ctxt; use ext::pipes::ast_builder::{append_types, ext_ctxt_ast_builder, path}; use core::cmp; -use core::dvec::DVec; use core::to_str::ToStr; +#[deriving_eq] pub enum direction { send, recv } -pub impl direction : cmp::Eq { - pure fn eq(&self, other: &direction) -> bool { - match ((*self), (*other)) { - (send, send) => true, - (recv, recv) => true, - (send, _) => false, - (recv, _) => false, - } - } - pure fn ne(&self, other: &direction) -> bool { !(*self).eq(other) } -} - -pub impl direction: ToStr { +pub impl ToStr for direction { pure fn to_str(&self) -> ~str { match *self { send => ~"Send", @@ -43,8 +31,8 @@ pub impl direction: ToStr { } pub impl direction { - fn reverse() -> direction { - match self { + fn reverse(&self) -> direction { + match *self { send => recv, recv => send } @@ -56,62 +44,60 @@ pub struct next_state { tys: ~[@ast::Ty], } -pub enum message { - // name, span, data, current state, next state - message(~str, span, ~[@ast::Ty], state, Option) -} +// name, span, data, current state, next state +pub struct message(~str, span, ~[@ast::Ty], state, Option); pub impl message { - fn name() -> ~str { - match self { + fn name(&mut self) -> ~str { + match *self { message(ref id, _, _, _, _) => (*id) } } - fn span() -> span { - match self { + fn span(&mut self) -> span { + match *self { message(_, span, _, _, _) => span } } /// Return the type parameters actually used by this message - fn get_params() -> ~[ast::ty_param] { - match self { + fn get_params(&mut self) -> ~[ast::ty_param] { + match *self { message(_, _, _, this, _) => this.ty_params } } } -pub enum state { - state_(@{ - id: uint, - name: ~str, - ident: ast::ident, - span: span, - dir: direction, - ty_params: ~[ast::ty_param], - messages: DVec, - proto: protocol, - }), +pub type state = @state_; + +pub struct state_ { + id: uint, + name: ~str, + ident: ast::ident, + span: span, + dir: direction, + ty_params: ~[ast::ty_param], + messages: @mut ~[message], + proto: protocol } -pub impl state { - fn add_message(name: ~str, span: span, +pub impl state_ { + fn add_message(@self, name: ~str, span: span, +data: ~[@ast::Ty], next: Option) { self.messages.push(message(name, span, data, self, next)); } - fn filename() -> ~str { - (*self).proto.filename() + fn filename(&self) -> ~str { + self.proto.filename() } - fn data_name() -> ast::ident { + fn data_name(&self) -> ast::ident { self.ident } /// Returns the type that is used for the messages. - fn to_ty(cx: ext_ctxt) -> @ast::Ty { + fn to_ty(&self, cx: ext_ctxt) -> @ast::Ty { cx.ty_path_ast_builder (path(~[cx.ident_of(self.name)],self.span).add_tys( cx.ty_vars(self.ty_params))) @@ -119,7 +105,7 @@ pub impl state { /// Iterate over the states that can be reached in one message /// from this state. - fn reachable(f: fn(state) -> bool) { + fn reachable(&self, f: fn(state) -> bool) { for self.messages.each |m| { match *m { message(_, _, _, _, Some(next_state { state: ref id, _ })) => { @@ -132,17 +118,17 @@ pub impl state { } } -pub type protocol = @protocol_; +pub type protocol = @mut protocol_; pub fn protocol(name: ~str, +span: span) -> protocol { - @protocol_(name, span) + @mut protocol_(name, span) } pub fn protocol_(name: ~str, span: span) -> protocol_ { protocol_ { name: name, span: span, - states: DVec(), + states: @mut ~[], bounded: None } } @@ -150,31 +136,30 @@ pub fn protocol_(name: ~str, span: span) -> protocol_ { pub struct protocol_ { name: ~str, span: span, - states: DVec, + states: @mut ~[state], - mut bounded: Option, + bounded: Option, } pub impl protocol_ { - /// Get a state. - fn get_state(name: ~str) -> state { + fn get_state(&mut self, name: ~str) -> state { self.states.find(|i| i.name == name).get() } - fn get_state_by_id(id: uint) -> state { self.states[id] } + fn get_state_by_id(&mut self, id: uint) -> state { self.states[id] } - fn has_state(name: ~str) -> bool { + fn has_state(&mut self, name: ~str) -> bool { self.states.find(|i| i.name == name).is_some() } - fn filename() -> ~str { + fn filename(&mut self) -> ~str { ~"proto://" + self.name } - fn num_states() -> uint { self.states.len() } + fn num_states(&mut self) -> uint { self.states.len() } - fn has_ty_params() -> bool { + fn has_ty_params(&mut self) -> bool { for self.states.each |s| { if s.ty_params.len() > 0 { return true; @@ -182,34 +167,27 @@ pub impl protocol_ { } false } - fn is_bounded() -> bool { + fn is_bounded(&mut self) -> bool { let bounded = self.bounded.get(); bounded - //if bounded && self.has_ty_params() { - // debug!("protocol %s has is bounded, but type parameters\ - // are not yet supported.", - // *self.name); - // false - //} - //else { bounded } } } pub impl protocol { - fn add_state_poly(name: ~str, ident: ast::ident, dir: direction, + fn add_state_poly(&self, name: ~str, ident: ast::ident, dir: direction, +ty_params: ~[ast::ty_param]) -> state { - let messages = DVec(); + let messages = @mut ~[]; - let state = state_(@{ + let state = @state_ { id: self.states.len(), name: name, ident: ident, span: self.span, dir: dir, ty_params: ty_params, - messages: move messages, - proto: self - }); + messages: messages, + proto: *self + }; self.states.push(state); state @@ -217,9 +195,9 @@ pub impl protocol { } pub trait visitor { - fn visit_proto(proto: protocol, st: &[Tstate]) -> Tproto; - fn visit_state(state: state, m: &[Tmessage]) -> Tstate; - fn visit_message(name: ~str, spane: span, tys: &[@ast::Ty], + fn visit_proto(&self, proto: protocol, st: &[Tstate]) -> Tproto; + fn visit_state(&self, state: state, m: &[Tmessage]) -> Tstate; + fn visit_message(&self, name: ~str, spane: span, tys: &[@ast::Ty], this: state, next: Option) -> Tmessage; } diff --git a/src/libsyntax/ext/quote.rs b/src/libsyntax/ext/quote.rs index ffa6101d58fcc..d529ee0c01b01 100644 --- a/src/libsyntax/ext/quote.rs +++ b/src/libsyntax/ext/quote.rs @@ -515,7 +515,7 @@ fn expand_tts(cx: ext_ctxt, // try removing it when enough of them are gone. let p = parse::new_parser_from_tts(cx.parse_sess(), cx.cfg(), tts); - p.quote_depth += 1u; + *p.quote_depth += 1u; let tts = p.parse_all_token_trees(); p.abort_if_errors(); diff --git a/src/libsyntax/ext/source_util.rs b/src/libsyntax/ext/source_util.rs index dadc2e527b601..26c38c945c7f1 100644 --- a/src/libsyntax/ext/source_util.rs +++ b/src/libsyntax/ext/source_util.rs @@ -10,6 +10,7 @@ use codemap; use codemap::{FileMap, Loc, Pos, ExpandedFrom, span}; +use codemap::{CallInfo, NameAndSpan}; use ext::base::*; use ext::base; use ext::build::{mk_base_vec_e, mk_uint, mk_u8, mk_base_str}; @@ -22,10 +23,13 @@ use core::str; use core::vec; fn topmost_expn_info(expn_info: @codemap::ExpnInfo) -> @codemap::ExpnInfo { - let ExpandedFrom({call_site, _}) = *expn_info; + let ExpandedFrom(CallInfo { call_site, _ }) = *expn_info; match call_site.expn_info { Some(next_expn_info) => { - let ExpandedFrom({callie: {name, _}, _}) = *next_expn_info; + let ExpandedFrom(CallInfo { + callee: NameAndSpan {name, _}, + _ + }) = *next_expn_info; // Don't recurse into file using "include!" if name == ~"include" { return expn_info; } diff --git a/src/libsyntax/ext/trace_macros.rs b/src/libsyntax/ext/trace_macros.rs index a87882c4f207a..f662f0337bfbc 100644 --- a/src/libsyntax/ext/trace_macros.rs +++ b/src/libsyntax/ext/trace_macros.rs @@ -22,7 +22,7 @@ pub fn expand_trace_macros(cx: ext_ctxt, sp: span, tt: ~[ast::token_tree]) -> base::MacResult { let sess = cx.parse_sess(); let cfg = cx.cfg(); - let tt_rdr = new_tt_reader(cx.parse_sess().span_diagnostic, + let tt_rdr = new_tt_reader(copy cx.parse_sess().span_diagnostic, cx.parse_sess().interner, None, tt); let rdr = tt_rdr as reader; let rust_parser = Parser(sess, cfg, rdr.dup()); diff --git a/src/libsyntax/ext/tt/macro_parser.rs b/src/libsyntax/ext/tt/macro_parser.rs index 9e89e703c09bb..890420edf6d68 100644 --- a/src/libsyntax/ext/tt/macro_parser.rs +++ b/src/libsyntax/ext/tt/macro_parser.rs @@ -14,7 +14,7 @@ use codemap::{BytePos, mk_sp}; use codemap; use parse::common::*; //resolve bug? use parse::lexer::*; //resolve bug? -use parse::parse_sess; +use parse::ParseSess; use parse::parser::Parser; use parse::token::{Token, EOF, to_str, nonterminal}; use parse::token; @@ -101,7 +101,7 @@ eof: [a $( a )* a b ·] nonempty body. */ pub enum matcher_pos_up { /* to break a circularity */ - matcher_pos_up(Option) + matcher_pos_up(Option<~MatcherPos>) } pub fn is_some(&&mpu: matcher_pos_up) -> bool { @@ -111,17 +111,17 @@ pub fn is_some(&&mpu: matcher_pos_up) -> bool { } } -pub type matcher_pos = ~{ +pub struct MatcherPos { elts: ~[ast::matcher], // maybe should be /&? Need to understand regions. sep: Option, - mut idx: uint, - mut up: matcher_pos_up, // mutable for swapping only + idx: uint, + up: matcher_pos_up, // mutable for swapping only matches: ~[DVec<@named_match>], match_lo: uint, match_hi: uint, sp_lo: BytePos, -}; +} -pub fn copy_up(&& mpu: matcher_pos_up) -> matcher_pos { +pub fn copy_up(&& mpu: matcher_pos_up) -> ~MatcherPos { match &mpu { &matcher_pos_up(Some(ref mp)) => copy (*mp), _ => fail!() @@ -139,7 +139,7 @@ pub fn count_names(ms: &[matcher]) -> uint { #[allow(non_implicitly_copyable_typarams)] pub fn initial_matcher_pos(ms: ~[matcher], sep: Option, lo: BytePos) - -> matcher_pos { + -> ~MatcherPos { let mut match_idx_hi = 0u; for ms.each() |elt| { match elt.node { @@ -152,9 +152,16 @@ pub fn initial_matcher_pos(ms: ~[matcher], sep: Option, lo: BytePos) } } } - ~{elts: ms, sep: sep, mut idx: 0u, mut up: matcher_pos_up(None), - matches: copy vec::from_fn(count_names(ms), |_i| dvec::DVec()), - match_lo: 0u, match_hi: match_idx_hi, sp_lo: lo} + ~MatcherPos { + elts: ms, + sep: sep, + idx: 0u, + up: matcher_pos_up(None), + matches: copy vec::from_fn(count_names(ms), |_i| dvec::DVec()), + match_lo: 0u, + match_hi: match_idx_hi, + sp_lo: lo + } } // named_match is a pattern-match result for a single ast::match_nonterminal: @@ -181,11 +188,11 @@ pub enum named_match { matched_nonterminal(nonterminal) } -pub type earley_item = matcher_pos; +pub type earley_item = ~MatcherPos; -pub fn nameize(p_s: parse_sess, ms: ~[matcher], res: ~[@named_match]) +pub fn nameize(p_s: @mut ParseSess, ms: ~[matcher], res: ~[@named_match]) -> HashMap { - fn n_rec(p_s: parse_sess, m: matcher, res: ~[@named_match], + fn n_rec(p_s: @mut ParseSess, m: matcher, res: ~[@named_match], ret_val: HashMap) { match m { codemap::spanned {node: match_tok(_), _} => (), @@ -216,7 +223,7 @@ pub enum parse_result { error(codemap::span, ~str) } -pub fn parse_or_else(sess: parse_sess, cfg: ast::crate_cfg, rdr: reader, +pub fn parse_or_else(sess: @mut ParseSess, cfg: ast::crate_cfg, rdr: reader, ms: ~[matcher]) -> HashMap { match parse(sess, cfg, rdr, ms) { success(m) => m, @@ -225,7 +232,7 @@ pub fn parse_or_else(sess: parse_sess, cfg: ast::crate_cfg, rdr: reader, } } -pub fn parse(sess: parse_sess, +pub fn parse(sess: @mut ParseSess, cfg: ast::crate_cfg, rdr: reader, ms: ~[matcher]) @@ -260,7 +267,7 @@ pub fn parse(sess: parse_sess, if idx == len { // pop from the matcher position - let new_pos = copy_up(ei.up); + let mut new_pos = copy_up(ei.up); // update matches (the MBE "parse tree") by appending // each tree as a subtree. @@ -279,7 +286,7 @@ pub fn parse(sess: parse_sess, } new_pos.idx += 1; - cur_eis.push(move new_pos); + cur_eis.push(new_pos); } // can we go around again? @@ -288,19 +295,19 @@ pub fn parse(sess: parse_sess, match copy ei.sep { Some(ref t) if idx == len => { // we need a separator if tok == (*t) { //pass the separator - let ei_t = move ei; + let mut ei_t = ei; ei_t.idx += 1; - next_eis.push(move ei_t); + next_eis.push(ei_t); } } _ => { // we don't need a separator - let ei_t = move ei; + let mut ei_t = ei; ei_t.idx = 0; - cur_eis.push(move ei_t); + cur_eis.push(ei_t); } } } else { - eof_eis.push(move ei); + eof_eis.push(ei); } } else { match copy ei.elts[idx].node { @@ -308,33 +315,35 @@ pub fn parse(sess: parse_sess, match_seq(ref matchers, ref sep, zero_ok, match_idx_lo, match_idx_hi) => { if zero_ok { - let new_ei = copy ei; + let mut new_ei = copy ei; new_ei.idx += 1u; //we specifically matched zero repeats. for uint::range(match_idx_lo, match_idx_hi) |idx| { new_ei.matches[idx].push(@matched_seq(~[], sp)); } - cur_eis.push(move new_ei); + cur_eis.push(new_ei); } let matches = vec::map(ei.matches, // fresh, same size: |_m| DVec::<@named_match>()); - let ei_t = move ei; - cur_eis.push(~{ - elts: (*matchers), sep: (*sep), mut idx: 0u, - mut up: matcher_pos_up(Some(move ei_t)), - matches: move matches, + let ei_t = ei; + cur_eis.push(~MatcherPos { + elts: (*matchers), + sep: (*sep), + idx: 0u, + up: matcher_pos_up(Some(ei_t)), + matches: matches, match_lo: match_idx_lo, match_hi: match_idx_hi, sp_lo: sp.lo }); } - match_nonterminal(_,_,_) => { bb_eis.push(move ei) } + match_nonterminal(_,_,_) => { bb_eis.push(ei) } match_tok(ref t) => { - let ei_t = move ei; + let mut ei_t = ei; if (*t) == tok { ei_t.idx += 1; - next_eis.push(move ei_t); + next_eis.push(ei_t); } } } @@ -379,7 +388,7 @@ pub fn parse(sess: parse_sess, } else /* bb_eis.len() == 1 */ { let rust_parser = Parser(sess, cfg, rdr.dup()); - let ei = bb_eis.pop(); + let mut ei = bb_eis.pop(); match ei.elts[ei.idx].node { match_nonterminal(_, name, idx) => { ei.matches[idx].push(@matched_nonterminal( @@ -388,7 +397,7 @@ pub fn parse(sess: parse_sess, } _ => fail!() } - cur_eis.push(move ei); + cur_eis.push(ei); for rust_parser.tokens_consumed.times() || { rdr.next_token(); @@ -412,16 +421,16 @@ pub fn parse_nt(p: Parser, name: ~str) -> nonterminal { ~"expr" => token::nt_expr(p.parse_expr()), ~"ty" => token::nt_ty(p.parse_ty(false /* no need to disambiguate*/)), // this could be handled like a token, since it is one - ~"ident" => match copy p.token { + ~"ident" => match *p.token { token::IDENT(sn,b) => { p.bump(); token::nt_ident(sn,b) } _ => p.fatal(~"expected ident, found " - + token::to_str(p.reader.interner(), copy p.token)) + + token::to_str(p.reader.interner(), *p.token)) }, ~"path" => token::nt_path(p.parse_path_with_tps(false)), ~"tt" => { - p.quote_depth += 1u; //but in theory, non-quoted tts might be useful + *p.quote_depth += 1u; //but in theory, non-quoted tts might be useful let res = token::nt_tt(@p.parse_token_tree()); - p.quote_depth -= 1u; + *p.quote_depth -= 1u; res } ~"matchers" => token::nt_matchers(p.parse_matchers()), diff --git a/src/libsyntax/ext/tt/macro_rules.rs b/src/libsyntax/ext/tt/macro_rules.rs index 3e7a84240e40e..f42bb01f7c21d 100644 --- a/src/libsyntax/ext/tt/macro_rules.rs +++ b/src/libsyntax/ext/tt/macro_rules.rs @@ -53,18 +53,19 @@ pub fn add_new_extension(cx: ext_ctxt, sp: span, name: ident, // Parse the macro_rules! invocation (`none` is for no interpolations): - let arg_reader = new_tt_reader(cx.parse_sess().span_diagnostic, + let arg_reader = new_tt_reader(copy cx.parse_sess().span_diagnostic, cx.parse_sess().interner, None, arg); let argument_map = parse_or_else(cx.parse_sess(), cx.cfg(), arg_reader as reader, argument_gram); // Extract the arguments: - let lhses:~[@named_match] = match argument_map.get(&lhs_nm) { - @matched_seq(s, _) => s, - _ => cx.span_bug(sp, ~"wrong-structured lhs") + let lhses = match argument_map.get(&lhs_nm) { + @matched_seq(ref s, _) => /* FIXME (#2543) */ copy *s, + _ => cx.span_bug(sp, ~"wrong-structured lhs") }; - let rhses:~[@named_match] = match argument_map.get(&rhs_nm) { - @matched_seq(s, _) => s, + + let rhses = match argument_map.get(&rhs_nm) { + @matched_seq(ref s, _) => /* FIXME (#2543) */ copy *s, _ => cx.span_bug(sp, ~"wrong-structured rhs") }; diff --git a/src/libsyntax/ext/tt/transcribe.rs b/src/libsyntax/ext/tt/transcribe.rs index aa9036d295e53..a9502ff29020e 100644 --- a/src/libsyntax/ext/tt/transcribe.rs +++ b/src/libsyntax/ext/tt/transcribe.rs @@ -28,7 +28,7 @@ use std::oldmap::HashMap; `~` */ ///an unzipping of `token_tree`s struct TtFrame { - readme: ~[ast::token_tree], + readme: @mut ~[ast::token_tree], idx: uint, dotdotdoted: bool, sep: Option, @@ -59,8 +59,8 @@ pub fn new_tt_reader(sp_diag: span_handler, let r = @mut TtReader { sp_diag: sp_diag, interner: itr, - mut cur: @mut TtFrame { - readme: src, + cur: @mut TtFrame { + readme: @mut src, idx: 0u, dotdotdoted: false, sep: None, @@ -82,7 +82,7 @@ pub fn new_tt_reader(sp_diag: span_handler, pure fn dup_tt_frame(f: @mut TtFrame) -> @mut TtFrame { @mut TtFrame { - readme: f.readme, + readme: @mut (copy *f.readme), idx: f.idx, dotdotdoted: f.dotdotdoted, sep: f.sep, @@ -199,9 +199,9 @@ pub fn tt_next_token(r: @mut TtReader) -> TokenAndSpan { loop { /* because it's easiest, this handles `tt_delim` not starting with a `tt_tok`, even though it won't happen */ match r.cur.readme[r.cur.idx] { - tt_delim(copy tts) => { + tt_delim(tts) => { r.cur = @mut TtFrame { - readme: tts, + readme: @mut copy tts, idx: 0u, dotdotdoted: false, sep: None, @@ -242,7 +242,7 @@ pub fn tt_next_token(r: @mut TtReader) -> TokenAndSpan { r.repeat_len.push(len); r.repeat_idx.push(0u); r.cur = @mut TtFrame { - readme: tts, + readme: @mut copy tts, idx: 0u, dotdotdoted: true, sep: sep, diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs index 8cecbfb12101e..dacb6f60e3764 100644 --- a/src/libsyntax/fold.rs +++ b/src/libsyntax/fold.rs @@ -82,10 +82,10 @@ fn fold_meta_item_(&&mi: @meta_item, fld: ast_fold) -> @meta_item { node: match mi.node { meta_word(ref id) => meta_word((*id)), - meta_list(ref id, mis) => { - let fold_meta_item = |x|fold_meta_item_(x, fld); - meta_list(/* FIXME: (#2543) */ copy (*id), - vec::map(mis, |e| fold_meta_item(*e))) + meta_list(ref id, ref mis) => { + let fold_meta_item = |x| fold_meta_item_(x, fld); + meta_list(/* FIXME: (#2543) */ copy *id, + mis.map(|e| fold_meta_item(*e))) } meta_name_value(ref id, s) => { meta_name_value((*id), /* FIXME (#2543) */ copy s) @@ -213,52 +213,54 @@ fn noop_fold_struct_field(&&sf: @struct_field, fld: ast_fold) } pub fn noop_fold_item_underscore(i: item_, fld: ast_fold) -> item_ { - return match i { - item_const(t, e) => item_const(fld.fold_ty(t), fld.fold_expr(e)), - item_fn(decl, purity, typms, ref body) => { - item_fn(fold_fn_decl(decl, fld), - purity, - fold_ty_params(typms, fld), - fld.fold_block((*body))) - } - item_mod(m) => item_mod(fld.fold_mod(m)), - item_foreign_mod(nm) => item_foreign_mod(fld.fold_foreign_mod(nm)), - item_ty(t, typms) => item_ty(fld.fold_ty(t), - fold_ty_params(typms, fld)), - item_enum(ref enum_definition, typms) => { + match i { + item_const(t, e) => item_const(fld.fold_ty(t), fld.fold_expr(e)), + item_fn(ref decl, purity, ref typms, ref body) => { + item_fn(fold_fn_decl(/* FIXME (#2543) */ copy *decl, fld), + purity, + fold_ty_params(/* FIXME (#2543) */ copy *typms, fld), + fld.fold_block(*body)) + } + item_mod(m) => item_mod(fld.fold_mod(m)), + item_foreign_mod(nm) => item_foreign_mod(fld.fold_foreign_mod(nm)), + item_ty(t, typms) => item_ty(fld.fold_ty(t), + fold_ty_params(typms, fld)), + item_enum(ref enum_definition, ref typms) => { item_enum(ast::enum_def(ast::enum_def_ { variants: enum_definition.variants.map( |x| fld.fold_variant(*x)), common: enum_definition.common.map( |x| fold_struct_def(*x, fld)), - }), fold_ty_params(typms, fld)) - } - item_struct(struct_def, typms) => { - let struct_def = fold_struct_def(struct_def, fld); - item_struct(struct_def, /* FIXME (#2543) */ copy typms) - } - item_impl(tps, ifce, ty, ref methods) => { - item_impl(fold_ty_params(tps, fld), - ifce.map(|p| fold_trait_ref(*p, fld)), - fld.fold_ty(ty), - vec::map(*methods, |x| fld.fold_method(*x))) - } - item_trait(tps, traits, ref methods) => { - let methods = do (*methods).map |method| { - match *method { - required(*) => copy *method, - provided(method) => provided(fld.fold_method(method)) - } - }; - item_trait(fold_ty_params(tps, fld), - vec::map(traits, |p| fold_trait_ref(*p, fld)), - move methods) - } - item_mac(ref m) => { - // FIXME #2888: we might actually want to do something here. - item_mac((*m)) - } - }; + }), fold_ty_params(/* FIXME (#2543) */ copy *typms, fld)) + } + item_struct(ref struct_def, ref typms) => { + let struct_def = fold_struct_def( + /* FIXME (#2543) */ copy *struct_def, + fld); + item_struct(struct_def, /* FIXME (#2543) */ copy *typms) + } + item_impl(ref tps, ifce, ty, ref methods) => { + item_impl(fold_ty_params(/* FIXME (#2543) */ copy *tps, fld), + ifce.map(|p| fold_trait_ref(*p, fld)), + fld.fold_ty(ty), + methods.map(|x| fld.fold_method(*x))) + } + item_trait(ref tps, ref traits, ref methods) => { + let methods = do methods.map |method| { + match *method { + required(*) => copy *method, + provided(method) => provided(fld.fold_method(method)) + } + }; + item_trait(fold_ty_params(/* FIXME (#2543) */ copy *tps, fld), + traits.map(|p| fold_trait_ref(*p, fld)), + methods) + } + item_mac(ref m) => { + // FIXME #2888: we might actually want to do something here. + item_mac((*m)) + } + } } fn fold_struct_def(struct_def: @ast::struct_def, fld: ast_fold) @@ -466,14 +468,14 @@ pub fn noop_fold_expr(e: expr_, fld: ast_fold) -> expr_ { expr_match(fld.fold_expr(expr), vec::map((*arms), |x| fld.fold_arm(*x))) } - expr_fn(proto, decl, ref body, _) => { + expr_fn(proto, ref decl, ref body, _) => { expr_fn(proto, - fold_fn_decl(decl, fld), + fold_fn_decl(/* FIXME (#2543) */ copy *decl, fld), fld.fold_block(*body), @()) } - expr_fn_block(decl, ref body) => { - expr_fn_block(fold_fn_decl(decl, fld), + expr_fn_block(ref decl, ref body) => { + expr_fn_block(fold_fn_decl(/* FIXME (#2543) */ copy *decl, fld), fld.fold_block(*body)) } expr_block(ref blk) => expr_block(fld.fold_block((*blk))), @@ -692,7 +694,7 @@ pub fn default_ast_fold() -> ast_fold_fns { new_span: noop_span}; } -pub impl ast_fold_fns: ast_fold { +pub impl ast_fold for ast_fold_fns { /* naturally, a macro to write these would be nice */ fn fold_crate(c: crate) -> crate { let (n, s) = (self.fold_crate)(c.node, c.span, self as ast_fold); diff --git a/src/libsyntax/parse/attr.rs b/src/libsyntax/parse/attr.rs index e297e33d825c6..c0c97a0b9eb59 100644 --- a/src/libsyntax/parse/attr.rs +++ b/src/libsyntax/parse/attr.rs @@ -18,13 +18,14 @@ use parse::token; use core::either::{Either, Left, Right}; +// a parser that can parse attributes. pub trait parser_attr { fn parse_outer_attributes() -> ~[ast::attribute]; fn parse_attribute(style: ast::attr_style) -> ast::attribute; fn parse_attribute_naked(style: ast::attr_style, lo: BytePos) -> ast::attribute; fn parse_inner_attrs_and_next() -> - {inner: ~[ast::attribute], next: ~[ast::attribute]}; + (~[ast::attribute], ~[ast::attribute]); fn parse_meta_item() -> @ast::meta_item; fn parse_meta_seq() -> ~[@ast::meta_item]; fn parse_optional_meta() -> ~[@ast::meta_item]; @@ -36,7 +37,7 @@ impl parser_attr for Parser { fn parse_outer_attributes() -> ~[ast::attribute] { let mut attrs: ~[ast::attribute] = ~[]; loop { - match copy self.token { + match *self.token { token::POUND => { if self.look_ahead(1u) != token::LBRACKET { break; @@ -81,19 +82,22 @@ impl parser_attr for Parser { // attribute of the next item (since we can't know whether the attribute // is an inner attribute of the containing item or an outer attribute of // the first contained item until we see the semi). + + // you can make the 'next' field an Option, but the result is going to be + // more useful as a vector. fn parse_inner_attrs_and_next() -> - {inner: ~[ast::attribute], next: ~[ast::attribute]} { + (~[ast::attribute], ~[ast::attribute]) { let mut inner_attrs: ~[ast::attribute] = ~[]; let mut next_outer_attrs: ~[ast::attribute] = ~[]; loop { - match copy self.token { + match *self.token { token::POUND => { if self.look_ahead(1u) != token::LBRACKET { // This is an extension break; } let attr = self.parse_attribute(ast::attr_inner); - if self.token == token::SEMI { + if *self.token == token::SEMI { self.bump(); inner_attrs += ~[attr]; } else { @@ -121,28 +125,28 @@ impl parser_attr for Parser { _ => break } } - return {inner: inner_attrs, next: next_outer_attrs}; + (inner_attrs, next_outer_attrs) } fn parse_meta_item() -> @ast::meta_item { let lo = self.span.lo; - let name = *self.id_to_str(self.parse_ident()); - match self.token { - token::EQ => { - self.bump(); - let lit = self.parse_lit(); - let mut hi = self.span.hi; - return @spanned(lo, hi, ast::meta_name_value(name, lit)); - } - token::LPAREN => { - let inner_items = self.parse_meta_seq(); - let mut hi = self.span.hi; - return @spanned(lo, hi, ast::meta_list(name, inner_items)); - } - _ => { - let mut hi = self.span.hi; - return @spanned(lo, hi, ast::meta_word(name)); - } + let name = self.id_to_str(self.parse_ident()); + match *self.token { + token::EQ => { + self.bump(); + let lit = self.parse_lit(); + let mut hi = self.span.hi; + @spanned(lo, hi, ast::meta_name_value(name, lit)) + } + token::LPAREN => { + let inner_items = self.parse_meta_seq(); + let mut hi = self.span.hi; + @spanned(lo, hi, ast::meta_list(name, inner_items)) + } + _ => { + let mut hi = self.span.hi; + @spanned(lo, hi, ast::meta_word(name)) + } } } @@ -153,7 +157,7 @@ impl parser_attr for Parser { } fn parse_optional_meta() -> ~[@ast::meta_item] { - match self.token { + match *self.token { token::LPAREN => return self.parse_meta_seq(), _ => return ~[] } diff --git a/src/libsyntax/parse/comments.rs b/src/libsyntax/parse/comments.rs index 2cadf195778a2..152bd9b0ce417 100644 --- a/src/libsyntax/parse/comments.rs +++ b/src/libsyntax/parse/comments.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. // @@ -15,6 +15,7 @@ use codemap::{BytePos, CharPos, CodeMap, FileMap, Pos}; use diagnostic; use parse::lexer::{is_whitespace, get_str_from, reader}; use parse::lexer::{StringReader, bump, is_eof, nextch, TokenAndSpan}; +use parse::lexer::{is_line_non_doc_comment, is_block_non_doc_comment}; use parse::lexer; use parse::token; use parse; @@ -43,16 +44,20 @@ impl cmp::Eq for cmnt_style { } } -pub type cmnt = {style: cmnt_style, lines: ~[~str], pos: BytePos}; +pub struct cmnt { + style: cmnt_style, + lines: ~[~str], + pos: BytePos +} -pub fn is_doc_comment(s: ~str) -> bool { - s.starts_with(~"///") || +pub fn is_doc_comment(s: &str) -> bool { + (s.starts_with(~"///") && !is_line_non_doc_comment(s)) || s.starts_with(~"//!") || - s.starts_with(~"/**") || + (s.starts_with(~"/**") && !is_block_non_doc_comment(s)) || s.starts_with(~"/*!") } -pub fn doc_comment_style(comment: ~str) -> ast::attr_style { +pub fn doc_comment_style(comment: &str) -> ast::attr_style { assert is_doc_comment(comment); if comment.starts_with(~"//!") || comment.starts_with(~"/*!") { ast::attr_inner @@ -61,7 +66,7 @@ pub fn doc_comment_style(comment: ~str) -> ast::attr_style { } } -pub fn strip_doc_comment_decoration(comment: ~str) -> ~str { +pub fn strip_doc_comment_decoration(comment: &str) -> ~str { /// remove whitespace-only lines from the start/end of lines fn vertical_trim(lines: ~[~str]) -> ~[~str] { @@ -146,7 +151,7 @@ fn consume_non_eol_whitespace(rdr: @mut StringReader) { fn push_blank_line_comment(rdr: @mut StringReader, comments: &mut ~[cmnt]) { debug!(">>> blank-line comment"); let v: ~[~str] = ~[]; - comments.push({style: blank_line, lines: v, pos: rdr.last_pos}); + comments.push(cmnt {style: blank_line, lines: v, pos: rdr.last_pos}); } fn consume_whitespace_counting_blank_lines(rdr: @mut StringReader, @@ -165,7 +170,7 @@ fn read_shebang_comment(rdr: @mut StringReader, code_to_the_left: bool, debug!(">>> shebang comment"); let p = rdr.last_pos; debug!("<<< shebang comment"); - comments.push({ + comments.push(cmnt { style: if code_to_the_left { trailing } else { isolated }, lines: ~[read_one_line_comment(rdr)], pos: p @@ -188,7 +193,7 @@ fn read_line_comments(rdr: @mut StringReader, code_to_the_left: bool, } debug!("<<< line comments"); if !lines.is_empty() { - comments.push({ + comments.push(cmnt { style: if code_to_the_left { trailing } else { isolated }, lines: lines, pos: p @@ -231,54 +236,63 @@ fn read_block_comment(rdr: @mut StringReader, bump(rdr); bump(rdr); + let mut curr_line = ~"/*"; + // doc-comments are not really comments, they are attributes if rdr.curr == '*' || rdr.curr == '!' { while !(rdr.curr == '*' && nextch(rdr) == '/') && !is_eof(rdr) { + str::push_char(&mut curr_line, rdr.curr); bump(rdr); } if !is_eof(rdr) { + curr_line += ~"*/"; bump(rdr); bump(rdr); } - return; - } - - let mut curr_line = ~"/*"; - let mut level: int = 1; - while level > 0 { - debug!("=== block comment level %d", level); - if is_eof(rdr) {(rdr as reader).fatal(~"unterminated block comment");} - if rdr.curr == '\n' { - trim_whitespace_prefix_and_push_line(&mut lines, curr_line, col); - curr_line = ~""; - bump(rdr); - } else { - str::push_char(&mut curr_line, rdr.curr); - if rdr.curr == '/' && nextch(rdr) == '*' { - bump(rdr); + if !is_block_non_doc_comment(curr_line) { return; } + assert !curr_line.contains_char('\n'); + lines.push(curr_line); + } else { + let mut level: int = 1; + while level > 0 { + debug!("=== block comment level %d", level); + if is_eof(rdr) { + (rdr as reader).fatal(~"unterminated block comment"); + } + if rdr.curr == '\n' { + trim_whitespace_prefix_and_push_line(&mut lines, curr_line, + col); + curr_line = ~""; bump(rdr); - curr_line += ~"*"; - level += 1; } else { - if rdr.curr == '*' && nextch(rdr) == '/' { + str::push_char(&mut curr_line, rdr.curr); + if rdr.curr == '/' && nextch(rdr) == '*' { bump(rdr); bump(rdr); - curr_line += ~"/"; - level -= 1; - } else { bump(rdr); } + curr_line += ~"*"; + level += 1; + } else { + if rdr.curr == '*' && nextch(rdr) == '/' { + bump(rdr); + bump(rdr); + curr_line += ~"/"; + level -= 1; + } else { bump(rdr); } + } } } + if str::len(curr_line) != 0 { + trim_whitespace_prefix_and_push_line(&mut lines, curr_line, col); + } } - if str::len(curr_line) != 0 { - trim_whitespace_prefix_and_push_line(&mut lines, curr_line, col); - } + let mut style = if code_to_the_left { trailing } else { isolated }; consume_non_eol_whitespace(rdr); if !is_eof(rdr) && rdr.curr != '\n' && vec::len(lines) == 1u { style = mixed; } debug!("<<< block comment"); - comments.push({style: style, lines: lines, pos: p}); + comments.push(cmnt {style: style, lines: lines, pos: p}); } fn peeking_at_comment(rdr: @mut StringReader) -> bool { @@ -301,12 +315,14 @@ fn consume_comment(rdr: @mut StringReader, debug!("<<< consume comment"); } -pub type lit = {lit: ~str, pos: BytePos}; +pub struct lit { + lit: ~str, + pos: BytePos +} pub fn gather_comments_and_literals(span_diagnostic: diagnostic::span_handler, path: ~str, - srdr: io::Reader) -> - {cmnts: ~[cmnt], lits: ~[lit]} { + srdr: io::Reader) -> (~[cmnt], ~[lit]) { let src = @str::from_bytes(srdr.read_whole_stream()); let itr = parse::token::mk_fake_ident_interner(); let cm = CodeMap::new(); @@ -340,12 +356,13 @@ pub fn gather_comments_and_literals(span_diagnostic: diagnostic::span_handler, let TokenAndSpan {tok: tok, sp: sp} = rdr.peek(); if token::is_lit(tok) { let s = get_str_from(rdr, bstart); - literals.push({lit: s, pos: sp.lo}); + literals.push(lit {lit: s, pos: sp.lo}); log(debug, ~"tok lit: " + s); } else { log(debug, ~"tok: " + token::to_str(rdr.interner, tok)); } first_read = false; } - return {cmnts: comments, lits: literals}; + + (comments, literals) } diff --git a/src/libsyntax/parse/common.rs b/src/libsyntax/parse/common.rs index e7b5005d8dbf4..57d62d628dc6f 100644 --- a/src/libsyntax/parse/common.rs +++ b/src/libsyntax/parse/common.rs @@ -20,21 +20,30 @@ use core::option::{None, Option, Some}; use core::option; use std::oldmap::HashMap; -// seq_sep : a sequence separator (token) +// SeqSep : a sequence separator (token) // and whether a trailing separator is allowed. -pub type seq_sep = { +pub struct SeqSep { sep: Option, trailing_sep_allowed: bool -}; +} -pub fn seq_sep_trailing_disallowed(t: token::Token) -> seq_sep { - return {sep: option::Some(t), trailing_sep_allowed: false}; +pub fn seq_sep_trailing_disallowed(t: token::Token) -> SeqSep { + SeqSep { + sep: option::Some(t), + trailing_sep_allowed: false + } } -pub fn seq_sep_trailing_allowed(t: token::Token) -> seq_sep { - return {sep: option::Some(t), trailing_sep_allowed: true}; +pub fn seq_sep_trailing_allowed(t: token::Token) -> SeqSep { + SeqSep { + sep: option::Some(t), + trailing_sep_allowed: true + } } -pub fn seq_sep_none() -> seq_sep { - return {sep: option::None, trailing_sep_allowed: false}; +pub fn seq_sep_none() -> SeqSep { + SeqSep { + sep: option::None, + trailing_sep_allowed: false + } } pub fn token_to_str(reader: reader, ++token: token::Token) -> ~str { @@ -44,25 +53,25 @@ pub fn token_to_str(reader: reader, ++token: token::Token) -> ~str { pub impl Parser { fn unexpected_last(t: token::Token) -> ! { self.span_fatal( - copy self.last_span, + *self.last_span, ~"unexpected token: `" + token_to_str(self.reader, t) + ~"`"); } fn unexpected() -> ! { self.fatal(~"unexpected token: `" - + token_to_str(self.reader, self.token) + ~"`"); + + token_to_str(self.reader, *self.token) + ~"`"); } // expect and consume the token t. Signal an error if // the next token is not t. fn expect(t: token::Token) { - if self.token == t { + if *self.token == t { self.bump(); } else { let mut s: ~str = ~"expected `"; s += token_to_str(self.reader, t); s += ~"` but found `"; - s += token_to_str(self.reader, self.token); + s += token_to_str(self.reader, *self.token); self.fatal(s + ~"`"); } } @@ -70,12 +79,12 @@ pub impl Parser { fn parse_ident() -> ast::ident { self.check_strict_keywords(); self.check_reserved_keywords(); - match copy self.token { + match *self.token { token::IDENT(i, _) => { self.bump(); return i; } token::INTERPOLATED(token::nt_ident(*)) => { self.bug( ~"ident interpolation not converted to real token"); } _ => { self.fatal(~"expected ident, found `" - + token_to_str(self.reader, self.token) + + token_to_str(self.reader, *self.token) + ~"`"); } } } @@ -95,7 +104,7 @@ pub impl Parser { // consume token 'tok' if it exists. Returns true if the given // token was present, false otherwise. fn eat(tok: token::Token) -> bool { - return if self.token == tok { self.bump(); true } else { false }; + return if *self.token == tok { self.bump(); true } else { false }; } // Storing keywords as interned idents instead of strings would be nifty. @@ -120,7 +129,7 @@ pub impl Parser { } fn is_keyword(word: ~str) -> bool { - self.token_is_keyword(word, self.token) + self.token_is_keyword(word, *self.token) } fn is_any_keyword(tok: token::Token) -> bool { @@ -134,7 +143,7 @@ pub impl Parser { fn eat_keyword(word: ~str) -> bool { self.require_keyword(word); - let is_kw = match self.token { + let is_kw = match *self.token { token::IDENT(sid, false) => (word == *self.id_to_str(sid)), _ => false }; @@ -146,7 +155,7 @@ pub impl Parser { self.require_keyword(word); if !self.eat_keyword(word) { self.fatal(~"expected `" + word + ~"`, found `" + - token_to_str(self.reader, self.token) + + token_to_str(self.reader, *self.token) + ~"`"); } } @@ -156,9 +165,9 @@ pub impl Parser { } fn check_strict_keywords() { - match self.token { + match *self.token { token::IDENT(_, false) => { - let w = token_to_str(self.reader, self.token); + let w = token_to_str(self.reader, *self.token); self.check_strict_keywords_(w); } _ => () @@ -176,9 +185,9 @@ pub impl Parser { } fn check_reserved_keywords() { - match self.token { + match *self.token { token::IDENT(_, false) => { - let w = token_to_str(self.reader, self.token); + let w = token_to_str(self.reader, *self.token); self.check_reserved_keywords_(w); } _ => () @@ -194,9 +203,9 @@ pub impl Parser { // expect and consume a GT. if a >> is seen, replace it // with a single > and continue. fn expect_gt() { - if self.token == token::GT { + if *self.token == token::GT { self.bump(); - } else if self.token == token::BINOP(token::SHR) { + } else if *self.token == token::BINOP(token::SHR) { self.replace_token(token::GT, self.span.lo + BytePos(1u), self.span.hi); @@ -204,7 +213,7 @@ pub impl Parser { let mut s: ~str = ~"expected `"; s += token_to_str(self.reader, token::GT); s += ~"`, found `"; - s += token_to_str(self.reader, self.token); + s += token_to_str(self.reader, *self.token); s += ~"`"; self.fatal(s); } @@ -212,12 +221,12 @@ pub impl Parser { // parse a sequence bracketed by '<' and '>', stopping // before the '>'. - fn parse_seq_to_before_gt(sep: Option, + fn parse_seq_to_before_gt(sep: Option, f: fn(Parser) -> T) -> ~[T] { let mut first = true; let mut v = ~[]; - while self.token != token::GT - && self.token != token::BINOP(token::SHR) { + while *self.token != token::GT + && *self.token != token::BINOP(token::SHR) { match sep { Some(ref t) => { if first { first = false; } @@ -231,7 +240,7 @@ pub impl Parser { return v; } - fn parse_seq_to_gt(sep: Option, + fn parse_seq_to_gt(sep: Option, f: fn(Parser) -> T) -> ~[T] { let v = self.parse_seq_to_before_gt(sep, f); self.expect_gt(); @@ -240,7 +249,7 @@ pub impl Parser { } // parse a sequence bracketed by '<' and '>' - fn parse_seq_lt_gt(sep: Option, + fn parse_seq_lt_gt(sep: Option, f: fn(Parser) -> T) -> spanned<~[T]> { let lo = self.span.lo; self.expect(token::LT); @@ -253,7 +262,7 @@ pub impl Parser { // parse a sequence, including the closing delimiter. The function // f must consume tokens until reaching the next separator or // closing bracket. - fn parse_seq_to_end(ket: token::Token, sep: seq_sep, + fn parse_seq_to_end(ket: token::Token, sep: SeqSep, f: fn(Parser) -> T) -> ~[T] { let val = self.parse_seq_to_before_end(ket, sep, f); self.bump(); @@ -263,11 +272,11 @@ pub impl Parser { // parse a sequence, not including the closing delimiter. The function // f must consume tokens until reaching the next separator or // closing bracket. - fn parse_seq_to_before_end(ket: token::Token, sep: seq_sep, + fn parse_seq_to_before_end(ket: token::Token, sep: SeqSep, f: fn(Parser) -> T) -> ~[T] { let mut first: bool = true; let mut v: ~[T] = ~[]; - while self.token != ket { + while *self.token != ket { match sep.sep { Some(ref t) => { if first { first = false; } @@ -275,7 +284,7 @@ pub impl Parser { } _ => () } - if sep.trailing_sep_allowed && self.token == ket { break; } + if sep.trailing_sep_allowed && *self.token == ket { break; } v.push(f(self)); } return v; @@ -284,9 +293,9 @@ pub impl Parser { // parse a sequence, including the closing delimiter. The function // f must consume tokens until reaching the next separator or // closing bracket. - fn parse_unspanned_seq(bra: token::Token, - ket: token::Token, - sep: seq_sep, + fn parse_unspanned_seq(+bra: token::Token, + +ket: token::Token, + sep: SeqSep, f: fn(Parser) -> T) -> ~[T] { self.expect(bra); let result = self.parse_seq_to_before_end::(ket, sep, f); @@ -296,7 +305,7 @@ pub impl Parser { // NB: Do not use this function unless you actually plan to place the // spanned list in the AST. - fn parse_seq(bra: token::Token, ket: token::Token, sep: seq_sep, + fn parse_seq(bra: token::Token, ket: token::Token, sep: SeqSep, f: fn(Parser) -> T) -> spanned<~[T]> { let lo = self.span.lo; self.expect(bra); diff --git a/src/libsyntax/parse/eval.rs b/src/libsyntax/parse/eval.rs index 5decb2351e389..5d44db084d600 100644 --- a/src/libsyntax/parse/eval.rs +++ b/src/libsyntax/parse/eval.rs @@ -75,9 +75,9 @@ fn parse_companion_mod(cx: ctx, prefix: &Path, suffix: &Option) let p0 = new_sub_parser_from_file(cx.sess, cx.cfg, modpath, codemap::dummy_sp()); - let inner_attrs = p0.parse_inner_attrs_and_next(); - let m0 = p0.parse_mod_items(token::EOF, inner_attrs.next); - return (m0.view_items, m0.items, inner_attrs.inner); + let (inner, next) = p0.parse_inner_attrs_and_next(); + let m0 = p0.parse_mod_items(token::EOF, next); + return (m0.view_items, m0.items, inner); } else { return (~[], ~[], ~[]); } @@ -111,9 +111,9 @@ pub fn eval_src_mod_from_path(cx: ctx, prefix: &Path, path: &Path, let p0 = new_sub_parser_from_file(cx.sess, cx.cfg, &full_path, sp); - let inner_attrs = p0.parse_inner_attrs_and_next(); - let mod_attrs = vec::append(outer_attrs, inner_attrs.inner); - let first_item_outer_attrs = inner_attrs.next; + let (inner, next) = p0.parse_inner_attrs_and_next(); + let mod_attrs = vec::append(outer_attrs, inner); + let first_item_outer_attrs = next; let m0 = p0.parse_mod_items(token::EOF, first_item_outer_attrs); return (ast::item_mod(m0), mod_attrs); } diff --git a/src/libsyntax/parse/lexer.rs b/src/libsyntax/parse/lexer.rs index f5fbefdd89b4b..92c4f1e828f62 100644 --- a/src/libsyntax/parse/lexer.rs +++ b/src/libsyntax/parse/lexer.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. // @@ -127,7 +127,7 @@ impl reader for StringReader { fn dup(@mut self) -> reader { dup_string_reader(self) as reader } } -pub impl TtReader: reader { +pub impl reader for TtReader { fn is_eof(@mut self) -> bool { self.cur_tok == token::EOF } fn next_token(@mut self) -> TokenAndSpan { tt_next_token(self) } fn fatal(@mut self, m: ~str) -> ! { @@ -253,6 +253,10 @@ 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 { + s.trim_right().all(|ch| ch == '/') +} + // PRECONDITION: rdr.curr is not whitespace // EFFECT: eats any kind of comment. // returns a Some(sugared-doc-attr) if one exists, None otherwise @@ -271,15 +275,18 @@ fn consume_any_line_comment(rdr: @mut StringReader) str::push_char(&mut acc, rdr.curr); bump(rdr); } - return Some(TokenAndSpan{ - tok: token::DOC_COMMENT(rdr.interner.intern(@acc)), - sp: codemap::mk_sp(start_bpos, rdr.pos) - }); + // but comments with only "/"s are not + if !is_line_non_doc_comment(acc) { + return Some(TokenAndSpan{ + tok: token::DOC_COMMENT(rdr.interner.intern(@acc)), + sp: codemap::mk_sp(start_bpos, rdr.pos) + }); + } } else { while rdr.curr != '\n' && !is_eof(rdr) { bump(rdr); } - // Restart whitespace munch. - return consume_whitespace_and_comments(rdr); } + // Restart whitespace munch. + return consume_whitespace_and_comments(rdr); } '*' => { bump(rdr); bump(rdr); return consume_block_comment(rdr); } _ => () @@ -298,6 +305,11 @@ fn consume_any_line_comment(rdr: @mut StringReader) return None; } +pub pure fn is_block_non_doc_comment(s: &str) -> bool { + assert s.len() >= 1u; + str::all_between(s, 1u, s.len() - 1u, |ch| ch == '*') +} + // might return a sugared-doc-attr fn consume_block_comment(rdr: @mut StringReader) -> Option { @@ -315,10 +327,13 @@ fn consume_block_comment(rdr: @mut StringReader) acc += ~"*/"; bump(rdr); bump(rdr); - return Some(TokenAndSpan{ - tok: token::DOC_COMMENT(rdr.interner.intern(@acc)), - sp: codemap::mk_sp(start_bpos, rdr.pos) - }); + // but comments with only "*"s between two "/"s are not + if !is_block_non_doc_comment(acc) { + return Some(TokenAndSpan{ + tok: token::DOC_COMMENT(rdr.interner.intern(@acc)), + sp: codemap::mk_sp(start_bpos, rdr.pos) + }); + } } } else { loop { diff --git a/src/libsyntax/parse/mod.rs b/src/libsyntax/parse/mod.rs index 12038898a9d1c..5fa6115938506 100644 --- a/src/libsyntax/parse/mod.rs +++ b/src/libsyntax/parse/mod.rs @@ -47,42 +47,51 @@ pub mod classify; /// Reporting obsolete syntax pub mod obsolete; -pub type parse_sess = @{ +pub struct ParseSess { cm: @codemap::CodeMap, - mut next_id: node_id, + next_id: node_id, span_diagnostic: span_handler, interner: @ident_interner, -}; +} -pub fn new_parse_sess(demitter: Option) -> parse_sess { +pub fn new_parse_sess(demitter: Option) -> @mut ParseSess { let cm = @CodeMap::new(); - return @{cm: cm, - mut next_id: 1, - span_diagnostic: mk_span_handler(mk_handler(demitter), cm), - interner: mk_ident_interner(), - }; + @mut ParseSess { + cm: cm, + next_id: 1, + span_diagnostic: mk_span_handler(mk_handler(demitter), cm), + interner: mk_ident_interner(), + } } pub fn new_parse_sess_special_handler(sh: span_handler, cm: @codemap::CodeMap) - -> parse_sess { - return @{cm: cm, - mut next_id: 1, - span_diagnostic: sh, - interner: mk_ident_interner(), - }; + -> @mut ParseSess { + @mut ParseSess { + cm: cm, + next_id: 1, + span_diagnostic: sh, + interner: mk_ident_interner(), + } } +// a bunch of utility functions of the form parse__from_ +// where includes crate, expr, item, stmt, tts, and one that +// uses a HOF to parse anything, and includes file and +// source_str. + +// this appears to be the main entry point for rust parsing by +// rustc and crate: pub fn parse_crate_from_file(input: &Path, cfg: ast::crate_cfg, - sess: parse_sess) -> @ast::crate { - let p = new_crate_parser_from_file(sess, cfg, input); - let r = p.parse_crate_mod(cfg); - return r; + sess: @mut ParseSess) -> @ast::crate { + let p = new_parser_from_file(sess, cfg, input); + p.parse_crate_mod(cfg) + // why is there no p.abort_if_errors here? } pub fn parse_crate_from_source_str(name: ~str, source: @~str, cfg: ast::crate_cfg, - sess: parse_sess) -> @ast::crate { + sess: @mut ParseSess) -> @ast::crate { let p = new_parser_from_source_str(sess, cfg, name, codemap::FssNone, source); let r = p.parse_crate_mod(cfg); @@ -93,7 +102,7 @@ pub fn parse_crate_from_source_str(name: ~str, pub fn parse_expr_from_source_str(name: ~str, source: @~str, cfg: ast::crate_cfg, - sess: parse_sess) -> @ast::expr { + sess: @mut ParseSess) -> @ast::expr { let p = new_parser_from_source_str(sess, cfg, name, codemap::FssNone, source); let r = p.parse_expr(); @@ -105,7 +114,7 @@ pub fn parse_item_from_source_str(name: ~str, source: @~str, cfg: ast::crate_cfg, +attrs: ~[ast::attribute], - sess: parse_sess) + sess: @mut ParseSess) -> Option<@ast::item> { let p = new_parser_from_source_str(sess, cfg, name, codemap::FssNone, source); @@ -118,7 +127,7 @@ pub fn parse_stmt_from_source_str(name: ~str, source: @~str, cfg: ast::crate_cfg, +attrs: ~[ast::attribute], - sess: parse_sess) -> @ast::stmt { + sess: @mut ParseSess) -> @ast::stmt { let p = new_parser_from_source_str(sess, cfg, name, codemap::FssNone, source); let r = p.parse_stmt(attrs); @@ -129,10 +138,10 @@ pub fn parse_stmt_from_source_str(name: ~str, pub fn parse_tts_from_source_str(name: ~str, source: @~str, cfg: ast::crate_cfg, - sess: parse_sess) -> ~[ast::token_tree] { + sess: @mut ParseSess) -> ~[ast::token_tree] { let p = new_parser_from_source_str(sess, cfg, name, codemap::FssNone, source); - p.quote_depth += 1u; + *p.quote_depth += 1u; let r = p.parse_all_token_trees(); p.abort_if_errors(); return r; @@ -141,7 +150,7 @@ pub fn parse_tts_from_source_str(name: ~str, pub fn parse_from_source_str(f: fn (p: Parser) -> T, name: ~str, ss: codemap::FileSubstr, source: @~str, cfg: ast::crate_cfg, - sess: parse_sess) + sess: @mut ParseSess) -> T { let p = new_parser_from_source_str(sess, cfg, name, ss, @@ -151,10 +160,10 @@ pub fn parse_from_source_str(f: fn (p: Parser) -> T, p.reader.fatal(~"expected end-of-string"); } p.abort_if_errors(); - move r + r } -pub fn next_node_id(sess: parse_sess) -> node_id { +pub fn next_node_id(sess: @mut ParseSess) -> node_id { let rv = sess.next_id; sess.next_id += 1; // ID 0 is reserved for the crate and doesn't actually exist in the AST @@ -162,41 +171,43 @@ pub fn next_node_id(sess: parse_sess) -> node_id { return rv; } -pub fn new_parser_from_source_str(sess: parse_sess, cfg: ast::crate_cfg, +pub fn new_parser_from_source_str(sess: @mut ParseSess, cfg: ast::crate_cfg, +name: ~str, +ss: codemap::FileSubstr, source: @~str) -> Parser { let filemap = sess.cm.new_filemap_w_substr(name, ss, source); - let srdr = lexer::new_string_reader(sess.span_diagnostic, + let srdr = lexer::new_string_reader(copy sess.span_diagnostic, filemap, sess.interner); return Parser(sess, cfg, srdr as reader); } -pub fn new_parser_from_file(sess: parse_sess, +// Read the entire source file, return a parser +// that draws from that string +pub fn new_parser_result_from_file(sess: @mut ParseSess, cfg: ast::crate_cfg, path: &Path) -> Result { match io::read_whole_file_str(path) { - result::Ok(move src) => { + result::Ok(src) => { - let filemap = sess.cm.new_filemap(path.to_str(), @move src); - let srdr = lexer::new_string_reader(sess.span_diagnostic, + let filemap = sess.cm.new_filemap(path.to_str(), @src); + let srdr = lexer::new_string_reader(copy sess.span_diagnostic, filemap, sess.interner); Ok(Parser(sess, cfg, srdr as reader)) } - result::Err(move e) => Err(move e) + result::Err(e) => Err(e) } } /// Create a new parser for an entire crate, handling errors as appropriate /// if the file doesn't exist -pub fn new_crate_parser_from_file(sess: parse_sess, cfg: ast::crate_cfg, +pub fn new_parser_from_file(sess: @mut ParseSess, cfg: ast::crate_cfg, path: &Path) -> Parser { - match new_parser_from_file(sess, cfg, path) { - Ok(move parser) => move parser, - Err(move e) => { + match new_parser_result_from_file(sess, cfg, path) { + Ok(parser) => parser, + Err(e) => { sess.span_diagnostic.handler().fatal(e) } } @@ -204,19 +215,19 @@ pub fn new_crate_parser_from_file(sess: parse_sess, cfg: ast::crate_cfg, /// Create a new parser based on a span from an existing parser. Handles /// error messages correctly when the file does not exist. -pub fn new_sub_parser_from_file(sess: parse_sess, cfg: ast::crate_cfg, +pub fn new_sub_parser_from_file(sess: @mut ParseSess, cfg: ast::crate_cfg, path: &Path, sp: span) -> Parser { - match new_parser_from_file(sess, cfg, path) { - Ok(move parser) => move parser, - Err(move e) => { + match new_parser_result_from_file(sess, cfg, path) { + Ok(parser) => parser, + Err(e) => { sess.span_diagnostic.span_fatal(sp, e) } } } -pub fn new_parser_from_tts(sess: parse_sess, cfg: ast::crate_cfg, +pub fn new_parser_from_tts(sess: @mut ParseSess, cfg: ast::crate_cfg, tts: ~[ast::token_tree]) -> Parser { - let trdr = lexer::new_tt_reader(sess.span_diagnostic, sess.interner, + let trdr = lexer::new_tt_reader(copy sess.span_diagnostic, sess.interner, None, tts); return Parser(sess, cfg, trdr as reader) } @@ -227,12 +238,11 @@ mod test { use super::*; use std::serialize::Encodable; use std; - use core::dvec; use core::str; use util::testing::*; #[test] fn to_json_str (val: Encodable) -> ~str { - let bw = @io::BytesWriter {bytes: dvec::DVec(), pos: 0}; + let bw = @io::BytesWriter(); val.encode(~std::json::Encoder(bw as io::Writer)); str::from_bytes(bw.bytes.data) } diff --git a/src/libsyntax/parse/obsolete.rs b/src/libsyntax/parse/obsolete.rs index 1b4493b7ec9af..1ae8786e09bb2 100644 --- a/src/libsyntax/parse/obsolete.rs +++ b/src/libsyntax/parse/obsolete.rs @@ -45,10 +45,12 @@ pub enum ObsoleteSyntax { ObsoleteMoveInit, ObsoleteBinaryMove, ObsoleteUnsafeBlock, - ObsoleteUnenforcedBound + ObsoleteUnenforcedBound, + ObsoleteImplSyntax, + ObsoleteTraitBoundSeparator, } -pub impl ObsoleteSyntax: to_bytes::IterBytes { +pub impl to_bytes::IterBytes for ObsoleteSyntax { #[inline(always)] pure fn iter_bytes(&self, +lsb0: bool, f: to_bytes::Cb) { (*self as uint).iter_bytes(lsb0, f); @@ -115,7 +117,15 @@ pub impl Parser { "unenforced type parameter bound", "use trait bounds on the functions that take the type as \ arguments, not on the types themselves" - ) + ), + ObsoleteImplSyntax => ( + "colon-separated impl syntax", + "write `impl Trait for Type`" + ), + ObsoleteTraitBoundSeparator => ( + "space-separated trait bounds", + "write `+` between trait bounds" + ), }; self.report(sp, kind, kind_str, desc); @@ -148,7 +158,7 @@ pub impl Parser { } fn is_obsolete_ident(ident: &str) -> bool { - self.token_is_obsolete_ident(ident, copy self.token) + self.token_is_obsolete_ident(ident, *self.token) } fn eat_obsolete_ident(ident: &str) -> bool { @@ -162,7 +172,7 @@ pub impl Parser { fn try_parse_obsolete_struct_ctor() -> bool { if self.eat_obsolete_ident("new") { - self.obsolete(copy self.last_span, ObsoleteStructCtor); + self.obsolete(*self.last_span, ObsoleteStructCtor); self.parse_fn_decl(|p| p.parse_arg()); self.parse_block(); true @@ -172,13 +182,13 @@ pub impl Parser { } fn try_parse_obsolete_with() -> bool { - if self.token == token::COMMA + if *self.token == token::COMMA && self.token_is_obsolete_ident("with", self.look_ahead(1u)) { self.bump(); } if self.eat_obsolete_ident("with") { - self.obsolete(copy self.last_span, ObsoleteWith); + self.obsolete(*self.last_span, ObsoleteWith); self.parse_expr(); true } else { @@ -188,10 +198,10 @@ pub impl Parser { fn try_parse_obsolete_priv_section() -> bool { if self.is_keyword(~"priv") && self.look_ahead(1) == token::LBRACE { - self.obsolete(copy self.span, ObsoletePrivSection); + self.obsolete(*self.span, ObsoletePrivSection); self.eat_keyword(~"priv"); self.bump(); - while self.token != token::RBRACE { + while *self.token != token::RBRACE { self.parse_single_class_item(ast::private); } self.bump(); diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 41ccf39e2cee1..9bac163dab6ef 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -54,7 +54,7 @@ use ast::{ty_infer, ty_mac, ty_method}; use ast::{ty_nil, ty_param, ty_param_bound, ty_path, ty_ptr, ty_rec, ty_rptr}; use ast::{ty_tup, ty_u32, ty_uniq, ty_vec, type_value_ns, uniq}; use ast::{unnamed_field, unsafe_blk, unsafe_fn, variant, view_item}; -use ast::{view_item_, view_item_import, view_item_use}; +use ast::{view_item_, view_item_extern_mod, view_item_use}; use ast::{view_path, view_path_glob, view_path_list, view_path_simple}; use ast::{visibility, vstore, vstore_box, vstore_fixed, vstore_slice}; use ast::{vstore_uniq}; @@ -74,18 +74,17 @@ use parse::obsolete::{ObsoleteLet, ObsoleteFieldTerminator}; use parse::obsolete::{ObsoleteMoveInit, ObsoleteBinaryMove}; use parse::obsolete::{ObsoleteStructCtor, ObsoleteWith}; use parse::obsolete::{ObsoleteSyntax, ObsoleteLowerCaseKindBounds}; -use parse::obsolete::{ObsoleteUnsafeBlock}; +use parse::obsolete::{ObsoleteUnsafeBlock, ObsoleteImplSyntax}; +use parse::obsolete::{ObsoleteTraitBoundSeparator}; 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}; use parse::token; -use parse::{new_sub_parser_from_file, next_node_id, parse_sess}; +use parse::{new_sub_parser_from_file, next_node_id, ParseSess}; use print::pprust::expr_to_str; use util::interner::Interner; use core::cmp; -use core::dvec::DVec; -use core::dvec; use core::either::{Either, Left, Right}; use core::either; use core::result::Result; @@ -111,6 +110,7 @@ type arg_or_capture_item = Either; type item_info = (ident, item_, Option<~[attribute]>); pub enum item_or_view_item { + // indicates a failure to parse any kind of item: iovi_none, iovi_item(@item), iovi_foreign_item(@foreign_item), @@ -127,7 +127,7 @@ enum view_item_parse_mode { The important thing is to make sure that lookahead doesn't balk at INTERPOLATED tokens */ macro_rules! maybe_whole_expr ( - ($p:expr) => ( match copy $p.token { + ($p:expr) => ( match *$p.token { INTERPOLATED(token::nt_expr(e)) => { $p.bump(); return e; @@ -142,28 +142,28 @@ macro_rules! maybe_whole_expr ( ) macro_rules! maybe_whole ( - ($p:expr, $constructor:ident) => ( match copy $p.token { - INTERPOLATED(token::$constructor(ref x)) => { $p.bump(); return (*x); } + ($p:expr, $constructor:ident) => ( match *$p.token { + INTERPOLATED(token::$constructor(x)) => { $p.bump(); return x; } _ => () }) ; - (deref $p:expr, $constructor:ident) => ( match copy $p.token { + (deref $p:expr, $constructor:ident) => ( match *$p.token { INTERPOLATED(token::$constructor(x)) => { $p.bump(); return *x; } _ => () }) ; - (Some $p:expr, $constructor:ident) => ( match copy $p.token { + (Some $p:expr, $constructor:ident) => ( match *$p.token { INTERPOLATED(token::$constructor(x)) => { $p.bump(); return Some(x); } _ => () }) ; - (iovi $p:expr, $constructor:ident) => ( match copy $p.token { + (iovi $p:expr, $constructor:ident) => ( match *$p.token { INTERPOLATED(token::$constructor(x)) => { $p.bump(); return iovi_item(x); } _ => () }) ; - (pair_empty $p:expr, $constructor:ident) => ( match copy $p.token { - INTERPOLATED(token::$constructor(ref x)) => { - $p.bump(); return (~[], (*x)); + (pair_empty $p:expr, $constructor:ident) => ( match *$p.token { + INTERPOLATED(token::$constructor(x)) => { + $p.bump(); return (~[], x); } _ => () }) @@ -180,10 +180,16 @@ pure fn maybe_append(+lhs: ~[attribute], rhs: Option<~[attribute]>) } +struct ParsedItemsAndViewItems { + attrs_remaining: ~[attribute], + view_items: ~[@view_item], + items: ~[@item], + foreign_items: ~[@foreign_item] +} + /* ident is handled by common.rs */ -pub fn Parser(sess: parse_sess - , +pub fn Parser(sess: @mut ParseSess, cfg: ast::crate_cfg, +rdr: reader) -> Parser { @@ -192,39 +198,39 @@ pub fn Parser(sess: parse_sess let interner = rdr.interner(); Parser { - reader: move rdr, - interner: move interner, + reader: rdr, + interner: interner, sess: sess, cfg: cfg, - token: tok0.tok, - span: span0, - last_span: span0, - mut buffer: [TokenAndSpan {tok: tok0.tok, sp: span0}, ..4], - buffer_start: 0, - buffer_end: 0, - tokens_consumed: 0u, - restriction: UNRESTRICTED, - quote_depth: 0u, + token: @mut tok0.tok, + span: @mut span0, + last_span: @mut span0, + buffer: @mut [TokenAndSpan {tok: tok0.tok, sp: span0}, ..4], + buffer_start: @mut 0, + buffer_end: @mut 0, + tokens_consumed: @mut 0u, + restriction: @mut UNRESTRICTED, + quote_depth: @mut 0u, keywords: token::keyword_table(), strict_keywords: token::strict_keyword_table(), reserved_keywords: token::reserved_keyword_table(), obsolete_set: HashMap(), - mod_path_stack: ~[], + mod_path_stack: @mut ~[], } } pub struct Parser { - sess: parse_sess, + sess: @mut ParseSess, cfg: crate_cfg, - mut token: token::Token, - mut span: span, - mut last_span: span, - mut buffer: [TokenAndSpan * 4], - mut buffer_start: int, - mut buffer_end: int, - mut tokens_consumed: uint, - mut restriction: restriction, - mut quote_depth: uint, // not (yet) related to the quasiquoter + token: @mut token::Token, + span: @mut span, + last_span: @mut span, + buffer: @mut [TokenAndSpan * 4], + buffer_start: @mut int, + buffer_end: @mut int, + tokens_consumed: @mut uint, + restriction: @mut restriction, + quote_depth: @mut uint, // not (yet) related to the quasiquoter reader: reader, interner: @token::ident_interner, keywords: HashMap<~str, ()>, @@ -234,7 +240,7 @@ pub struct Parser { /// extra detail when the same error is seen twice obsolete_set: HashMap, /// Used to determine the path to externally loaded source files - mut mod_path_stack: ~[~str], + mod_path_stack: @mut ~[~str], drop {} /* do not copy the parser; its state is tied to outside state */ } @@ -242,39 +248,39 @@ pub struct Parser { pub impl Parser { // advance the parser by one token fn bump() { - self.last_span = self.span; - let next = if self.buffer_start == self.buffer_end { + *self.last_span = *self.span; + let next = if *self.buffer_start == *self.buffer_end { self.reader.next_token() } else { - let next = self.buffer[self.buffer_start]; - self.buffer_start = (self.buffer_start + 1) & 3; + let next = self.buffer[*self.buffer_start]; + *self.buffer_start = (*self.buffer_start + 1) & 3; next }; - self.token = next.tok; - self.span = next.sp; - self.tokens_consumed += 1u; + *self.token = next.tok; + *self.span = next.sp; + *self.tokens_consumed += 1u; } // EFFECT: replace the current token and span with the given one fn replace_token(next: token::Token, +lo: BytePos, +hi: BytePos) { - self.token = next; - self.span = mk_sp(lo, hi); + *self.token = next; + *self.span = mk_sp(lo, hi); } fn buffer_length() -> int { - if self.buffer_start <= self.buffer_end { - return self.buffer_end - self.buffer_start; + if *self.buffer_start <= *self.buffer_end { + return *self.buffer_end - *self.buffer_start; } - return (4 - self.buffer_start) + self.buffer_end; + return (4 - *self.buffer_start) + *self.buffer_end; } fn look_ahead(distance: uint) -> token::Token { let dist = distance as int; while self.buffer_length() < dist { - self.buffer[self.buffer_end] = self.reader.next_token(); - self.buffer_end = (self.buffer_end + 1) & 3; + self.buffer[*self.buffer_end] = self.reader.next_token(); + *self.buffer_end = (*self.buffer_end + 1) & 3; } - return copy self.buffer[(self.buffer_start + dist - 1) & 3].tok; + return copy self.buffer[(*self.buffer_start + dist - 1) & 3].tok; } fn fatal(m: ~str) -> ! { - self.sess.span_diagnostic.span_fatal(copy self.span, m) + self.sess.span_diagnostic.span_fatal(*copy self.span, m) } fn span_fatal(sp: span, m: ~str) -> ! { self.sess.span_diagnostic.span_fatal(sp, m) @@ -283,10 +289,10 @@ pub impl Parser { self.sess.span_diagnostic.span_note(sp, m) } fn bug(m: ~str) -> ! { - self.sess.span_diagnostic.span_bug(copy self.span, m) + self.sess.span_diagnostic.span_bug(*copy self.span, m) } fn warn(m: ~str) { - self.sess.span_diagnostic.span_warn(copy self.span, m) + self.sess.span_diagnostic.span_warn(*copy self.span, m) } fn span_err(sp: span, m: ~str) { self.sess.span_diagnostic.span_err(sp, m) @@ -309,12 +315,12 @@ pub impl Parser { { /* - extern "ABI" [pure|unsafe] fn (S) -> T - ^~~~^ ^~~~~~~~~~~~^ ^~^ ^ - | | | | - | | | Return type - | | Argument types - | | + extern "ABI" [pure|unsafe] fn <'lt> (S) -> T + ^~~~^ ^~~~~~~~~~~~^ ^~~~^ ^~^ ^ + | | | | | + | | | | Return type + | | | Argument types + | | Lifetimes | | | Purity ABI @@ -335,12 +341,12 @@ pub impl Parser { { /* - (&|~|@) [r/] [pure|unsafe] [once] fn (S) -> T - ^~~~~~^ ^~~^ ^~~~~~~~~~~~^ ^~~~~^ ^~^ ^ - | | | | | | - | | | | | Return type - | | | | Argument types - | | | | + (&|~|@) [r/] [pure|unsafe] [once] fn <'lt> (S) -> T + ^~~~~~^ ^~~^ ^~~~~~~~~~~~^ ^~~~~^ ^~~~^ ^~^ ^ + | | | | | | | + | | | | | | Return type + | | | | | Argument types + | | | | Lifetimes | | | Once-ness (a.k.a., affine) | | Purity | Lifetime bound @@ -396,12 +402,24 @@ pub impl Parser { } fn parse_ty_fn_decl() -> fn_decl { - let inputs = do self.parse_unspanned_seq( - token::LPAREN, token::RPAREN, - seq_sep_trailing_disallowed(token::COMMA)) |p| { + /* - p.parse_arg_general(false) - }; + (fn) <'lt> (S) -> T + ^~~~^ ^~^ ^ + | | | + | | Return type + | Argument types + Lifetimes + + */ + if self.eat(token::LT) { + let _lifetimes = self.parse_lifetimes(); + self.expect(token::GT); + } + let inputs = self.parse_unspanned_seq( + token::LPAREN, token::RPAREN, + seq_sep_trailing_disallowed(token::COMMA), + |p| p.parse_arg_general(false)); let (ret_style, ret_ty) = self.parse_ret_ty(); ast::fn_decl { inputs: inputs, output: ret_ty, cf: ret_style } } @@ -433,8 +451,8 @@ pub impl Parser { let hi = p.last_span.hi; debug!("parse_trait_methods(): trait method signature ends in \ `%s`", - token_to_str(p.reader, p.token)); - match p.token { + token_to_str(p.reader, *p.token)); + match *p.token { token::SEMI => { p.bump(); debug!("parse_trait_methods(): parsing required method"); @@ -472,7 +490,7 @@ pub impl Parser { } _ => { p.fatal(~"expected `;` or `}` but found `" + - token_to_str(p.reader, p.token) + ~"`"); + token_to_str(p.reader, *p.token) + ~"`"); } } } @@ -544,7 +562,7 @@ pub impl Parser { fn parse_region() -> @region { self.expect(token::BINOP(token::AND)); - match copy self.token { + match *self.token { token::IDENT(sid, _) => { self.bump(); self.region_from_name(Some(sid)) @@ -560,32 +578,41 @@ pub impl Parser { let lo = self.span.lo; - let t = if self.token == token::LPAREN { + let t = if *self.token == token::LPAREN { self.bump(); - if self.token == token::RPAREN { + if *self.token == token::RPAREN { self.bump(); ty_nil } else { + // (t) is a parenthesized ty + // (t,) is the type of a tuple with only one field, + // of type t let mut ts = ~[self.parse_ty(false)]; - while self.token == token::COMMA { + let mut one_tuple = false; + while *self.token == token::COMMA { self.bump(); - ts.push(self.parse_ty(false)); + if *self.token != token::RPAREN { + ts.push(self.parse_ty(false)); + } + else { + one_tuple = true; + } } - let t = if vec::len(ts) == 1u { ts[0].node } + let t = if ts.len() == 1 && !one_tuple { ts[0].node } else { ty_tup(ts) }; self.expect(token::RPAREN); t } - } else if self.token == token::AT { + } else if *self.token == token::AT { self.bump(); self.parse_box_or_uniq_pointee(ManagedSigil, ty_box) - } else if self.token == token::TILDE { + } else if *self.token == token::TILDE { self.bump(); self.parse_box_or_uniq_pointee(OwnedSigil, ty_uniq) - } else if self.token == token::BINOP(token::STAR) { + } else if *self.token == token::BINOP(token::STAR) { self.bump(); ty_ptr(self.parse_mt()) - } else if self.token == token::LBRACE { + } else if *self.token == token::LBRACE { let elems = self.parse_unspanned_seq( token::LBRACE, token::RBRACE, seq_sep_trailing_allowed(token::COMMA), @@ -594,7 +621,7 @@ pub impl Parser { self.unexpected_last(token::RBRACE); } ty_rec(elems) - } else if self.token == token::LBRACKET { + } else if *self.token == token::LBRACKET { self.expect(token::LBRACKET); let mt = self.parse_mt(); @@ -605,15 +632,15 @@ pub impl Parser { }; self.expect(token::RBRACKET); t - } else if self.token == token::BINOP(token::AND) { + } else if *self.token == token::BINOP(token::AND) { self.bump(); self.parse_borrowed_pointee() } else if self.eat_keyword(~"extern") { self.parse_ty_bare_fn() - } else if self.token_is_closure_keyword(self.token) { + } else if self.token_is_closure_keyword(*self.token) { self.parse_ty_closure(None, None) - } else if self.token == token::MOD_SEP - || is_ident_or_path(self.token) { + } else if *self.token == token::MOD_SEP + || is_ident_or_path(*self.token) { let path = self.parse_path_with_tps(colons_before_params); ty_path(path, self.get_id()) } else { self.fatal(~"expected type"); }; @@ -626,15 +653,19 @@ pub impl Parser { sigil: ast::Sigil, ctor: &fn(+v: mt) -> ty_) -> ty_ { - // @foo/fn() or @fn() are parsed directly as fn types: - match copy self.token { + // @'foo fn() or @foo/fn() or @fn() are parsed directly as fn types: + match *self.token { + token::LIFETIME(rname) => { + self.bump(); + return self.parse_ty_closure(Some(sigil), Some(rname)); + } + token::IDENT(rname, _) => { if self.look_ahead(1u) == token::BINOP(token::SLASH) && - self.token_is_closure_keyword(self.look_ahead(2u)) - { + self.token_is_closure_keyword(self.look_ahead(2u)) { self.bump(); self.bump(); return self.parse_ty_closure(Some(sigil), Some(rname)); - } else if self.token_is_closure_keyword(self.token) { + } else if self.token_is_closure_keyword(*self.token) { return self.parse_ty_closure(Some(sigil), None); } } @@ -650,8 +681,13 @@ pub impl Parser { } fn parse_borrowed_pointee() -> ty_ { - // look for `&foo/` and interpret `foo` as the region name: - let rname = match copy self.token { + // look for `&'lt` or `&foo/` and interpret `foo` as the region name: + let rname = match *self.token { + token::LIFETIME(sid) => { + self.bump(); + Some(sid) + } + token::IDENT(sid, _) => { if self.look_ahead(1u) == token::BINOP(token::SLASH) { self.bump(); self.bump(); @@ -660,10 +696,11 @@ pub impl Parser { None } } + _ => { None } }; - if self.token_is_closure_keyword(self.token) { + if self.token_is_closure_keyword(*self.token) { return self.parse_ty_closure(Some(BorrowedSigil), rname); } @@ -689,13 +726,13 @@ pub impl Parser { } fn is_named_argument() -> bool { - let offset = if self.token == token::BINOP(token::AND) { + let offset = if *self.token == token::BINOP(token::AND) { 1 - } else if self.token == token::BINOP(token::MINUS) { + } else if *self.token == token::BINOP(token::MINUS) { 1 - } else if self.token == token::ANDAND { + } else if *self.token == token::ANDAND { 1 - } else if self.token == token::BINOP(token::PLUS) { + } else if *self.token == token::BINOP(token::PLUS) { if self.look_ahead(1) == token::BINOP(token::PLUS) { 2 } else { @@ -703,7 +740,7 @@ pub impl Parser { } } else { 0 }; if offset == 0 { - is_plain_ident(self.token) + is_plain_ident(*self.token) && self.look_ahead(1) == token::COLON } else { is_plain_ident(self.look_ahead(offset)) @@ -714,7 +751,7 @@ pub impl Parser { fn parse_capture_item_or(parse_arg_fn: fn(Parser) -> arg_or_capture_item) -> arg_or_capture_item { - if self.eat_keyword(~"move") || self.eat_keyword(~"copy") { + if self.eat_keyword(~"copy") { // XXX outdated syntax now that moves-based-on-type has gone in self.parse_ident(); either::Right(()) @@ -737,7 +774,7 @@ pub impl Parser { } else { m = infer(self.get_id()); ast_util::ident_to_pat(self.get_id(), - copy self.last_span, + *self.last_span, special_idents::invalid) }; @@ -781,7 +818,7 @@ pub impl Parser { fn maybe_parse_fixed_vstore_with_star() -> Option { if self.eat(token::BINOP(token::STAR)) { - match copy self.token { + match *self.token { token::LIT_INT_UNSUFFIXED(i) if i >= 0i64 => { self.bump(); Some(i as uint) @@ -790,7 +827,7 @@ pub impl Parser { self.fatal( fmt!("expected integral vector length \ but found `%s`", - token_to_str(self.reader, self.token))); + token_to_str(self.reader, *self.token))); } } } else { @@ -819,7 +856,8 @@ pub impl Parser { } else if self.eat_keyword(~"false") { lit_bool(false) } else { - let tok = self.token; + // XXX: This is a really bad copy! + let tok = *self.token; self.bump(); self.lit_from_token(tok) }; @@ -882,9 +920,8 @@ pub impl Parser { // vstores is... um... the same. I guess that's my fault. This // is still not ideal as for &str we end up parsing more than we // ought to and have to sort it out later. - if self.token == token::BINOP(token::SLASH) + if *self.token == token::BINOP(token::SLASH) && self.look_ahead(1u) == token::BINOP(token::AND) { - self.expect(token::BINOP(token::SLASH)); Some(self.parse_region()) } else { @@ -892,22 +929,95 @@ pub impl Parser { } }; - // Parse any type parameters which may appear: + // Parse any lifetime or type parameters which may appear: let tps = { - if self.token == token::LT { - self.parse_seq_lt_gt(Some(token::COMMA), - |p| p.parse_ty(false)) + if !self.eat(token::LT) { + ~[] } else { - codemap::spanned {node: ~[], span: path.span} + // First consume lifetimes. + let _lifetimes = self.parse_lifetimes(); + let result = self.parse_seq_to_gt( + Some(token::COMMA), + |p| p.parse_ty(false)); + result } }; - @ast::path { span: mk_sp(lo, tps.span.hi), + let hi = self.span.lo; + + @ast::path { span: mk_sp(lo, hi), rp: rp, - types: tps.node, + types: tps, .. *path } } + fn parse_opt_lifetime() -> Option { + /*! + * + * Parses 0 or 1 lifetime. + */ + + match *self.token { + token::LIFETIME(_) => { + Some(self.parse_lifetime()) + } + _ => { + None + } + } + } + + fn parse_lifetime() -> ast::Lifetime { + /*! + * + * Parses a single lifetime. + */ + + match *self.token { + token::LIFETIME(i) => { + self.bump(); + return ast::Lifetime { + id: self.get_id(), + span: *self.span, + ident: i + }; + } + _ => { + self.fatal(fmt!("Expected a lifetime name")); + } + } + } + + fn parse_lifetimes() -> ~[ast::Lifetime] { + /*! + * + * Parses zero or more comma separated lifetimes. + * Expects each lifetime to be followed by either + * a comma or `>`. Used when parsing type parameter + * lists, where we expect something like `<'a, 'b, T>`. + */ + + let mut res = ~[]; + loop { + match *self.token { + token::LIFETIME(_) => { + res.push(self.parse_lifetime()); + } + _ => { + return res; + } + } + + match *self.token { + token::COMMA => { self.bump();} + token::GT => { return res; } + _ => { + self.fatal(~"expected `,` or `>` after lifetime name"); + } + } + } + } + fn parse_mutability() -> mutability { if self.eat_keyword(~"mut") { m_mutbl @@ -947,14 +1057,16 @@ pub impl Parser { fn mk_lit_u32(i: u32) -> @expr { let span = self.span; - let lv_lit = @codemap::spanned { node: lit_uint(i as u64, ty_u32), - span: span }; + let lv_lit = @codemap::spanned { + node: lit_uint(i as u64, ty_u32), + span: *span + }; @expr { id: self.get_id(), callee_id: self.get_id(), node: expr_lit(lv_lit), - span: span, + span: *span, } } @@ -965,28 +1077,37 @@ pub impl Parser { let mut ex: expr_; - if self.token == token::LPAREN { + if *self.token == token::LPAREN { self.bump(); - if self.token == token::RPAREN { + // (e) is parenthesized e + // (e,) is a tuple with only one field, e + let mut one_tuple = false; + if *self.token == token::RPAREN { hi = self.span.hi; self.bump(); let lit = @spanned(lo, hi, lit_nil); return self.mk_expr(lo, hi, expr_lit(lit)); } let mut es = ~[self.parse_expr()]; - while self.token == token::COMMA { - self.bump(); es.push(self.parse_expr()); + while *self.token == token::COMMA { + self.bump(); + if *self.token != token::RPAREN { + es.push(self.parse_expr()); + } + else { + one_tuple = true; + } } hi = self.span.hi; self.expect(token::RPAREN); - return if es.len() == 1 { + return if es.len() == 1 && !one_tuple { self.mk_expr(lo, self.span.hi, expr_paren(es[0])) } else { self.mk_expr(lo, hi, expr_tup(es)) } - } else if self.token == token::LBRACE { + } else if *self.token == token::LBRACE { if self.looking_at_record_literal() { ex = self.parse_record_literal(); hi = self.span.hi; @@ -996,7 +1117,7 @@ pub impl Parser { return self.mk_expr(blk.span.lo, blk.span.hi, expr_block(blk)); } - } else if token::is_bar(self.token) { + } else if token::is_bar(*self.token) { return self.parse_lambda_expr(); } else if self.eat_keyword(~"if") { return self.parse_if_expr(); @@ -1023,17 +1144,17 @@ pub impl Parser { return self.parse_fn_expr(sigil); } else if self.eat_keyword(~"unsafe") { return self.parse_block_expr(lo, unsafe_blk); - } else if self.token == token::LBRACKET { + } else if *self.token == token::LBRACKET { self.bump(); let mutbl = self.parse_mutability(); - if self.token == token::RBRACKET { + if *self.token == token::RBRACKET { // Empty vector. self.bump(); ex = expr_vec(~[], mutbl); } else { // Nonempty vector. let first_expr = self.parse_expr(); - if self.token == token::COMMA && + if *self.token == token::COMMA && self.look_ahead(1) == token::DOTDOT { // Repeating vector syntax: [ 0, ..512 ] self.bump(); @@ -1041,7 +1162,7 @@ pub impl Parser { let count = self.parse_expr(); self.expect(token::RBRACKET); ex = expr_repeat(first_expr, count, mutbl); - } else if self.token == token::COMMA { + } else if *self.token == token::COMMA { // Vector with two or more elements. self.bump(); let remaining_exprs = @@ -1069,13 +1190,13 @@ pub impl Parser { ex = expr_assert(e); hi = e.span.hi; } else if self.eat_keyword(~"return") { - if can_begin_expr(self.token) { + if can_begin_expr(*self.token) { let e = self.parse_expr(); hi = e.span.hi; ex = expr_ret(Some(e)); } else { ex = expr_ret(None); } } else if self.eat_keyword(~"break") { - if is_ident(self.token) { + if is_ident(*self.token) { ex = expr_break(Some(self.parse_ident())); } else { ex = expr_break(None); @@ -1085,31 +1206,28 @@ pub impl Parser { let e = self.parse_expr(); ex = expr_copy(e); hi = e.span.hi; - } else if self.eat_keyword(~"move") { - // XXX move keyword is no longer important, remove after snapshot - return self.parse_expr(); - } else if self.token == token::MOD_SEP || - is_ident(self.token) && !self.is_keyword(~"true") && - !self.is_keyword(~"false") { + } else if *self.token == token::MOD_SEP || + is_ident(*self.token) && !self.is_keyword(~"true") && + !self.is_keyword(~"false") { let pth = self.parse_path_with_tps(true); /* `!`, as an operator, is prefix, so we know this isn't that */ - if self.token == token::NOT { + if *self.token == token::NOT { self.bump(); - let tts = match self.token { - token::LPAREN | token::LBRACE => { - let ket = token::flip_delimiter(copy self.token); - self.parse_unspanned_seq(copy self.token, ket, - seq_sep_none(), - |p| p.parse_token_tree()) - } + match *self.token { + token::LPAREN | token::LBRACE => {} _ => self.fatal(~"expected open delimiter") }; + + let ket = token::flip_delimiter(*self.token); + let tts = self.parse_unspanned_seq(*self.token, + ket, + seq_sep_none(), + |p| p.parse_token_tree()); let hi = self.span.hi; - return self.mk_mac_expr( - lo, hi, mac_invoc_tt(pth, tts)); - } else if self.token == token::LBRACE { + return self.mk_mac_expr(lo, hi, mac_invoc_tt(pth, tts)); + } else if *self.token == token::LBRACE { // This might be a struct literal. if self.looking_at_record_literal() { // It's a struct literal. @@ -1117,8 +1235,7 @@ pub impl Parser { let mut fields = ~[]; let mut base = None; fields.push(self.parse_field(token::COLON)); - while self.token != token::RBRACE { - + while *self.token != token::RBRACE { if self.try_parse_obsolete_with() { break; } @@ -1130,7 +1247,7 @@ pub impl Parser { break; } - if self.token == token::RBRACE { + if *self.token == token::RBRACE { // Accept an optional trailing comma. break; } @@ -1167,7 +1284,7 @@ pub impl Parser { } fn permits_call() -> bool { - return self.restriction != RESTRICT_NO_CALL_EXPRS; + return *self.restriction != RESTRICT_NO_CALL_EXPRS; } fn parse_dot_or_call_expr_with(e0: @expr) -> @expr { @@ -1177,7 +1294,7 @@ pub impl Parser { loop { // expr.f if self.eat(token::DOT) { - match copy self.token { + match *self.token { token::IDENT(i, _) => { hi = self.span.hi; self.bump(); @@ -1190,7 +1307,7 @@ pub impl Parser { }; // expr.f() method call - match copy self.token { + match *self.token { token::LPAREN if self.permits_call() => { let es = self.parse_unspanned_seq( token::LPAREN, token::RPAREN, @@ -1199,7 +1316,7 @@ pub impl Parser { hi = self.span.hi; let nd = expr_method_call(e, i, tys, es, NoSugar); - e = self.mk_expr(lo, hi, move nd); + e = self.mk_expr(lo, hi, nd); } _ => { e = self.mk_expr(lo, hi, expr_field(e, i, tys)); @@ -1211,7 +1328,7 @@ pub impl Parser { loop; } if self.expr_is_complete(e) { break; } - match copy self.token { + match *self.token { // expr(...) token::LPAREN if self.permits_call() => { let es = self.parse_unspanned_seq( @@ -1242,17 +1359,17 @@ pub impl Parser { // parse an optional separator followed by a kleene-style // repetition token (+ or *). fn parse_sep_and_zerok() -> (Option, bool) { - if self.token == token::BINOP(token::STAR) - || self.token == token::BINOP(token::PLUS) { - let zerok = self.token == token::BINOP(token::STAR); + if *self.token == token::BINOP(token::STAR) + || *self.token == token::BINOP(token::PLUS) { + let zerok = *self.token == token::BINOP(token::STAR); self.bump(); return (None, zerok); } else { - let sep = self.token; + let sep = *self.token; self.bump(); - if self.token == token::BINOP(token::STAR) - || self.token == token::BINOP(token::PLUS) { - let zerok = self.token == token::BINOP(token::STAR); + if *self.token == token::BINOP(token::STAR) + || *self.token == token::BINOP(token::PLUS) { + let zerok = *self.token == token::BINOP(token::STAR); self.bump(); return (Some(sep), zerok); } else { @@ -1267,18 +1384,18 @@ pub impl Parser { fn parse_non_delim_tt_tok(p: Parser) -> token_tree { maybe_whole!(deref p, nt_tt); - match p.token { + match *p.token { token::RPAREN | token::RBRACE | token::RBRACKET => { p.fatal(~"incorrect close delimiter: `" - + token_to_str(p.reader, p.token) + ~"`"); + + token_to_str(p.reader, *p.token) + ~"`"); } /* we ought to allow different depths of unquotation */ - token::DOLLAR if p.quote_depth > 0u => { + token::DOLLAR if *p.quote_depth > 0u => { p.bump(); - let sp = p.span; + let sp = *p.span; - if p.token == token::LPAREN { + if *p.token == token::LPAREN { let seq = p.parse_seq(token::LPAREN, token::RPAREN, seq_sep_none(), |p| p.parse_token_tree()); @@ -1296,18 +1413,18 @@ pub impl Parser { // turn the next token into a tt_tok: fn parse_any_tt_tok(p: Parser) -> token_tree{ - let res = tt_tok(p.span, p.token); + let res = tt_tok(*p.span, *p.token); p.bump(); res } - match self.token { + match *self.token { token::EOF => { self.fatal(~"file ended in the middle of a macro invocation"); } token::LPAREN | token::LBRACE | token::LBRACKET => { // tjc: ?????? - let ket = token::flip_delimiter(copy self.token); + let ket = token::flip_delimiter(*self.token); tt_delim(vec::append( // the open delimiter: ~[parse_any_tt_tok(self)], @@ -1323,11 +1440,11 @@ pub impl Parser { } fn parse_all_token_trees() -> ~[token_tree] { - let tts = DVec(); - while self.token != token::EOF { + let mut tts = ~[]; + while *self.token != token::EOF { tts.push(self.parse_token_tree()); } - tts.get() + tts } fn parse_matchers() -> ~[matcher] { @@ -1335,11 +1452,11 @@ pub impl Parser { // the interpolation of matchers maybe_whole!(self, nt_matchers); let name_idx = @mut 0u; - return match self.token { + return match *self.token { token::LBRACE | token::LPAREN | token::LBRACKET => { - self.parse_matcher_subseq(name_idx, copy self.token, + self.parse_matcher_subseq(name_idx, *self.token, // tjc: not sure why we need a copy - token::flip_delimiter(copy self.token)) + token::flip_delimiter(*self.token)) } _ => self.fatal(~"expected open delimiter") } @@ -1356,9 +1473,9 @@ pub impl Parser { self.expect(bra); - while self.token != ket || lparens > 0u { - if self.token == token::LPAREN { lparens += 1u; } - if self.token == token::RPAREN { lparens -= 1u; } + while *self.token != ket || lparens > 0u { + if *self.token == token::LPAREN { lparens += 1u; } + if *self.token == token::RPAREN { lparens -= 1u; } ret_val.push(self.parse_matcher(name_idx)); } @@ -1370,11 +1487,12 @@ pub impl Parser { fn parse_matcher(name_idx: @mut uint) -> matcher { let lo = self.span.lo; - let m = if self.token == token::DOLLAR { + let m = if *self.token == token::DOLLAR { self.bump(); - if self.token == token::LPAREN { + if *self.token == token::LPAREN { let name_idx_lo = *name_idx; - let ms = self.parse_matcher_subseq(name_idx, token::LPAREN, + let ms = self.parse_matcher_subseq(name_idx, + token::LPAREN, token::RPAREN); if ms.len() == 0u { self.fatal(~"repetition body must be nonempty"); @@ -1390,7 +1508,7 @@ pub impl Parser { m } } else { - let m = match_tok(self.token); + let m = match_tok(*self.token); self.bump(); m }; @@ -1404,7 +1522,7 @@ pub impl Parser { let mut hi; let mut ex; - match copy self.token { + match *self.token { token::NOT => { self.bump(); let e = self.parse_prefix_expr(); @@ -1429,6 +1547,7 @@ pub impl Parser { } token::AND => { self.bump(); + let _lt = self.parse_opt_lifetime(); let m = self.parse_mutability(); let e = self.parse_prefix_expr(); hi = e.span.hi; @@ -1492,13 +1611,13 @@ pub impl Parser { fn parse_more_binops(lhs: @expr, min_prec: uint) -> @expr { if self.expr_is_complete(lhs) { return lhs; } - let peeked = self.token; + let peeked = *self.token; if peeked == token::BINOP(token::OR) && - (self.restriction == RESTRICT_NO_BAR_OP || - self.restriction == RESTRICT_NO_BAR_OR_DOUBLEBAR_OP) { + (*self.restriction == RESTRICT_NO_BAR_OP || + *self.restriction == RESTRICT_NO_BAR_OR_DOUBLEBAR_OP) { lhs } else if peeked == token::OROR && - self.restriction == RESTRICT_NO_BAR_OR_DOUBLEBAR_OP { + *self.restriction == RESTRICT_NO_BAR_OR_DOUBLEBAR_OP { lhs } else { let cur_opt = token_to_binop(peeked); @@ -1538,7 +1657,7 @@ pub impl Parser { fn parse_assign_expr() -> @expr { let lo = self.span.lo; let lhs = self.parse_binops(); - match copy self.token { + match *self.token { token::EQ => { self.bump(); let rhs = self.parse_expr(); @@ -1565,7 +1684,7 @@ pub impl Parser { expr_assign_op(aop, lhs, rhs)) } token::LARROW => { - self.obsolete(copy self.span, ObsoleteBinaryMove); + self.obsolete(*self.span, ObsoleteBinaryMove); // Bogus value (but it's an error) self.bump(); // <- self.bump(); // rhs @@ -1595,8 +1714,7 @@ pub impl Parser { els = Some(elexpr); hi = elexpr.span.hi; } - let q = {cond: cond, then: thn, els: els, lo: lo, hi: hi}; - self.mk_expr(q.lo, q.hi, expr_if(q.cond, q.then, q.els)) + self.mk_expr(lo, hi, expr_if(cond, thn, els)) } fn parse_fn_expr(sigil: Sigil) -> @expr { @@ -1616,7 +1734,7 @@ pub impl Parser { fn parse_lambda_block_expr() -> @expr { self.parse_lambda_expr_( || { - match self.token { + match *self.token { token::BINOP(token::OR) | token::OROR => { self.parse_fn_block_decl() } @@ -1627,7 +1745,7 @@ pub impl Parser { output: @Ty { id: self.get_id(), node: ty_infer, - span: self.span + span: *self.span }, cf: return_val } @@ -1724,8 +1842,8 @@ pub impl Parser { // but they aren't represented by tests debug!("sugary call on %?", e.node); self.span_fatal( - lo, fmt!("`%s` must be followed by a block call", - keyword)); + *lo, + fmt!("`%s` must be followed by a block call", keyword)); } } } @@ -1741,13 +1859,13 @@ pub impl Parser { fn parse_loop_expr() -> @expr { // loop headers look like 'loop {' or 'loop unsafe {' let is_loop_header = - self.token == token::LBRACE - || (is_ident(copy self.token) + *self.token == token::LBRACE + || (is_ident(*self.token) && self.look_ahead(1) == token::LBRACE); // labeled loop headers look like 'loop foo: {' let is_labeled_loop_header = - is_ident(self.token) - && !self.is_any_keyword(copy self.token) + is_ident(*self.token) + && !self.is_any_keyword(*self.token) && self.look_ahead(1) == token::COLON; if is_loop_header || is_labeled_loop_header { @@ -1767,7 +1885,7 @@ pub impl Parser { } else { // This is a 'continue' expression let lo = self.span.lo; - let ex = if is_ident(self.token) { + let ex = if is_ident(*self.token) { expr_again(Some(self.parse_ident())) } else { expr_again(None) @@ -1780,7 +1898,7 @@ pub impl Parser { // For distingishing between record literals and blocks fn looking_at_record_literal() -> bool { let lookahead = self.look_ahead(1); - self.token == token::LBRACE && + *self.token == token::LBRACE && (self.token_is_keyword(~"mut", lookahead) || (is_plain_ident(lookahead) && self.look_ahead(2) == token::COLON)) @@ -1790,8 +1908,8 @@ pub impl Parser { self.expect(token::LBRACE); let mut fields = ~[self.parse_field(token::COLON)]; let mut base = None; - while self.token != token::RBRACE { - if self.token == token::COMMA + while *self.token != token::RBRACE { + if *self.token == token::COMMA && self.look_ahead(1) == token::DOTDOT { self.bump(); self.bump(); @@ -1803,14 +1921,14 @@ pub impl Parser { } self.expect(token::COMMA); - if self.token == token::RBRACE { + if *self.token == token::RBRACE { // record ends by an optional trailing comma break; } fields.push(self.parse_field(token::COLON)); } self.expect(token::RBRACE); - //self.warn(~"REC"); + self.warn(~"REC"); return expr_rec(fields, base); } @@ -1819,7 +1937,7 @@ pub impl Parser { let discriminant = self.parse_expr(); self.expect(token::LBRACE); let mut arms: ~[arm] = ~[]; - while self.token != token::RBRACE { + while *self.token != token::RBRACE { let pats = self.parse_pats(); let mut guard = None; if self.eat_keyword(~"if") { guard = Some(self.parse_expr()); } @@ -1828,7 +1946,7 @@ pub impl Parser { let require_comma = !classify::expr_is_simple_block(expr) - && self.token != token::RBRACE; + && *self.token != token::RBRACE; if require_comma { self.expect(token::COMMA); @@ -1861,21 +1979,21 @@ pub impl Parser { // parse an expression, subject to the given restriction fn parse_expr_res(r: restriction) -> @expr { - let old = self.restriction; - self.restriction = r; + let old = *self.restriction; + *self.restriction = r; let e = self.parse_assign_expr(); - self.restriction = old; + *self.restriction = old; return e; } fn parse_initializer() -> Option<@expr> { - match self.token { + match *self.token { token::EQ => { self.bump(); return Some(self.parse_expr()); } token::LARROW => { - self.obsolete(copy self.span, ObsoleteMoveInit); + self.obsolete(*self.span, ObsoleteMoveInit); self.bump(); self.bump(); return None; @@ -1890,7 +2008,7 @@ pub impl Parser { let mut pats = ~[]; loop { pats.push(self.parse_pat(true)); - if self.token == token::BINOP(token::OR) { self.bump(); } + if *self.token == token::BINOP(token::OR) { self.bump(); } else { return pats; } }; } @@ -1900,12 +2018,12 @@ pub impl Parser { let mut tail = None; let mut first = true; - while self.token != token::RBRACKET { + while *self.token != token::RBRACKET { if first { first = false; } else { self.expect(token::COMMA); } let mut is_tail = false; - if self.token == token::DOTDOT { + if *self.token == token::DOTDOT { self.bump(); is_tail = true; } @@ -1932,15 +2050,15 @@ pub impl Parser { let mut fields = ~[]; let mut etc = false; let mut first = true; - while self.token != token::RBRACE { + while *self.token != token::RBRACE { if first { first = false; } else { self.expect(token::COMMA); } - if self.token == token::UNDERSCORE { + if *self.token == token::UNDERSCORE { self.bump(); - if self.token != token::RBRACE { + if *self.token != token::RBRACE { self.fatal(~"expected `}`, found `" + - token_to_str(self.reader, self.token) + + token_to_str(self.reader, *self.token) + ~"`"); } etc = true; @@ -1957,14 +2075,14 @@ pub impl Parser { let fieldpath = ast_util::ident_to_path(mk_sp(lo1, hi1), fieldname); let mut subpat; - if self.token == token::COLON { + if *self.token == token::COLON { self.bump(); subpat = self.parse_pat(refutable); } else { subpat = @ast::pat { id: self.get_id(), node: pat_ident(bind_infer, fieldpath, None), - span: self.last_span + span: *self.last_span }; } fields.push(ast::field_pat { ident: fieldname, pat: subpat }); @@ -1978,7 +2096,7 @@ pub impl Parser { let lo = self.span.lo; let mut hi = self.span.hi; let mut pat; - match self.token { + match *self.token { token::UNDERSCORE => { self.bump(); pat = pat_wild; } token::AT => { self.bump(); @@ -2056,7 +2174,7 @@ pub impl Parser { } token::LPAREN => { self.bump(); - if self.token == token::RPAREN { + if *self.token == token::RPAREN { hi = self.span.hi; self.bump(); let lit = @codemap::spanned { @@ -2066,11 +2184,13 @@ pub impl Parser { pat = pat_lit(expr); } else { let mut fields = ~[self.parse_pat(refutable)]; - while self.token == token::COMMA { - self.bump(); - fields.push(self.parse_pat(refutable)); + if self.look_ahead(1) != token::RPAREN { + while *self.token == token::COMMA { + self.bump(); + fields.push(self.parse_pat(refutable)); + } } - if vec::len(fields) == 1u { self.expect(token::COMMA); } + if fields.len() == 1 { self.expect(token::COMMA); } hi = self.span.hi; self.expect(token::RPAREN); pat = pat_tup(fields); @@ -2101,10 +2221,6 @@ pub impl Parser { } else if self.eat_keyword(~"copy") { pat = self.parse_pat_ident(refutable, bind_by_copy); } else { - if self.eat_keyword(~"move") { - /* XXX---remove move keyword */ - } - // XXX---refutable match bindings should work same as let let binding_mode = if refutable {bind_infer} else {bind_by_copy}; @@ -2118,7 +2234,7 @@ pub impl Parser { cannot_be_enum_or_struct = true } - if is_plain_ident(self.token) && cannot_be_enum_or_struct { + if is_plain_ident(*self.token) && cannot_be_enum_or_struct { let name = self.parse_value_path(); let sub; if self.eat(token::AT) { @@ -2129,7 +2245,7 @@ pub impl Parser { pat = pat_ident(binding_mode, name, sub); } else { let enum_path = self.parse_path_with_tps(true); - match self.token { + match *self.token { token::LBRACE => { self.bump(); let (fields, etc) = @@ -2140,7 +2256,7 @@ pub impl Parser { _ => { let mut args: ~[@pat] = ~[]; let mut star_pat = false; - match self.token { + match *self.token { token::LPAREN => match self.look_ahead(1u) { token::BINOP(token::STAR) => { // This is a "top constructor only" pat @@ -2184,9 +2300,9 @@ pub impl Parser { fn parse_pat_ident(refutable: bool, binding_mode: ast::binding_mode) -> ast::pat_ { - if !is_plain_ident(self.token) { + if !is_plain_ident(*self.token) { self.span_fatal( - copy self.last_span, + *self.last_span, ~"expected identifier, found path"); } let name = self.parse_value_path(); @@ -2200,9 +2316,9 @@ pub impl Parser { // leads to a parse error. Note that if there is no explicit // binding mode then we do not end up here, because the lookahead // will direct us over to parse_enum_variant() - if self.token == token::LPAREN { + if *self.token == token::LPAREN { self.span_fatal( - copy self.last_span, + *self.last_span, ~"expected identifier, found enum pattern"); } @@ -2250,7 +2366,7 @@ pub impl Parser { if self.eat_keyword(~"mut") { is_mutbl = struct_mutable; } - if !is_plain_ident(self.token) { + if !is_plain_ident(*self.token) { self.fatal(~"expected ident"); } let name = self.parse_ident(); @@ -2279,8 +2395,8 @@ pub impl Parser { self.expect_keyword(~"let"); let decl = self.parse_let(); return @spanned(lo, decl.span.hi, stmt_decl(decl, self.get_id())); - } else if is_ident(self.token) - && !self.is_any_keyword(copy self.token) + } else if is_ident(*self.token) + && !self.is_any_keyword(*self.token) && self.look_ahead(1) == token::NOT { check_expected_item(self, first_item_attrs); @@ -2290,7 +2406,7 @@ pub impl Parser { let pth = self.parse_value_path(); self.bump(); - let id = if self.token == token::LPAREN { + let id = if *self.token == token::LPAREN { token::special_idents::invalid // no special identifier } else { self.parse_ident() @@ -2345,7 +2461,7 @@ pub impl Parser { } fn expr_is_complete(e: @expr) -> bool { - return self.restriction == RESTRICT_STMT_EXPR && + return *self.restriction == RESTRICT_STMT_EXPR && !classify::expr_requires_semi_to_be_stmt(e); } @@ -2361,20 +2477,20 @@ pub impl Parser { maybe_whole!(pair_empty self, nt_block); fn maybe_parse_inner_attrs_and_next(p: Parser, parse_attrs: bool) -> - {inner: ~[attribute], next: ~[attribute]} { + (~[attribute], ~[attribute]) { if parse_attrs { p.parse_inner_attrs_and_next() } else { - {inner: ~[], next: ~[]} + (~[], ~[]) } } let lo = self.span.lo; if self.eat_keyword(~"unsafe") { - self.obsolete(copy self.span, ObsoleteUnsafeBlock); + self.obsolete(*self.span, ObsoleteUnsafeBlock); } self.expect(token::LBRACE); - let {inner: move inner, next: move next} = + let (inner, next) = maybe_parse_inner_attrs_and_next(self, parse_attrs); return (inner, self.parse_block_tail_(lo, default_blk, next)); } @@ -2399,10 +2515,12 @@ pub impl Parser { let mut stmts = ~[]; let mut expr = None; - let {attrs_remaining: move attrs_remaining, - view_items: move view_items, - items: items, _} = - self.parse_items_and_view_items(first_item_attrs, + let ParsedItemsAndViewItems { + attrs_remaining: attrs_remaining, + view_items: view_items, + items: items, + _ + } = self.parse_items_and_view_items(first_item_attrs, IMPORTS_AND_ITEMS_ALLOWED, false); for items.each |item| { @@ -2413,12 +2531,12 @@ pub impl Parser { let mut initial_attrs = attrs_remaining; - if self.token == token::RBRACE && !vec::is_empty(initial_attrs) { + if *self.token == token::RBRACE && !vec::is_empty(initial_attrs) { self.fatal(~"expected item"); } - while self.token != token::RBRACE { - match self.token { + while *self.token != token::RBRACE { + match *self.token { token::SEMI => { self.bump(); // empty } @@ -2428,7 +2546,7 @@ pub impl Parser { match stmt.node { stmt_expr(e, stmt_id) => { // Expression without semicolon - match self.token { + match *self.token { token::SEMI => { self.bump(); stmts.push(@codemap::spanned { @@ -2453,7 +2571,7 @@ pub impl Parser { stmt_mac(ref m, _) => { // Statement macro; might be an expr - match self.token { + match *self.token { token::SEMI => { self.bump(); stmts.push(@codemap::spanned { @@ -2499,9 +2617,9 @@ pub impl Parser { @Ty { id: self.get_id(), node: ty_path( - ident_to_path(copy self.last_span, i), + ident_to_path(*self.last_span, i), self.get_id()), - span: self.last_span, + span: *self.last_span, } } @@ -2527,12 +2645,12 @@ pub impl Parser { if self.eat_keyword(~"static") { bounds.push(RegionTyParamBound); } else { - self.span_err(copy self.span, + self.span_err(*self.span, ~"`&static` is the only permissible \ region bound here"); } - } else if is_ident(self.token) { - let maybe_bound = match self.token { + } else if is_ident(*self.token) { + let maybe_bound = match *self.token { token::IDENT(copy sid, _) => { match *self.id_to_str(sid) { @@ -2540,7 +2658,7 @@ pub impl Parser { | ~"copy" | ~"const" | ~"owned" => { - self.obsolete(copy self.span, + self.obsolete(*self.span, ObsoleteLowerCaseKindBounds); // Bogus value, but doesn't matter, since // is an error @@ -2550,7 +2668,8 @@ pub impl Parser { _ => None } } - _ => fail!() + _ => self.bug( + ~"is_ident() said this would be an identifier") }; match maybe_bound { @@ -2568,11 +2687,16 @@ pub impl Parser { } if self.eat(token::BINOP(token::PLUS)) { - // Should be `break;` but that isn't backwards compatible. + loop; + } + + if is_ident_or_path(*self.token) { + self.obsolete(*self.span, + ObsoleteTraitBoundSeparator); } } } - return @move bounds; + return @bounds; } fn parse_ty_param() -> ty_param { @@ -2583,7 +2707,10 @@ pub impl Parser { fn parse_ty_params() -> ~[ty_param] { if self.eat(token::LT) { - self.parse_seq_to_gt(Some(token::COMMA), |p| p.parse_ty_param()) + let _lifetimes = self.parse_lifetimes(); + self.parse_seq_to_gt( + Some(token::COMMA), + |p| p.parse_ty_param()) } else { ~[] } } @@ -2606,7 +2733,7 @@ pub impl Parser { } fn is_self_ident() -> bool { - match self.token { + match *self.token { token::IDENT(id, false) if id == special_idents::self_ => true, _ => false @@ -2616,7 +2743,7 @@ pub impl Parser { fn expect_self_ident() { if !self.is_self_ident() { self.fatal(fmt!("expected `self` but found `%s`", - token_to_str(self.reader, self.token))); + token_to_str(self.reader, *self.token))); } self.bump(); } @@ -2647,7 +2774,7 @@ pub impl Parser { // A bit of complexity and lookahead is needed here in order to to be // backwards compatible. let lo = self.span.lo; - let self_ty = match copy self.token { + let self_ty = match *self.token { token::BINOP(token::AND) => { maybe_parse_self_ty(sty_region, self) } @@ -2669,7 +2796,7 @@ pub impl Parser { // If we parsed a self type, expect a comma before the argument list. let args_or_capture_items; if self_ty != sty_by_ref { - match copy self.token { + match *self.token { token::COMMA => { self.bump(); let sep = seq_sep_trailing_disallowed(token::COMMA); @@ -2683,7 +2810,8 @@ pub impl Parser { } _ => { self.fatal(~"expected `,` or `)`, found `" + - token_to_str(self.reader, self.token) + ~"`"); + token_to_str(self.reader, *self.token) + + ~"`"); } } } else { @@ -2724,7 +2852,7 @@ pub impl Parser { let output = if self.eat(token::RARROW) { self.parse_ty(false) } else { - @Ty { id: self.get_id(), node: ty_infer, span: self.span } + @Ty { id: self.get_id(), node: ty_infer, span: *self.span } }; ast::fn_decl { @@ -2734,10 +2862,10 @@ pub impl Parser { } } - fn parse_fn_header() -> {ident: ident, tps: ~[ty_param]} { + fn parse_fn_header() -> (ident, ~[ty_param]) { let id = self.parse_value_ident(); let ty_params = self.parse_ty_params(); - return {ident: id, tps: ty_params}; + (id, ty_params) } fn mk_item(+lo: BytePos, +hi: BytePos, +ident: ident, @@ -2752,10 +2880,10 @@ pub impl Parser { } fn parse_item_fn(purity: purity) -> item_info { - let t = self.parse_fn_header(); + let (ident, tps) = self.parse_fn_header(); let decl = self.parse_fn_decl(|p| p.parse_arg()); let (inner_attrs, body) = self.parse_inner_attrs_and_block(true); - (t.ident, item_fn(decl, purity, t.tps, body), Some(inner_attrs)) + (ident, item_fn(decl, purity, tps, body), Some(inner_attrs)) } fn parse_method_name() -> ident { @@ -2803,7 +2931,7 @@ pub impl Parser { // Parse traits, if necessary. let traits; - if self.token == token::COLON { + if *self.token == token::COLON { self.bump(); traits = self.parse_trait_ref_list(token::LBRACE); } else { @@ -2828,7 +2956,7 @@ pub impl Parser { // First, parse type parameters if necessary. let mut tps; - if self.token == token::LT { + if *self.token == token::LT { tps = self.parse_ty_params(); } else { tps = ~[]; @@ -2838,16 +2966,11 @@ pub impl Parser { // XXX: clownshoes let ident = special_idents::clownshoes_extensions; - // Parse the type. (If this is `impl trait for type`, however, this - // actually parses the trait.) + // Parse the trait. let mut ty = self.parse_ty(false); // Parse traits, if necessary. - let opt_trait = if self.token == token::COLON { - // Old-style trait. - self.bump(); - Some(self.parse_trait_ref()) - } else if self.eat_keyword(~"for") { + let opt_trait = if self.eat_keyword(~"for") { // New-style trait. Reinterpret the type as a trait. let opt_trait_ref = match ty.node { ty_path(path, node_id) => { @@ -2857,13 +2980,16 @@ pub impl Parser { }) } _ => { - self.span_err(copy self.span, ~"not a trait"); + self.span_err(*self.span, ~"not a trait"); None } }; ty = self.parse_ty(false); opt_trait_ref + } else if self.eat(token::COLON) { + self.obsolete(*self.span, ObsoleteImplSyntax); + Some(self.parse_trait_ref()) } else { None }; @@ -2884,7 +3010,7 @@ pub impl Parser { // the return type of the ctor function. fn ident_to_path_tys(i: ident, typarams: ~[ty_param]) -> @path { - let s = self.last_span; + let s = *self.last_span; @ast::path { span: s, @@ -2902,7 +3028,7 @@ pub impl Parser { } fn ident_to_path(i: ident) -> @path { - @ast::path { span: self.last_span, + @ast::path { span: *self.last_span, global: false, idents: ~[i], rp: None, @@ -2927,7 +3053,7 @@ pub impl Parser { self.parse_region_param(); let ty_params = self.parse_ty_params(); if self.eat(token::COLON) { - self.obsolete(copy self.span, ObsoleteClassTraits); + self.obsolete(*self.span, ObsoleteClassTraits); let _ = self.parse_trait_ref_list(token::LBRACE); } @@ -2939,7 +3065,7 @@ pub impl Parser { // It's a record-like struct. is_tuple_like = false; fields = ~[]; - while self.token != token::RBRACE { + while *self.token != token::RBRACE { match self.parse_class_item() { dtor_decl(ref blk, ref attrs, s) => { match the_dtor { @@ -2963,7 +3089,7 @@ pub impl Parser { } } self.bump(); - } else if self.token == token::LPAREN { + } else if *self.token == token::LPAREN { // It's a tuple-like struct. is_tuple_like = true; fields = do self.parse_unspanned_seq(token::LPAREN, token::RPAREN, @@ -2985,7 +3111,7 @@ pub impl Parser { } else { self.fatal(fmt!("expected `{`, `(`, or `;` after struct name \ but found `%s`", - token_to_str(self.reader, self.token))); + token_to_str(self.reader, *self.token))); } let actual_dtor = do the_dtor.map |dtor| { @@ -3015,13 +3141,13 @@ pub impl Parser { fn parse_single_class_item(vis: visibility) -> @struct_field { if self.eat_obsolete_ident("let") { - self.obsolete(copy self.last_span, ObsoleteLet); + self.obsolete(*self.last_span, ObsoleteLet); } let a_var = self.parse_instance_var(vis); - match self.token { + match *self.token { token::SEMI => { - self.obsolete(copy self.span, ObsoleteFieldTerminator); + self.obsolete(*self.span, ObsoleteFieldTerminator); self.bump(); } token::COMMA => { @@ -3029,11 +3155,11 @@ pub impl Parser { } token::RBRACE => {} _ => { - self.span_fatal(copy self.span, + self.span_fatal(*self.span, fmt!("expected `;`, `,`, or '}' but \ found `%s`", token_to_str(self.reader, - self.token))); + *self.token))); } } a_var @@ -3082,19 +3208,27 @@ pub impl Parser { self.eat_keyword(~"static") } + // given a termination token and a vector of already-parsed + // attributes (of length 0 or 1), parse all of the items in a module fn parse_mod_items(term: token::Token, +first_item_attrs: ~[attribute]) -> _mod { - // Shouldn't be any view items since we've already parsed an item attr - let {attrs_remaining: move attrs_remaining, - view_items: move view_items, - items: starting_items, _} = - self.parse_items_and_view_items(first_item_attrs, + // parse all of the items up to closing or an attribute. + // view items are legal here. + let ParsedItemsAndViewItems { + attrs_remaining: attrs_remaining, + view_items: view_items, + items: starting_items, + _ + } = self.parse_items_and_view_items(first_item_attrs, VIEW_ITEMS_AND_ITEMS_ALLOWED, true); - let mut items: ~[@item] = move starting_items; + let mut items: ~[@item] = starting_items; + // looks like this code depends on the invariant that + // outer attributes can't occur on view items (or macros + // invocations?) let mut first = true; - while self.token != term { + while *self.token != term { let mut attrs = self.parse_outer_attributes(); if first { attrs = vec::append(attrs_remaining, attrs); @@ -3111,7 +3245,7 @@ pub impl Parser { } _ => { self.fatal(~"expected item but found `" + - token_to_str(self.reader, self.token) + ~"`"); + token_to_str(self.reader, *self.token) + ~"`"); } } debug!("parse_mod_items: attrs=%?", attrs); @@ -3136,21 +3270,21 @@ pub impl Parser { } fn parse_item_mod(outer_attrs: ~[ast::attribute]) -> item_info { - let id_span = self.span; + let id_span = *self.span; let id = self.parse_ident(); - let info_ = if self.token == token::SEMI { + let info_ = if *self.token == token::SEMI { self.bump(); // This mod is in an external file. Let's go get it! let (m, attrs) = self.eval_src_mod(id, outer_attrs, id_span); - (id, m, Some(move attrs)) + (id, m, Some(attrs)) } else { self.push_mod_path(id, outer_attrs); self.expect(token::LBRACE); - let inner_attrs = self.parse_inner_attrs_and_next(); - let m = self.parse_mod_items(token::RBRACE, inner_attrs.next); + let (inner, next) = self.parse_inner_attrs_and_next(); + let m = self.parse_mod_items(token::RBRACE, next); self.expect(token::RBRACE); self.pop_mod_path(); - (id, item_mod(m), Some(inner_attrs.inner)) + (id, item_mod(m), Some(inner)) }; // XXX: Transitionary hack to do the template work inside core @@ -3158,11 +3292,11 @@ pub impl Parser { // on the mod, then we'll go and suck in another file and merge // its contents match ::attr::first_attr_value_str_by_name(outer_attrs, ~"merge") { - Some(ref path) => { + Some(path) => { let prefix = Path( - self.sess.cm.span_to_filename(copy self.span)); + self.sess.cm.span_to_filename(*self.span)); let prefix = prefix.dir_path(); - let path = Path((*path)); + let path = Path(copy *path); let (new_mod_item, new_attrs) = self.eval_src_mod_from_path( prefix, path, ~[], id_span); @@ -3191,7 +3325,7 @@ pub impl Parser { let file_path = match ::attr::first_attr_value_str_by_name( attrs, ~"path") { - Some(ref d) => (*d), + Some(d) => copy *d, None => copy *default_path }; self.mod_path_stack.push(file_path) @@ -3205,16 +3339,16 @@ pub impl Parser { outer_attrs: ~[ast::attribute], id_sp: span) -> (ast::item_, ~[ast::attribute]) { - let prefix = Path(self.sess.cm.span_to_filename(copy self.span)); + let prefix = Path(self.sess.cm.span_to_filename(*self.span)); let prefix = prefix.dir_path(); - let mod_path = Path(".").push_many(self.mod_path_stack); + let mod_path = Path(".").push_many(*self.mod_path_stack); let default_path = self.sess.interner.get(id) + ~".rs"; let file_path = match ::attr::first_attr_value_str_by_name( outer_attrs, ~"path") { - Some(ref d) => { - let path = Path(*d); + Some(d) => { + let path = Path(copy *d); if !path.is_absolute { - mod_path.push(*d) + mod_path.push(copy *d) } else { path } @@ -3240,15 +3374,15 @@ pub impl Parser { let p0 = new_sub_parser_from_file(self.sess, self.cfg, &full_path, id_sp); - let inner_attrs = p0.parse_inner_attrs_and_next(); - let mod_attrs = vec::append(outer_attrs, inner_attrs.inner); - let first_item_outer_attrs = inner_attrs.next; + let (inner, next) = p0.parse_inner_attrs_and_next(); + let mod_attrs = vec::append(outer_attrs, inner); + let first_item_outer_attrs = next; let m0 = p0.parse_mod_items(token::EOF, first_item_outer_attrs); return (ast::item_mod(m0), mod_attrs); fn cdir_path_opt(default: ~str, attrs: ~[ast::attribute]) -> ~str { match ::attr::first_attr_value_str_by_name(attrs, ~"path") { - Some(ref d) => (*d), + Some(d) => copy *d, None => default } } @@ -3258,13 +3392,13 @@ pub impl Parser { let lo = self.span.lo; let vis = self.parse_visibility(); let purity = self.parse_fn_purity(); - let t = self.parse_fn_header(); + let (ident, tps) = self.parse_fn_header(); let decl = self.parse_fn_decl(|p| p.parse_arg()); let mut hi = self.span.hi; self.expect(token::SEMI); - @ast::foreign_item { ident: t.ident, + @ast::foreign_item { ident: ident, attrs: attrs, - node: foreign_item_fn(decl, purity, t.tps), + node: foreign_item_fn(decl, purity, tps), id: self.get_id(), span: mk_sp(lo, hi), vis: vis } @@ -3302,9 +3436,9 @@ pub impl Parser { fn parse_foreign_item(+attrs: ~[attribute]) -> @foreign_item { let vis = self.parse_visibility(); if self.is_keyword(~"const") { - self.parse_item_foreign_const(vis, move attrs) + self.parse_item_foreign_const(vis, attrs) } else { - self.parse_item_foreign_fn( move attrs) + self.parse_item_foreign_fn(attrs) } } @@ -3313,17 +3447,18 @@ pub impl Parser { +first_item_attrs: ~[attribute]) -> foreign_mod { // Shouldn't be any view items since we've already parsed an item attr - let {attrs_remaining: move attrs_remaining, - view_items: move view_items, - items: _, - foreign_items: move foreign_items} = - self.parse_items_and_view_items(first_item_attrs, + let ParsedItemsAndViewItems { + attrs_remaining: attrs_remaining, + view_items: view_items, + items: _, + foreign_items: foreign_items + } = self.parse_items_and_view_items(first_item_attrs, VIEW_ITEMS_AND_FOREIGN_ITEMS_ALLOWED, true); - let mut items: ~[@foreign_item] = move foreign_items; + let mut items: ~[@foreign_item] = foreign_items; let mut initial_attrs = attrs_remaining; - while self.token != token::RBRACE { + while *self.token != token::RBRACE { let attrs = vec::append(initial_attrs, self.parse_outer_attributes()); initial_attrs = ~[]; @@ -3331,7 +3466,7 @@ pub impl Parser { } ast::foreign_mod { sort: sort, - abi: move abi, + abi: abi, view_items: view_items, items: items } @@ -3345,7 +3480,7 @@ pub impl Parser { // Parse the ABI. let abi_opt; - match self.token { + match *self.token { token::LIT_STR(copy found_abi) => { self.bump(); abi_opt = Some(found_abi); @@ -3359,21 +3494,21 @@ pub impl Parser { if self.is_keyword(~"mod") { must_be_named_mod = true; self.expect_keyword(~"mod"); - } else if self.token != token::LBRACE { - self.span_fatal(copy self.span, + } else if *self.token != token::LBRACE { + self.span_fatal(*self.span, fmt!("expected `{` or `mod` but found %s", - token_to_str(self.reader, self.token))); + token_to_str(self.reader, *self.token))); } - let (sort, ident) = match self.token { + let (sort, ident) = match *self.token { token::IDENT(*) => (ast::named, self.parse_ident()), _ => { if must_be_named_mod { - self.span_fatal(copy self.span, + self.span_fatal(*self.span, fmt!("expected foreign module name but \ found %s", token_to_str(self.reader, - self.token))); + *self.token))); } (ast::anonymous, @@ -3384,28 +3519,24 @@ pub impl Parser { // extern mod { ... } if items_allowed && self.eat(token::LBRACE) { let abi; - match move abi_opt { - Some(move found_abi) => abi = move found_abi, + match abi_opt { + Some(found_abi) => abi = found_abi, None => abi = special_idents::c_abi, } - let extra_attrs = self.parse_inner_attrs_and_next(); - let m = self.parse_foreign_mod_items(sort, - move abi, - extra_attrs.next); + let (inner, next) = self.parse_inner_attrs_and_next(); + let m = self.parse_foreign_mod_items(sort, abi, next); self.expect(token::RBRACE); return iovi_item(self.mk_item(lo, self.last_span.hi, ident, - item_foreign_mod(m), visibility, - maybe_append(attrs, - Some(extra_attrs. - inner)))); + item_foreign_mod(m), visibility, + maybe_append(attrs, Some(inner)))); } match abi_opt { None => {} // OK. Some(_) => { - self.span_err(copy self.span, ~"an ABI may not be specified \ + self.span_err(*self.span, ~"an ABI may not be specified \ here"); } } @@ -3414,27 +3545,27 @@ pub impl Parser { let metadata = self.parse_optional_meta(); self.expect(token::SEMI); iovi_view_item(@ast::view_item { - node: view_item_use(ident, metadata, self.get_id()), + node: view_item_extern_mod(ident, metadata, self.get_id()), attrs: attrs, vis: visibility, span: mk_sp(lo, self.last_span.hi) }) } - fn parse_type_decl() -> {lo: BytePos, ident: ident} { + fn parse_type_decl() -> (BytePos, ident) { let lo = self.last_span.lo; let id = self.parse_ident(); - return {lo: lo, ident: id}; + (lo, id) } fn parse_item_type() -> item_info { - let t = self.parse_type_decl(); + let (_, ident) = self.parse_type_decl(); self.parse_region_param(); let tps = self.parse_ty_params(); self.expect(token::EQ); let ty = self.parse_ty(false); self.expect(token::SEMI); - (t.ident, item_ty(ty, tps), None) + (ident, item_ty(ty, tps), None) } fn parse_region_param() { @@ -3446,7 +3577,7 @@ pub impl Parser { fn parse_struct_def() -> @struct_def { let mut the_dtor: Option<(blk, ~[attribute], codemap::span)> = None; let mut fields: ~[@struct_field] = ~[]; - while self.token != token::RBRACE { + while *self.token != token::RBRACE { match self.parse_class_item() { dtor_decl(ref blk, ref attrs, s) => { match the_dtor { @@ -3492,7 +3623,7 @@ pub impl Parser { let mut all_nullary = true, have_disr = false; let mut common_fields = None; - while self.token != token::RBRACE { + while *self.token != token::RBRACE { let variant_attrs = self.parse_outer_attributes(); let vlo = self.span.lo; @@ -3515,7 +3646,7 @@ pub impl Parser { ident = self.parse_ident(); self.expect(token::LBRACE); let nested_enum_def = self.parse_enum_def(ty_params); - kind = enum_variant_kind(move nested_enum_def); + kind = enum_variant_kind(nested_enum_def); needs_comma = false; } else { ident = self.parse_value_ident(); @@ -3523,7 +3654,7 @@ pub impl Parser { // Parse a struct variant. all_nullary = false; kind = struct_variant_kind(self.parse_struct_def()); - } else if self.token == token::LPAREN { + } else if *self.token == token::LPAREN { all_nullary = false; let arg_tys = self.parse_unspanned_seq( token::LPAREN, token::RPAREN, @@ -3572,7 +3703,7 @@ pub impl Parser { self.parse_region_param(); let ty_params = self.parse_ty_params(); // Newtype syntax - if self.token == token::EQ { + if *self.token == token::EQ { self.bump(); let ty = self.parse_ty(false); self.expect(token::SEMI); @@ -3604,7 +3735,7 @@ pub impl Parser { } fn parse_fn_ty_sigil() -> Option { - match self.token { + match *self.token { token::AT => { self.bump(); Some(ManagedSigil) @@ -3630,6 +3761,8 @@ pub impl Parser { } } + // parse one of the items or view items allowed by the + // flags; on failure, return iovi_none. fn parse_item_or_view_item(+attrs: ~[attribute], items_allowed: bool, foreign_items_allowed: bool, macros_allowed: bool) @@ -3649,14 +3782,17 @@ pub impl Parser { } if items_allowed && self.eat_keyword(~"const") { + // CONST ITEM let (ident, item_, extra_attrs) = self.parse_item_const(); return iovi_item(self.mk_item(lo, self.last_span.hi, ident, item_, visibility, maybe_append(attrs, extra_attrs))); } else if foreign_items_allowed && self.is_keyword(~"const") { + // FOREIGN CONST ITEM let item = self.parse_item_foreign_const(visibility, attrs); return iovi_foreign_item(item); } else if items_allowed && + // FUNCTION ITEM (not sure about lookahead condition...) self.is_keyword(~"fn") && !self.fn_expr_lookahead(self.look_ahead(1u)) { self.bump(); @@ -3665,6 +3801,7 @@ pub impl Parser { visibility, maybe_append(attrs, extra_attrs))); } else if items_allowed && self.eat_keyword(~"pure") { + // PURE FUNCTION ITEM self.expect_keyword(~"fn"); let (ident, item_, extra_attrs) = self.parse_item_fn(pure_fn); return iovi_item(self.mk_item(lo, self.last_span.hi, ident, item_, @@ -3673,10 +3810,12 @@ pub impl Parser { } else if foreign_items_allowed && (self.is_keyword(~"fn") || self.is_keyword(~"pure") || self.is_keyword(~"unsafe")) { + // FOREIGN FUNCTION ITEM (no items allowed) let item = self.parse_item_foreign_fn(attrs); return iovi_foreign_item(item); } else if items_allowed && self.is_keyword(~"unsafe") && self.look_ahead(1u) != token::LBRACE { + // UNSAFE FUNCTION ITEM (where items are allowed) self.bump(); self.expect_keyword(~"fn"); let (ident, item_, extra_attrs) = self.parse_item_fn(unsafe_fn); @@ -3685,6 +3824,7 @@ pub impl Parser { maybe_append(attrs, extra_attrs))); } else if self.eat_keyword(~"extern") { if items_allowed && self.eat_keyword(~"fn") { + // EXTERN FUNCTION ITEM let (ident, item_, extra_attrs) = self.parse_item_fn(extern_fn); return iovi_item(self.mk_item(lo, self.last_span.hi, ident, @@ -3692,39 +3832,47 @@ pub impl Parser { maybe_append(attrs, extra_attrs))); } + // EXTERN MODULE ITEM return self.parse_item_foreign_mod(lo, visibility, attrs, items_allowed); } else if items_allowed && self.eat_keyword(~"mod") { + // MODULE ITEM let (ident, item_, extra_attrs) = self.parse_item_mod(attrs); return iovi_item(self.mk_item(lo, self.last_span.hi, ident, item_, visibility, maybe_append(attrs, extra_attrs))); } else if items_allowed && self.eat_keyword(~"type") { + // TYPE ITEM let (ident, item_, extra_attrs) = self.parse_item_type(); return iovi_item(self.mk_item(lo, self.last_span.hi, ident, item_, visibility, maybe_append(attrs, extra_attrs))); } else if items_allowed && self.eat_keyword(~"enum") { + // ENUM ITEM let (ident, item_, extra_attrs) = self.parse_item_enum(); return iovi_item(self.mk_item(lo, self.last_span.hi, ident, item_, visibility, maybe_append(attrs, extra_attrs))); } else if items_allowed && self.eat_keyword(~"trait") { + // TRAIT ITEM let (ident, item_, extra_attrs) = self.parse_item_trait(); return iovi_item(self.mk_item(lo, self.last_span.hi, ident, item_, visibility, maybe_append(attrs, extra_attrs))); } else if items_allowed && self.eat_keyword(~"impl") { + // IMPL ITEM let (ident, item_, extra_attrs) = self.parse_item_impl(); return iovi_item(self.mk_item(lo, self.last_span.hi, ident, item_, visibility, maybe_append(attrs, extra_attrs))); } else if items_allowed && self.eat_keyword(~"struct") { + // STRUCT ITEM let (ident, item_, extra_attrs) = self.parse_item_struct(); return iovi_item(self.mk_item(lo, self.last_span.hi, ident, item_, visibility, maybe_append(attrs, extra_attrs))); } else if self.eat_keyword(~"use") { + // USE ITEM let view_item = self.parse_use(); self.expect(token::SEMI); return iovi_view_item(@ast::view_item { @@ -3733,11 +3881,12 @@ pub impl Parser { vis: visibility, span: mk_sp(lo, self.last_span.hi) }); - } else if macros_allowed && !self.is_any_keyword(copy self.token) + } else if macros_allowed && !self.is_any_keyword(*self.token) && self.look_ahead(1) == token::NOT && (is_plain_ident(self.look_ahead(2)) || self.look_ahead(2) == token::LPAREN || self.look_ahead(2) == token::LBRACE) { + // MACRO INVOCATION ITEM if attrs.len() > 0 { self.fatal(~"attrs on macros are not yet supported"); } @@ -3749,20 +3898,22 @@ pub impl Parser { // a 'special' identifier (like what `macro_rules!` uses) // is optional. We should eventually unify invoc syntax // and remove this. - let id = if is_plain_ident(self.token) { + let id = if is_plain_ident(*self.token) { self.parse_ident() } else { token::special_idents::invalid // no special identifier }; - let tts = match self.token { + // eat a matched-delimiter token tree: + let tts = match *self.token { token::LPAREN | token::LBRACE => { - let ket = token::flip_delimiter(copy self.token); - self.parse_unspanned_seq(copy self.token, ket, + let ket = token::flip_delimiter(*self.token); + self.parse_unspanned_seq(*self.token, ket, seq_sep_none(), |p| p.parse_token_tree()) } _ => self.fatal(~"expected open delimiter") }; + // single-variant-enum... : let m = ast::mac_invoc_tt(pth, tts); let m: ast::mac = codemap::spanned { node: m, span: mk_sp(self.span.lo, @@ -3771,11 +3922,12 @@ pub impl Parser { return iovi_item(self.mk_item(lo, self.last_span.hi, id, item_, visibility, attrs)); } else { + // FAILURE TO PARSE ITEM if visibility != inherited { let mut s = ~"unmatched visibility `"; s += if visibility == public { ~"pub" } else { ~"priv" }; s += ~"`"; - self.span_fatal(copy self.last_span, s); + self.span_fatal(*self.last_span, s); } return iovi_none; }; @@ -3795,7 +3947,7 @@ pub impl Parser { } fn parse_use() -> view_item_ { - return view_item_import(self.parse_view_paths()); + return view_item_use(self.parse_view_paths()); } fn parse_view_path() -> @view_path { @@ -3811,12 +3963,12 @@ pub impl Parser { let first_ident = self.parse_ident(); let mut path = ~[first_ident]; debug!("parsed view_path: %s", *self.id_to_str(first_ident)); - match self.token { + match *self.token { token::EQ => { // x = foo::bar self.bump(); path = ~[self.parse_ident()]; - while self.token == token::MOD_SEP { + while *self.token == token::MOD_SEP { self.bump(); let id = self.parse_ident(); path.push(id); @@ -3833,11 +3985,10 @@ pub impl Parser { token::MOD_SEP => { // foo::bar or foo::{a,b,c} or foo::* - while self.token == token::MOD_SEP { + while *self.token == token::MOD_SEP { self.bump(); - match copy self.token { - + match *self.token { token::IDENT(i, _) => { self.bump(); path.push(i); @@ -3888,7 +4039,7 @@ pub impl Parser { fn parse_view_paths() -> ~[@view_path] { let mut vp = ~[self.parse_view_path()]; - while self.token == token::COMMA { + while *self.token == token::COMMA { self.bump(); vp.push(self.parse_view_path()); } @@ -3898,7 +4049,7 @@ pub impl Parser { fn is_view_item() -> bool { let tok, next_tok; if !self.is_keyword(~"pub") && !self.is_keyword(~"priv") { - tok = self.token; + tok = *self.token; next_tok = self.look_ahead(1); } else { tok = self.look_ahead(1); @@ -3909,6 +4060,7 @@ pub impl Parser { self.token_is_keyword(~"mod", next_tok)) } + // parse a view item. fn parse_view_item(+attrs: ~[attribute], vis: visibility) -> @view_item { let lo = self.span.lo; let node = if self.eat_keyword(~"use") { @@ -3917,9 +4069,9 @@ pub impl Parser { self.expect_keyword(~"mod"); let ident = self.parse_ident(); let metadata = self.parse_optional_meta(); - view_item_use(ident, metadata, self.get_id()) + view_item_extern_mod(ident, metadata, self.get_id()) } else { - fail!(); + self.bug(~"expected view item"); }; self.expect(token::SEMI); @ast::view_item { node: node, @@ -3928,13 +4080,12 @@ pub impl Parser { span: mk_sp(lo, self.last_span.hi) } } + // Parses a sequence of items. Stops when it finds program + // text that can't be parsed as an item fn parse_items_and_view_items(+first_item_attrs: ~[attribute], mode: view_item_parse_mode, macros_allowed: bool) - -> {attrs_remaining: ~[attribute], - view_items: ~[@view_item], - items: ~[@item], - foreign_items: ~[@foreign_item]} { + -> ParsedItemsAndViewItems { let mut attrs = vec::append(first_item_attrs, self.parse_outer_attributes()); @@ -3954,7 +4105,7 @@ pub impl Parser { VIEW_ITEMS_AND_ITEMS_ALLOWED | IMPORTS_AND_ITEMS_ALLOWED => false }; - let (view_items, items, foreign_items) = (DVec(), DVec(), DVec()); + let mut (view_items, items, foreign_items) = (~[], ~[], ~[]); loop { match self.parse_item_or_view_item(attrs, items_allowed, foreign_items_allowed, @@ -3964,8 +4115,8 @@ pub impl Parser { iovi_view_item(view_item) => { if restricted_to_imports { match view_item.node { - view_item_import(_) => {} - view_item_use(*) => + view_item_use(*) => {} + view_item_extern_mod(*) => self.fatal(~"\"extern mod\" \ declarations are not \ allowed here") @@ -3985,26 +4136,31 @@ pub impl Parser { attrs = self.parse_outer_attributes(); } - {attrs_remaining: attrs, - view_items: dvec::unwrap(move view_items), - items: dvec::unwrap(move items), - foreign_items: dvec::unwrap(move foreign_items)} + ParsedItemsAndViewItems { + attrs_remaining: attrs, + view_items: view_items, + items: items, + foreign_items: foreign_items + } } // Parses a source module as a crate fn parse_crate_mod(_cfg: crate_cfg) -> @crate { let lo = self.span.lo; - let crate_attrs = self.parse_inner_attrs_and_next(); - let first_item_outer_attrs = crate_attrs.next; + // parse the crate's inner attrs, maybe (oops) one + // of the attrs of an item: + let (inner, next) = self.parse_inner_attrs_and_next(); + let first_item_outer_attrs = next; + // parse the items inside the crate: let m = self.parse_mod_items(token::EOF, first_item_outer_attrs); @spanned(lo, self.span.lo, ast::crate_ { module: m, - attrs: crate_attrs.inner, + attrs: inner, config: self.cfg }) } fn parse_str() -> @~str { - match copy self.token { + match *self.token { token::LIT_STR(s) => { self.bump(); self.id_to_str(s) } _ => self.fatal(~"expected string literal") } diff --git a/src/libsyntax/parse/token.rs b/src/libsyntax/parse/token.rs index 3279c79e5af0d..f145e433fa7c1 100644 --- a/src/libsyntax/parse/token.rs +++ b/src/libsyntax/parse/token.rs @@ -429,7 +429,7 @@ pub fn mk_ident_interner() -> @ident_interner { ]; let rv = @ident_interner { - interner: interner::mk_prefill(init_vec) + interner: interner::Interner::prefill(init_vec) }; task::local_data::local_data_set(interner_key!(), @rv); @@ -443,7 +443,7 @@ pub fn mk_ident_interner() -> @ident_interner { /* for when we don't care about the contents; doesn't interact with TLD or serialization */ pub fn mk_fake_ident_interner() -> @ident_interner { - @ident_interner { interner: interner::mk::<@~str>() } + @ident_interner { interner: interner::Interner::new() } } /** @@ -493,7 +493,7 @@ pub fn strict_keyword_table() -> HashMap<~str, ()> { ~"false", ~"fn", ~"for", ~"if", ~"impl", ~"let", ~"log", ~"loop", - ~"match", ~"mod", ~"move", ~"mut", + ~"match", ~"mod", ~"mut", ~"once", ~"priv", ~"pub", ~"pure", ~"ref", ~"return", diff --git a/src/libsyntax/print/pp.rs b/src/libsyntax/print/pp.rs index aeebcce1f2b27..402c7c2663465 100644 --- a/src/libsyntax/print/pp.rs +++ b/src/libsyntax/print/pp.rs @@ -72,9 +72,15 @@ use core::vec; #[deriving_eq] pub enum breaks { consistent, inconsistent, } -pub type break_t = {offset: int, blank_space: int}; +pub struct break_t { + offset: int, + blank_space: int +} -pub type begin_t = {offset: int, breaks: breaks}; +pub struct begin_t { + offset: int, + breaks: breaks +} pub enum token { STRING(@~str, int), @@ -90,7 +96,10 @@ pub impl token { } fn is_hardbreak_tok(&self) -> bool { match *self { - BREAK({offset: 0, blank_space: bs }) if bs == size_infinity => + BREAK(break_t { + offset: 0, + blank_space: bs + }) if bs == size_infinity => true, _ => false @@ -128,7 +137,10 @@ pub fn buf_str(toks: ~[token], szs: ~[int], left: uint, right: uint, pub enum print_stack_break { fits, broken(breaks), } -pub type print_stack_elt = {offset: int, pbreak: print_stack_break}; +pub struct print_stack_elt { + offset: int, + pbreak: print_stack_break +} pub const size_infinity: int = 0xffff; @@ -147,11 +159,11 @@ pub fn mk_printer(out: @io::Writer, linewidth: uint) -> @mut Printer { space: linewidth as int, left: 0, right: 0, - token: move token, - size: move size, + token: token, + size: size, left_total: 0, right_total: 0, - scan_stack: move scan_stack, + scan_stack: scan_stack, scan_stack_empty: true, top: 0, bottom: 0, @@ -445,7 +457,10 @@ pub impl Printer { if n != 0u { self.print_stack[n - 1u] } else { - {offset: 0, pbreak: broken(inconsistent)} + print_stack_elt { + offset: 0, + pbreak: broken(inconsistent) + } } } fn print_str(&mut self, s: ~str) { @@ -468,12 +483,16 @@ pub impl Printer { if L > self.space { let col = self.margin - self.space + b.offset; debug!("print BEGIN -> push broken block at col %d", col); - self.print_stack.push({offset: col, - pbreak: broken(b.breaks)}); + self.print_stack.push(print_stack_elt { + offset: col, + pbreak: broken(b.breaks) + }); } else { debug!("print BEGIN -> push fitting block"); - self.print_stack.push({offset: 0, - pbreak: fits}); + self.print_stack.push(print_stack_elt { + offset: 0, + pbreak: fits + }); } } END => { @@ -527,7 +546,10 @@ pub impl Printer { // Convenience functions to talk to the printer. pub fn box(p: @mut Printer, indent: uint, b: breaks) { - p.pretty_print(BEGIN({offset: indent as int, breaks: b})); + p.pretty_print(BEGIN(begin_t { + offset: indent as int, + breaks: b + })); } pub fn ibox(p: @mut Printer, indent: uint) { box(p, indent, inconsistent); } @@ -535,7 +557,10 @@ pub fn ibox(p: @mut Printer, indent: uint) { box(p, indent, inconsistent); } pub fn cbox(p: @mut Printer, indent: uint) { box(p, indent, consistent); } pub fn break_offset(p: @mut Printer, n: uint, off: int) { - p.pretty_print(BREAK({offset: off, blank_space: n as int})); + p.pretty_print(BREAK(break_t { + offset: off, + blank_space: n as int + })); } pub fn end(p: @mut Printer) { p.pretty_print(END); } @@ -563,7 +588,7 @@ pub fn space(p: @mut Printer) { spaces(p, 1u); } pub fn hardbreak(p: @mut Printer) { spaces(p, size_infinity as uint); } pub fn hardbreak_tok_offset(off: int) -> token { - return BREAK({offset: off, blank_space: size_infinity}); + BREAK(break_t {offset: off, blank_space: size_infinity}) } pub fn hardbreak_tok() -> token { return hardbreak_tok_offset(0); } diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index b05461aa8d98f..d5a09e087a02e 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -108,17 +108,18 @@ pub fn print_crate(cm: @CodeMap, intr: @ident_interner, span_diagnostic: diagnostic::span_handler, crate: @ast::crate, filename: ~str, in: io::Reader, out: io::Writer, ann: pp_ann, is_expanded: bool) { - let r = comments::gather_comments_and_literals(span_diagnostic, - filename, in); + let (cmnts, lits) = + comments::gather_comments_and_literals(span_diagnostic, + filename, in); let s = @ps { s: pp::mk_printer(out, default_columns), cm: Some(cm), intr: intr, - comments: Some(r.cmnts), + comments: Some(cmnts), // If the code is post expansion, don't use the table of // literals, since it doesn't correspond with the literals // in the AST anymore. - literals: if is_expanded { None } else { Some(r.lits) }, + literals: if is_expanded { None } else { Some(lits) }, cur_cmnt_and_lit: @mut CurrentCommentAndLiteral { cur_cmnt: 0, cur_lit: 0 @@ -414,6 +415,9 @@ pub fn print_type_ex(s: @ps, &&ty: @ast::Ty, print_colons: bool) { ast::ty_tup(elts) => { popen(s); commasep(s, inconsistent, elts, print_type); + if elts.len() == 1 { + word(s.s, ~","); + } pclose(s); } ast::ty_bare_fn(f) => { @@ -495,9 +499,16 @@ pub fn print_item(s: @ps, &&item: @ast::item) { end(s); // end the outer cbox } - ast::item_fn(decl, purity, typarams, ref body) => { - print_fn(s, decl, Some(purity), item.ident, typarams, None, - item.vis); + ast::item_fn(ref decl, purity, ref typarams, ref body) => { + print_fn( + s, + /* FIXME (#2543) */ copy *decl, + Some(purity), + item.ident, + /* FIXME (#2543) */ copy *typarams, + None, + item.vis + ); word(s.s, ~" "); print_block_with_attrs(s, (*body), item.attrs); } @@ -539,9 +550,15 @@ pub fn print_item(s: @ps, &&item: @ast::item) { word(s.s, ~";"); end(s); // end the outer ibox } - ast::item_enum(ref enum_definition, params) => { - print_enum_def(s, (*enum_definition), params, item.ident, - item.span, item.vis); + ast::item_enum(ref enum_definition, ref params) => { + print_enum_def( + s, + *enum_definition, + /* FIXME (#2543) */ copy *params, + item.ident, + item.span, + item.vis + ); } ast::item_struct(struct_def, tps) => { head(s, visibility_qualified(item.vis, ~"struct")); @@ -577,13 +594,13 @@ pub fn print_item(s: @ps, &&item: @ast::item) { bclose(s, item.span); } } - ast::item_trait(tps, traits, ref methods) => { + ast::item_trait(ref tps, ref traits, ref methods) => { head(s, visibility_qualified(item.vis, ~"trait")); print_ident(s, item.ident); - print_type_params(s, tps); - if vec::len(traits) != 0u { + print_type_params(s, /* FIXME (#2543) */ copy *tps); + if traits.len() != 0u { word(s.s, ~":"); - for vec::each(traits) |trait_| { + for traits.each |trait_| { nbsp(s); print_path(s, trait_.path, false); } @@ -619,7 +636,7 @@ pub fn print_enum_def(s: @ps, enum_definition: ast::enum_def, ident == enum_definition.variants[0].node.name; if newtype { match enum_definition.variants[0].node.kind { - ast::tuple_variant_kind(args) if args.len() == 1 => {} + ast::tuple_variant_kind(ref args) if args.len() == 1 => {} _ => newtype = false } } @@ -884,7 +901,7 @@ pub fn print_attribute(s: @ps, attr: ast::attribute) { if attr.node.is_sugared_doc { let meta = attr::attr_meta(attr); let comment = attr::get_meta_item_value_str(meta).get(); - word(s.s, comment); + word(s.s, *comment); } else { word(s.s, ~"#["); print_meta_item(s, @attr.node.value); @@ -1199,6 +1216,9 @@ pub fn print_expr(s: @ps, &&expr: @ast::expr) { ast::expr_tup(exprs) => { popen(s); commasep_exprs(s, inconsistent, exprs); + if exprs.len() == 1 { + word(s.s, ~","); + } pclose(s); } ast::expr_call(func, args, sugar) => { @@ -1325,24 +1345,24 @@ pub fn print_expr(s: @ps, &&expr: @ast::expr) { } bclose_(s, expr.span, match_indent_unit); } - ast::expr_fn(sigil, decl, ref body, _) => { + ast::expr_fn(sigil, ref decl, ref body, _) => { // containing cbox, will be closed by print-block at } cbox(s, indent_unit); // head-box, will be closed by print-block at start ibox(s, 0u); print_fn_header_info(s, None, None, ast::Many, Some(sigil), ast::inherited); - print_fn_args_and_ret(s, decl, None); + print_fn_args_and_ret(s, /* FIXME (#2543) */ copy *decl, None); space(s.s); print_block(s, (*body)); } - ast::expr_fn_block(decl, ref body) => { + ast::expr_fn_block(ref decl, ref body) => { // in do/for blocks we don't want to show an empty // argument list, but at this point we don't know which // we are inside. // // if !decl.inputs.is_empty() { - print_fn_block_args(s, decl); + print_fn_block_args(s, /* FIXME (#2543) */ copy *decl); space(s.s); // } assert (*body).node.stmts.is_empty(); @@ -1634,6 +1654,9 @@ pub fn print_pat(s: @ps, &&pat: @ast::pat, refutable: bool) { ast::pat_tup(elts) => { popen(s); commasep(s, inconsistent, elts, |s, p| print_pat(s, p, refutable)); + if elts.len() == 1 { + word(s.s, ~","); + } pclose(s); } ast::pat_box(inner) => { @@ -1803,16 +1826,21 @@ pub fn print_type_params(s: @ps, &¶ms: ~[ast::ty_param]) { pub fn print_meta_item(s: @ps, &&item: @ast::meta_item) { ibox(s, indent_unit); match item.node { - ast::meta_word(ref name) => word(s.s, (*name)), - ast::meta_name_value(ref name, value) => { - word_space(s, (*name)); + ast::meta_word(name) => word(s.s, *name), + ast::meta_name_value(name, value) => { + word_space(s, *name); word_space(s, ~"="); print_literal(s, @value); } - ast::meta_list(ref name, items) => { - word(s.s, (*name)); + ast::meta_list(name, ref items) => { + word(s.s, *name); popen(s); - commasep(s, consistent, items, print_meta_item); + commasep( + s, + consistent, + /* FIXME (#2543) */ copy *items, + print_meta_item + ); pclose(s); } } @@ -1859,7 +1887,7 @@ pub fn print_view_item(s: @ps, item: @ast::view_item) { print_outer_attributes(s, item.attrs); print_visibility(s, item.vis); match item.node { - ast::view_item_use(id, mta, _) => { + ast::view_item_extern_mod(id, mta, _) => { head(s, ~"extern mod"); print_ident(s, id); if !mta.is_empty() { @@ -1869,7 +1897,7 @@ pub fn print_view_item(s: @ps, item: @ast::view_item) { } } - ast::view_item_import(vps) => { + ast::view_item_use(vps) => { head(s, ~"use"); print_view_paths(s, vps); } @@ -2255,7 +2283,7 @@ pub mod test { //use util; use util::testing::check_equal; - fn string_check (given : &T, expected: &T) { + fn string_check (given : &T, expected: &T) { if !(given == expected) { fail!(fmt!("given %?, expected %?",given,expected)); } diff --git a/src/libsyntax/syntax.rc b/src/libsyntax/syntax.rc index 877817af06c18..05bbe43ee9abf 100644 --- a/src/libsyntax/syntax.rc +++ b/src/libsyntax/syntax.rc @@ -17,7 +17,6 @@ #[crate_type = "lib"]; #[legacy_modes]; -#[legacy_records]; #[allow(vecs_implicitly_copyable)]; #[allow(non_camel_case_types)]; diff --git a/src/libsyntax/util/interner.rs b/src/libsyntax/util/interner.rs index 905571d181721..41500d6a409a8 100644 --- a/src/libsyntax/util/interner.rs +++ b/src/libsyntax/util/interner.rs @@ -14,72 +14,66 @@ use core::prelude::*; -use core::dvec::DVec; -use std::oldmap::HashMap; -use std::oldmap; +use hashmap::linear::LinearMap; +use dvec::DVec; -pub type hash_interner = {map: HashMap, vect: DVec}; - -pub fn mk() -> Interner { - let m = oldmap::HashMap::(); - let hi: hash_interner = - {map: m, vect: DVec()}; - move ((move hi) as Interner::) -} - -pub fn mk_prefill(init: &[T]) -> Interner { - let rv = mk(); - for init.each() |v| { rv.intern(*v); } - return rv; +pub struct Interner { + priv map: @mut LinearMap, + priv vect: DVec, } +// when traits can extend traits, we should extend index to get [] +pub impl Interner { + static fn new() -> Interner { + Interner { + map: @mut LinearMap::new(), + vect: DVec(), + } + } -/* when traits can extend traits, we should extend index to get [] */ -pub trait Interner { - fn intern(T) -> uint; - fn gensym(T) -> uint; - pure fn get(uint) -> T; - fn len() -> uint; -} + static fn prefill(init: &[T]) -> Interner { + let rv = Interner::new(); + for init.each() |v| { rv.intern(*v); } + rv + } -pub impl hash_interner: Interner { - fn intern(val: T) -> uint { + fn intern(&self, val: T) -> uint { match self.map.find(&val) { - Some(idx) => return idx, - None => { - let new_idx = self.vect.len(); - self.map.insert(val, new_idx); - self.vect.push(val); - return new_idx; - } + Some(&idx) => return idx, + None => (), } + + let new_idx = self.vect.len(); + self.map.insert(val, new_idx); + self.vect.push(val); + new_idx } - fn gensym(val: T) -> uint { + + fn gensym(&self, val: T) -> uint { let new_idx = self.vect.len(); // leave out of .map to avoid colliding self.vect.push(val); - return new_idx; + new_idx } // 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(idx: uint) -> T { self.vect.get_elt(idx) } + pure fn get(&self, idx: uint) -> T { self.vect.get_elt(idx) } - fn len() -> uint { return self.vect.len(); } + fn len(&self) -> uint { self.vect.len() } } - #[test] #[should_fail] pub fn i1 () { - let i : Interner<@~str> = mk(); + let i : Interner<@~str> = Interner::new(); i.get(13); } #[test] pub fn i2 () { - let i : Interner<@~str> = mk(); + let i : Interner<@~str> = Interner::new(); // first one is zero: assert i.intern (@~"dog") == 0; // re-use gets the same entry: @@ -104,7 +98,7 @@ pub fn i2 () { #[test] pub fn i3 () { - let i : Interner<@~str> = mk_prefill([@~"Alan",@~"Bob",@~"Carol"]); + let i : Interner<@~str> = Interner::prefill([@~"Alan",@~"Bob",@~"Carol"]); assert i.get(0) == @~"Alan"; assert i.get(1) == @~"Bob"; assert i.get(2) == @~"Carol"; diff --git a/src/libsyntax/util/testing.rs b/src/libsyntax/util/testing.rs index b6d333349a091..78a175df29f27 100644 --- a/src/libsyntax/util/testing.rs +++ b/src/libsyntax/util/testing.rs @@ -11,13 +11,13 @@ // support for test cases. use core::cmp; -pub pure fn check_equal_ptr (given : &T, expected: &T) { +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) { +pub pure fn check_equal (given : T, expected: T) { if !((given == expected) && (expected == given )) { fail!(fmt!("given %?, expected %?",given,expected)); } diff --git a/src/libsyntax/visit.rs b/src/libsyntax/visit.rs index 37b96e0565370..3701607ffc13f 100644 --- a/src/libsyntax/visit.rs +++ b/src/libsyntax/visit.rs @@ -137,11 +137,20 @@ pub fn visit_item(i: @item, e: E, v: vt) { (v.visit_ty)(t, e, v); (v.visit_expr)(ex, e, v); } - item_fn(decl, purity, tp, ref body) => { - (v.visit_fn)(fk_item_fn(/* FIXME (#2543) */ copy i.ident, - /* FIXME (#2543) */ copy tp, - purity), decl, (*body), - i.span, i.id, e, v); + item_fn(ref decl, purity, ref tp, ref body) => { + (v.visit_fn)( + fk_item_fn( + /* FIXME (#2543) */ copy i.ident, + /* FIXME (#2543) */ copy *tp, + purity + ), + /* FIXME (#2543) */ copy *decl, + (*body), + i.span, + i.id, + e, + v + ); } item_mod(m) => (v.visit_mod)(m, i.span, i.id, e, v), item_foreign_mod(nm) => { @@ -152,9 +161,14 @@ pub fn visit_item(i: @item, e: E, v: vt) { (v.visit_ty)(t, e, v); (v.visit_ty_params)(tps, e, v); } - item_enum(ref enum_definition, tps) => { - (v.visit_ty_params)(tps, e, v); - visit_enum_def((*enum_definition), tps, e, v); + item_enum(ref enum_definition, ref tps) => { + (v.visit_ty_params)(/* FIXME (#2543) */ copy *tps, e, v); + visit_enum_def( + *enum_definition, + /* FIXME (#2543) */ copy *tps, + e, + v + ); } item_impl(tps, traits, ty, methods) => { (v.visit_ty_params)(tps, e, v); @@ -170,8 +184,8 @@ pub fn visit_item(i: @item, e: E, v: vt) { (v.visit_ty_params)(tps, e, v); (v.visit_struct_def)(struct_def, i.ident, tps, i.id, e, v); } - item_trait(tps, traits, ref methods) => { - (v.visit_ty_params)(tps, e, v); + item_trait(ref tps, ref traits, ref methods) => { + (v.visit_ty_params)(/* FIXME (#2543) */ copy *tps, e, v); for traits.each |p| { visit_path(p.path, e, v); } for (*methods).each |m| { (v.visit_trait_method)(*m, e, v); @@ -460,13 +474,27 @@ pub fn visit_expr(ex: @expr, e: E, v: vt) { (v.visit_expr)(x, e, v); for (*arms).each |a| { (v.visit_arm)(*a, e, v); } } - expr_fn(proto, decl, ref body, _) => { - (v.visit_fn)(fk_anon(proto), decl, (*body), - ex.span, ex.id, e, v); - } - expr_fn_block(decl, ref body) => { - (v.visit_fn)(fk_fn_block, decl, (*body), - ex.span, ex.id, e, v); + expr_fn(proto, ref decl, ref body, _) => { + (v.visit_fn)( + fk_anon(proto), + /* FIXME (#2543) */ copy *decl, + *body, + ex.span, + ex.id, + e, + v + ); + } + expr_fn_block(ref decl, ref body) => { + (v.visit_fn)( + fk_fn_block, + /* FIXME (#2543) */ copy *decl, + *body, + ex.span, + ex.id, + e, + v + ); } expr_block(ref b) => (v.visit_block)((*b), e, v), expr_assign(a, b) => { diff --git a/src/rt/boxed_region.cpp b/src/rt/boxed_region.cpp index c9734f460c5e3..d159df03dc3c0 100644 --- a/src/rt/boxed_region.cpp +++ b/src/rt/boxed_region.cpp @@ -38,7 +38,10 @@ rust_opaque_box *boxed_region::malloc(type_desc *td, size_t body_size) { rust_opaque_box *boxed_region::realloc(rust_opaque_box *box, size_t new_size) { - assert(box->ref_count == 1); + + // We also get called on the unique-vec-in-managed-heap path. + assert(box->ref_count == 1 || + box->ref_count == (size_t)(-2)); size_t total_size = new_size + sizeof(rust_opaque_box); rust_opaque_box *new_box = @@ -47,7 +50,6 @@ rust_opaque_box *boxed_region::realloc(rust_opaque_box *box, if (new_box->next) new_box->next->prev = new_box; if (live_allocs == box) live_allocs = new_box; - LOG(rust_get_current_task(), box, "@realloc()=%p with orig=%p, size %lu==%lu+%lu", new_box, box, total_size, sizeof(rust_opaque_box), new_size); diff --git a/src/rt/memory_region.cpp b/src/rt/memory_region.cpp index 6307730b0f4b3..6de9d5a1df4a2 100644 --- a/src/rt/memory_region.cpp +++ b/src/rt/memory_region.cpp @@ -121,8 +121,10 @@ memory_region::realloc(void *mem, size_t orig_size) { } void * -memory_region::malloc(size_t size, const char *tag, bool zero) { +memory_region::malloc(size_t size, const char *tag) { +# if RUSTRT_TRACK_ALLOCATIONS >= 1 size_t old_size = size; +# endif size += HEADER_SIZE; alloc_header *mem = (alloc_header *)::malloc(size); if (mem == NULL) { @@ -143,18 +145,9 @@ memory_region::malloc(size_t size, const char *tag, bool zero) { void *data = get_data(mem); claim_alloc(data); - if(zero) { - memset(data, 0, old_size); - } - return data; } -void * -memory_region::calloc(size_t size, const char *tag) { - return malloc(size, tag, true); -} - memory_region::~memory_region() { if (_synchronized) { _lock.lock(); } if (_live_allocations == 0 && !_detailed_leaks) { diff --git a/src/rt/memory_region.h b/src/rt/memory_region.h index 7a68a0f8af548..999a992eefaea 100644 --- a/src/rt/memory_region.h +++ b/src/rt/memory_region.h @@ -77,8 +77,7 @@ class memory_region { public: memory_region(rust_env *env, bool synchronized); memory_region(memory_region *parent); - void *malloc(size_t size, const char *tag, bool zero = true); - void *calloc(size_t size, const char *tag); + void *malloc(size_t size, const char *tag); void *realloc(void *mem, size_t size); void free(void *mem); ~memory_region(); diff --git a/src/rt/rust_builtin.cpp b/src/rt/rust_builtin.cpp index 3f6545caaa8e4..2c5b56f3fa4ef 100644 --- a/src/rt/rust_builtin.cpp +++ b/src/rt/rust_builtin.cpp @@ -128,58 +128,40 @@ vec_reserve_shared(type_desc* ty, rust_vec_box** vp, reserve_vec_exact(task, vp, n_elts * ty->size); } -extern "C" CDECL rust_vec* -rand_seed() { - size_t size = sizeof(ub4) * RANDSIZ; - rust_task *task = rust_get_current_task(); - rust_vec *v = (rust_vec *) task->kernel->malloc(vec_size(size), - "rand_seed"); - v->fill = v->alloc = size; - isaac_seed(task->kernel, (uint8_t*) &v->data, size); - return v; +extern "C" CDECL size_t +rand_seed_size() { + return rng_seed_size(); } -extern "C" CDECL void * -rand_new() { +extern "C" CDECL void +rand_gen_seed(uint8_t* dest, size_t size) { rust_task *task = rust_get_current_task(); - rust_sched_loop *thread = task->sched_loop; - randctx *rctx = (randctx *) task->malloc(sizeof(randctx), "rand_new"); - if (!rctx) { - task->fail(); - return NULL; - } - isaac_init(thread->kernel, rctx, NULL); - return rctx; + rng_gen_seed(task->kernel, dest, size); } extern "C" CDECL void * -rand_new_seeded(rust_vec_box* seed) { +rand_new_seeded(uint8_t* seed, size_t seed_size) { rust_task *task = rust_get_current_task(); - rust_sched_loop *thread = task->sched_loop; - randctx *rctx = (randctx *) task->malloc(sizeof(randctx), - "rand_new_seeded"); - if (!rctx) { + rust_rng *rng = (rust_rng *) task->malloc(sizeof(rust_rng), + "rand_new_seeded"); + if (!rng) { task->fail(); return NULL; } - isaac_init(thread->kernel, rctx, seed); - return rctx; -} - -extern "C" CDECL void * -rand_new_seeded2(rust_vec_box** seed) { - return rand_new_seeded(*seed); + rng_init(task->kernel, rng, seed, seed_size); + return rng; } -extern "C" CDECL size_t -rand_next(randctx *rctx) { - return isaac_rand(rctx); +extern "C" CDECL uint32_t +rand_next(rust_rng *rng) { + rust_task *task = rust_get_current_task(); + return rng_gen_u32(task->kernel, rng); } extern "C" CDECL void -rand_free(randctx *rctx) { +rand_free(rust_rng *rng) { rust_task *task = rust_get_current_task(); - task->free(rctx); + task->free(rng); } diff --git a/src/rt/rust_exchange_alloc.cpp b/src/rt/rust_exchange_alloc.cpp index 6c0204ca73611..a92bc4edd411a 100644 --- a/src/rt/rust_exchange_alloc.cpp +++ b/src/rt/rust_exchange_alloc.cpp @@ -18,23 +18,15 @@ uintptr_t exchange_count = 0; void * -rust_exchange_alloc::malloc(size_t size, bool zero) { +rust_exchange_alloc::malloc(size_t size) { void *value = ::malloc(size); assert(value); - if (zero) { - memset(value, 0, size); - } sync::increment(exchange_count); return value; } -void * -rust_exchange_alloc::calloc(size_t size) { - return this->malloc(size); -} - void * rust_exchange_alloc::realloc(void *ptr, size_t size) { void *new_ptr = ::realloc(ptr, size); diff --git a/src/rt/rust_exchange_alloc.h b/src/rt/rust_exchange_alloc.h index 1b52929acf1b7..767caf0132345 100644 --- a/src/rt/rust_exchange_alloc.h +++ b/src/rt/rust_exchange_alloc.h @@ -16,8 +16,7 @@ class rust_exchange_alloc { public: - void *malloc(size_t size, bool zero = true); - void *calloc(size_t size); + void *malloc(size_t size); void *realloc(void *mem, size_t size); void free(void *mem); }; diff --git a/src/rt/rust_globals.h b/src/rt/rust_globals.h index d0116fe27813d..3d3ce7562b5ed 100644 --- a/src/rt/rust_globals.h +++ b/src/rt/rust_globals.h @@ -37,9 +37,6 @@ #include #include -#include "rand.h" -#include "uthash.h" - #if defined(__WIN32__) extern "C" { #include diff --git a/src/rt/rust_kernel.cpp b/src/rt/rust_kernel.cpp index 6b7a82414161c..4d2d6ad344cc9 100644 --- a/src/rt/rust_kernel.cpp +++ b/src/rt/rust_kernel.cpp @@ -79,11 +79,6 @@ rust_kernel::malloc(size_t size, const char *tag) { return exchange_alloc.malloc(size); } -void * -rust_kernel::calloc(size_t size, const char *tag) { - return exchange_alloc.calloc(size); -} - void * rust_kernel::realloc(void *mem, size_t size) { return exchange_alloc.realloc(mem, size); diff --git a/src/rt/rust_kernel.h b/src/rt/rust_kernel.h index 01ebf5ab57b95..ec0515faeafc0 100644 --- a/src/rt/rust_kernel.h +++ b/src/rt/rust_kernel.h @@ -49,7 +49,6 @@ #include "rust_log.h" #include "rust_sched_reaper.h" #include "rust_type.h" -#include "util/hash_map.h" #include "sync/lock_and_signal.h" class rust_scheduler; @@ -133,7 +132,6 @@ class rust_kernel { void fatal(char const *fmt, ...); void *malloc(size_t size, const char *tag); - void *calloc(size_t size, const char *tag); void *realloc(void *mem, size_t size); void free(void *mem); rust_exchange_alloc *region() { return &exchange_alloc; } diff --git a/src/rt/rust_rng.cpp b/src/rt/rust_rng.cpp new file mode 100644 index 0000000000000..2c11691bf86b9 --- /dev/null +++ b/src/rt/rust_rng.cpp @@ -0,0 +1,120 @@ +// 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. + +#include "rust_globals.h" +#include "rust_rng.h" +#include "rust_util.h" + +size_t +rng_seed_size() { + randctx rctx; + return sizeof(rctx.randrsl); +} + +// Initialization helpers for ISAAC RNG + +void +rng_gen_seed(rust_kernel* kernel, uint8_t* dest, size_t size) { +#ifdef __WIN32__ + HCRYPTPROV hProv; + kernel->win32_require + (_T("CryptAcquireContext"), + CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_FULL, + CRYPT_VERIFYCONTEXT|CRYPT_SILENT)); + kernel->win32_require + (_T("CryptGenRandom"), CryptGenRandom(hProv, size, (BYTE*) dest)); + kernel->win32_require + (_T("CryptReleaseContext"), CryptReleaseContext(hProv, 0)); +#else + int fd = open("/dev/urandom", O_RDONLY); + if (fd == -1) + kernel->fatal("error opening /dev/urandom: %s", strerror(errno)); + size_t amount = 0; + do { + ssize_t ret = read(fd, dest+amount, size-amount); + if (ret < 0) + kernel->fatal("error reading /dev/urandom: %s", strerror(errno)); + else if (ret == 0) + kernel->fatal("somehow hit eof reading from /dev/urandom"); + amount += (size_t)ret; + } while (amount < size); + int ret = close(fd); + // FIXME #3697: Why does this fail sometimes? + if (ret != 0) + kernel->log(log_warn, "error closing /dev/urandom: %s", + strerror(errno)); +#endif +} + +static void +isaac_init(rust_kernel *kernel, randctx *rctx, + uint8_t* user_seed, size_t seed_len) { + memset(rctx, 0, sizeof(randctx)); + + char *env_seed = kernel->env->rust_seed; + if (user_seed != NULL) { + // ignore bytes after the required length + if (seed_len > sizeof(rctx->randrsl)) { + seed_len = sizeof(rctx->randrsl); + } + memcpy(&rctx->randrsl, user_seed, seed_len); + } else if (env_seed != NULL) { + ub4 seed = (ub4) atoi(env_seed); + for (size_t i = 0; i < RANDSIZ; i ++) { + memcpy(&rctx->randrsl[i], &seed, sizeof(ub4)); + seed = (seed + 0x7ed55d16) + (seed << 12); + } + } else { + rng_gen_seed(kernel, + (uint8_t*)&rctx->randrsl, + sizeof(rctx->randrsl)); + } + + randinit(rctx, 1); +} + +void +rng_init(rust_kernel* kernel, rust_rng* rng, + uint8_t *user_seed, size_t seed_len) { + isaac_init(kernel, &rng->rctx, user_seed, seed_len); + rng->reseedable = !user_seed && !kernel->env->rust_seed; +} + +static void +rng_maybe_reseed(rust_kernel* kernel, rust_rng* rng) { + // If this RNG has generated more than 32KB of random data and was not + // seeded by the user or RUST_SEED, then we should reseed now. + const size_t RESEED_THRESHOLD = 32 * 1024; + size_t bytes_generated = rng->rctx.randc * sizeof(ub4); + if (bytes_generated < RESEED_THRESHOLD || !rng->reseedable) { + return; + } + rng_gen_seed(kernel, + (uint8_t*)rng->rctx.randrsl, + sizeof(rng->rctx.randrsl)); + randinit(&rng->rctx, 1); +} + +uint32_t +rng_gen_u32(rust_kernel* kernel, rust_rng* rng) { + uint32_t x = isaac_rand(&rng->rctx); + rng_maybe_reseed(kernel, rng); + return x; +} + +// +// Local Variables: +// mode: C++ +// fill-column: 78; +// indent-tabs-mode: nil +// c-basic-offset: 4 +// buffer-file-coding-system: utf-8-unix +// End: +// diff --git a/src/rt/rust_rng.h b/src/rt/rust_rng.h new file mode 100644 index 0000000000000..3879b1138fa20 --- /dev/null +++ b/src/rt/rust_rng.h @@ -0,0 +1,42 @@ +// 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. + +#ifndef RUST_RNG_H +#define RUST_RNG_H + +#include "rand.h" + +class rust_kernel; + +// Initialization helpers for ISAAC RNG + +struct rust_rng { + randctx rctx; + bool reseedable; +}; + +size_t rng_seed_size(); +void rng_gen_seed(rust_kernel* kernel, + uint8_t* dest, size_t size); +void rng_init(rust_kernel *kernel, rust_rng *rng, + uint8_t *user_seed, size_t seed_len); +uint32_t rng_gen_u32(rust_kernel *kernel, rust_rng *rng); + +// +// Local Variables: +// mode: C++ +// fill-column: 78; +// indent-tabs-mode: nil +// c-basic-offset: 4 +// buffer-file-coding-system: utf-8-unix +// End: +// + +#endif diff --git a/src/rt/rust_sched_loop.cpp b/src/rt/rust_sched_loop.cpp index 0d0eaaee9628e..c215752d8dd39 100644 --- a/src/rt/rust_sched_loop.cpp +++ b/src/rt/rust_sched_loop.cpp @@ -41,7 +41,7 @@ rust_sched_loop::rust_sched_loop(rust_scheduler *sched, int id, bool killed) : name("main") { LOGPTR(this, "new dom", (uintptr_t)this); - isaac_init(kernel, &rctx, NULL); + rng_init(kernel, &rng, NULL, 0); if (!tls_initialized) init_tls(); @@ -150,10 +150,10 @@ rust_sched_loop::release_task(rust_task *task) { rust_task * rust_sched_loop::schedule_task() { lock.must_have_lock(); - if (running_tasks.length() > 0) { - size_t k = isaac_rand(&rctx); - size_t i = k % running_tasks.length(); - return (rust_task *)running_tasks[i]; + size_t tasks = running_tasks.length(); + if (tasks > 0) { + size_t i = (tasks > 1) ? (rng_gen_u32(kernel, &rng) % tasks) : 0; + return running_tasks[i]; } return NULL; } diff --git a/src/rt/rust_sched_loop.h b/src/rt/rust_sched_loop.h index 0105b83e28b45..736c09ee920ca 100644 --- a/src/rt/rust_sched_loop.h +++ b/src/rt/rust_sched_loop.h @@ -13,6 +13,7 @@ #include "rust_globals.h" #include "rust_log.h" +#include "rust_rng.h" #include "rust_stack.h" #include "rust_signal.h" #include "context.h" @@ -61,7 +62,7 @@ struct rust_sched_loop #endif context c_context; - + rust_rng rng; bool should_exit; stk_seg *cached_c_stack; @@ -102,7 +103,6 @@ struct rust_sched_loop size_t min_stack_size; memory_region local_region; - randctx rctx; const char *const name; // Used for debugging // Only a pointer to 'name' is kept, so it must live as long as this diff --git a/src/rt/rust_stack.cpp b/src/rt/rust_stack.cpp index 3bcda8adf4024..64ca256ff4611 100644 --- a/src/rt/rust_stack.cpp +++ b/src/rt/rust_stack.cpp @@ -58,7 +58,7 @@ check_stack_canary(stk_seg *stk) { stk_seg * create_stack(memory_region *region, size_t sz) { size_t total_sz = sizeof(stk_seg) + sz; - stk_seg *stk = (stk_seg *)region->malloc(total_sz, "stack", false); + stk_seg *stk = (stk_seg *)region->malloc(total_sz, "stack"); memset(stk, 0, sizeof(stk_seg)); stk->end = (uintptr_t) &stk->data[sz]; add_stack_canary(stk); @@ -75,7 +75,7 @@ destroy_stack(memory_region *region, stk_seg *stk) { stk_seg * create_exchange_stack(rust_exchange_alloc *exchange, size_t sz) { size_t total_sz = sizeof(stk_seg) + sz; - stk_seg *stk = (stk_seg *)exchange->malloc(total_sz, false); + stk_seg *stk = (stk_seg *)exchange->malloc(total_sz); memset(stk, 0, sizeof(stk_seg)); stk->end = (uintptr_t) &stk->data[sz]; add_stack_canary(stk); diff --git a/src/rt/rust_task.cpp b/src/rt/rust_task.cpp index e51af464e488a..63dc1c9833e21 100644 --- a/src/rt/rust_task.cpp +++ b/src/rt/rust_task.cpp @@ -450,11 +450,6 @@ rust_task::backtrace() { #endif } -void * -rust_task::calloc(size_t size, const char *tag) { - return local_region.calloc(size, tag); -} - size_t rust_task::get_next_stack_size(size_t min, size_t current, size_t requested) { LOG(this, mem, "calculating new stack size for 0x%" PRIxPTR, this); diff --git a/src/rt/rust_util.h b/src/rt/rust_util.h index 4b0d87880ef9e..0385804a77871 100644 --- a/src/rt/rust_util.h +++ b/src/rt/rust_util.h @@ -19,21 +19,6 @@ extern struct type_desc str_body_tydesc; // Inline fn used regularly elsewhere. -static inline size_t -next_power_of_two(size_t s) -{ - size_t tmp = s - 1; - tmp |= tmp >> 1; - tmp |= tmp >> 2; - tmp |= tmp >> 4; - tmp |= tmp >> 8; - tmp |= tmp >> 16; -#ifdef _LP64 - tmp |= tmp >> 32; -#endif - return tmp + 1; -} - // Rounds |size| to the nearest |alignment|. Invariant: |alignment| is a power // of two. template @@ -91,10 +76,6 @@ inline void reserve_vec_exact(rust_task* task, rust_vec_box** vpp, } } -inline void reserve_vec(rust_task* task, rust_vec_box** vpp, size_t size) { - reserve_vec_exact(task, vpp, next_power_of_two(size)); -} - typedef rust_vec_box rust_str; inline rust_str * @@ -136,65 +117,6 @@ inline size_t get_box_size(size_t body_size, size_t body_align) { return total_size; } -// Initialization helpers for ISAAC RNG - -inline void isaac_seed(rust_kernel* kernel, uint8_t* dest, size_t size) -{ -#ifdef __WIN32__ - HCRYPTPROV hProv; - kernel->win32_require - (_T("CryptAcquireContext"), - CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_FULL, - CRYPT_VERIFYCONTEXT|CRYPT_SILENT)); - kernel->win32_require - (_T("CryptGenRandom"), CryptGenRandom(hProv, size, (BYTE*) dest)); - kernel->win32_require - (_T("CryptReleaseContext"), CryptReleaseContext(hProv, 0)); -#else - int fd = open("/dev/urandom", O_RDONLY); - if (fd == -1) - kernel->fatal("error opening /dev/urandom: %s", strerror(errno)); - size_t amount = 0; - do { - ssize_t ret = read(fd, dest+amount, size-amount); - if (ret < 0) - kernel->fatal("error reading /dev/urandom: %s", strerror(errno)); - else if (ret == 0) - kernel->fatal("somehow hit eof reading from /dev/urandom"); - amount += (size_t)ret; - } while (amount < size); - int ret = close(fd); - // FIXME #3697: Why does this fail sometimes? - if (ret != 0) - kernel->log(log_warn, "error closing /dev/urandom: %s", - strerror(errno)); -#endif -} - -inline void -isaac_init(rust_kernel *kernel, randctx *rctx, rust_vec_box* user_seed) -{ - memset(rctx, 0, sizeof(randctx)); - - char *env_seed = kernel->env->rust_seed; - if (user_seed != NULL) { - // ignore bytes after the required length - size_t seed_len = user_seed->body.fill < sizeof(rctx->randrsl) - ? user_seed->body.fill : sizeof(rctx->randrsl); - memcpy(&rctx->randrsl, user_seed->body.data, seed_len); - } else if (env_seed != NULL) { - ub4 seed = (ub4) atoi(env_seed); - for (size_t i = 0; i < RANDSIZ; i ++) { - memcpy(&rctx->randrsl[i], &seed, sizeof(ub4)); - seed = (seed + 0x7ed55d16) + (seed << 12); - } - } else { - isaac_seed(kernel, (uint8_t*) &rctx->randrsl, sizeof(rctx->randrsl)); - } - - randinit(rctx, 1); -} - // // Local Variables: // mode: C++ diff --git a/src/rt/rustrt.def.in b/src/rt/rustrt.def.in index a19f9053cbeaa..fca10ac3ef49b 100644 --- a/src/rt/rustrt.def.in +++ b/src/rt/rustrt.def.in @@ -17,11 +17,10 @@ rust_mktime new_task precise_time_ns rand_free -rand_new rand_new_seeded -rand_new_seeded2 +rand_seed_size +rand_gen_seed rand_next -rand_seed rust_get_sched_id rust_get_argc rust_get_argv diff --git a/src/rt/uthash/uthash.h b/src/rt/uthash/uthash.h deleted file mode 100644 index 28021b6161191..0000000000000 --- a/src/rt/uthash/uthash.h +++ /dev/null @@ -1,766 +0,0 @@ -/* -Copyright (c) 2003-2009, Troy D. Hanson http://uthash.sourceforge.net -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS -IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED -TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A -PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER -OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR -PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -#ifndef UTHASH_H -#define UTHASH_H - -#include /* memcmp,strlen */ -#include /* ptrdiff_t */ -#include /* uint32_t etc */ - -#define UTHASH_VERSION 1.6 - -/* C++ requires extra stringent casting */ -#if defined __cplusplus -#define TYPEOF(x) (typeof(x)) -#else -#define TYPEOF(x) -#endif - - -#define uthash_fatal(msg) exit(-1) /* fatal error (out of memory,etc) */ -#define uthash_bkt_malloc(sz) malloc(sz) /* malloc fcn for UT_hash_bucket's */ -#define uthash_bkt_free(ptr) free(ptr) /* free fcn for UT_hash_bucket's */ -#define uthash_tbl_malloc(sz) malloc(sz) /* malloc fcn for UT_hash_table */ -#define uthash_tbl_free(ptr) free(ptr) /* free fcn for UT_hash_table */ - -#define uthash_noexpand_fyi(tbl) /* can be defined to log noexpand */ -#define uthash_expand_fyi(tbl) /* can be defined to log expands */ - -/* initial number of buckets */ -#define HASH_INITIAL_NUM_BUCKETS 32 /* initial number of buckets */ -#define HASH_INITIAL_NUM_BUCKETS_LOG2 5 /* lg2 of initial number of buckets */ -#define HASH_BKT_CAPACITY_THRESH 10 /* expand when bucket count reaches */ - -/* calculate the element whose hash handle address is hhe */ -#define ELMT_FROM_HH(tbl,hhp) ((void*)(((char*)hhp) - (tbl)->hho)) - -#define HASH_FIND(hh,head,keyptr,keylen,out) \ -do { \ - unsigned _hf_bkt,_hf_hashv; \ - out=TYPEOF(out)head; \ - if (head) { \ - HASH_FCN(keyptr,keylen, (head)->hh.tbl->num_buckets, _hf_hashv, _hf_bkt); \ - HASH_FIND_IN_BKT((head)->hh.tbl, hh, (head)->hh.tbl->buckets[ _hf_bkt ], \ - keyptr,keylen,out); \ - } \ -} while (0) - -#define HASH_MAKE_TABLE(hh,head) \ -do { \ - (head)->hh.tbl = (UT_hash_table*)uthash_tbl_malloc( \ - sizeof(UT_hash_table)); \ - if (!((head)->hh.tbl)) { uthash_fatal( "out of memory"); } \ - memset((head)->hh.tbl, 0, sizeof(UT_hash_table)); \ - (head)->hh.tbl->tail = &((head)->hh); \ - (head)->hh.tbl->num_buckets = HASH_INITIAL_NUM_BUCKETS; \ - (head)->hh.tbl->log2_num_buckets = HASH_INITIAL_NUM_BUCKETS_LOG2; \ - (head)->hh.tbl->hho = (char*)(&(head)->hh) - (char*)(head); \ - (head)->hh.tbl->buckets = (UT_hash_bucket*)uthash_bkt_malloc( \ - HASH_INITIAL_NUM_BUCKETS*sizeof(struct UT_hash_bucket)); \ - if (! (head)->hh.tbl->buckets) { uthash_fatal( "out of memory"); } \ - memset((head)->hh.tbl->buckets, 0, \ - HASH_INITIAL_NUM_BUCKETS*sizeof(struct UT_hash_bucket)); \ -} while(0) - -#define HASH_ADD(hh,head,fieldname,keylen_in,add) \ - HASH_ADD_KEYPTR(hh,head,&add->fieldname,keylen_in,add) - -#define HASH_ADD_KEYPTR(hh,head,keyptr,keylen_in,add) \ -do { \ - unsigned _ha_bkt; \ - (add)->hh.next = NULL; \ - (add)->hh.key = (char*)keyptr; \ - (add)->hh.keylen = keylen_in; \ - if (!(head)) { \ - head = (add); \ - (head)->hh.prev = NULL; \ - HASH_MAKE_TABLE(hh,head); \ - } else { \ - (head)->hh.tbl->tail->next = (add); \ - (add)->hh.prev = ELMT_FROM_HH((head)->hh.tbl, (head)->hh.tbl->tail); \ - (head)->hh.tbl->tail = &((add)->hh); \ - } \ - (head)->hh.tbl->num_items++; \ - (add)->hh.tbl = (head)->hh.tbl; \ - HASH_FCN(keyptr,keylen_in, (head)->hh.tbl->num_buckets, \ - (add)->hh.hashv, _ha_bkt); \ - HASH_ADD_TO_BKT((head)->hh.tbl->buckets[_ha_bkt],&(add)->hh); \ - HASH_EMIT_KEY(hh,head,keyptr,keylen_in); \ - HASH_FSCK(hh,head); \ -} while(0) - -#define HASH_TO_BKT( hashv, num_bkts, bkt ) \ -do { \ - bkt = ((hashv) & ((num_bkts) - 1)); \ -} while(0) - -/* delete "delptr" from the hash table. - * "the usual" patch-up process for the app-order doubly-linked-list. - * The use of _hd_hh_del below deserves special explanation. - * These used to be expressed using (delptr) but that led to a bug - * if someone used the same symbol for the head and deletee, like - * HASH_DELETE(hh,users,users); - * We want that to work, but by changing the head (users) below - * we were forfeiting our ability to further refer to the deletee (users) - * in the patch-up process. Solution: use scratch space in the table to - * copy the deletee pointer, then the latter references are via that - * scratch pointer rather than through the repointed (users) symbol. - */ -#define HASH_DELETE(hh,head,delptr) \ -do { \ - unsigned _hd_bkt; \ - struct UT_hash_handle *_hd_hh_del; \ - if ( ((delptr)->hh.prev == NULL) && ((delptr)->hh.next == NULL) ) { \ - uthash_bkt_free((head)->hh.tbl->buckets ); \ - uthash_tbl_free((head)->hh.tbl); \ - head = NULL; \ - } else { \ - _hd_hh_del = &((delptr)->hh); \ - if ((delptr) == ELMT_FROM_HH((head)->hh.tbl,(head)->hh.tbl->tail)) { \ - (head)->hh.tbl->tail = \ - (UT_hash_handle*)((char*)((delptr)->hh.prev) + \ - (head)->hh.tbl->hho); \ - } \ - if ((delptr)->hh.prev) { \ - ((UT_hash_handle*)((char*)((delptr)->hh.prev) + \ - (head)->hh.tbl->hho))->next = (delptr)->hh.next; \ - } else { \ - head = TYPEOF(head)((delptr)->hh.next); \ - } \ - if (_hd_hh_del->next) { \ - ((UT_hash_handle*)((char*)_hd_hh_del->next + \ - (head)->hh.tbl->hho))->prev = \ - _hd_hh_del->prev; \ - } \ - HASH_TO_BKT( _hd_hh_del->hashv, (head)->hh.tbl->num_buckets, _hd_bkt); \ - HASH_DEL_IN_BKT(hh,(head)->hh.tbl->buckets[_hd_bkt], _hd_hh_del); \ - (head)->hh.tbl->num_items--; \ - } \ - HASH_FSCK(hh,head); \ -} while (0) - - -/* convenience forms of HASH_FIND/HASH_ADD/HASH_DEL */ -#define HASH_FIND_STR(head,findstr,out) \ - HASH_FIND(hh,head,findstr,strlen(findstr),out) -#define HASH_ADD_STR(head,strfield,add) \ - HASH_ADD(hh,head,strfield,strlen(add->strfield),add) -#define HASH_FIND_INT(head,findint,out) \ - HASH_FIND(hh,head,findint,sizeof(int),out) -#define HASH_ADD_INT(head,intfield,add) \ - HASH_ADD(hh,head,intfield,sizeof(int),add) -#define HASH_DEL(head,delptr) \ - HASH_DELETE(hh,head,delptr) - -/* HASH_FSCK checks hash integrity on every add/delete when HASH_DEBUG is defined. - * This is for uthash developer only; it compiles away if HASH_DEBUG isn't defined. - */ -#ifdef HASH_DEBUG -#define HASH_OOPS(...) do { fprintf(stderr,__VA_ARGS__); exit(-1); } while (0) -#define HASH_FSCK(hh,head) \ -do { \ - unsigned _bkt_i; \ - unsigned _count, _bkt_count; \ - char *_prev; \ - struct UT_hash_handle *_thh; \ - if (head) { \ - _count = 0; \ - for( _bkt_i = 0; _bkt_i < (head)->hh.tbl->num_buckets; _bkt_i++) { \ - _bkt_count = 0; \ - _thh = (head)->hh.tbl->buckets[_bkt_i].hh_head; \ - _prev = NULL; \ - while (_thh) { \ - if (_prev != (char*)(_thh->hh_prev)) { \ - HASH_OOPS("invalid hh_prev %p, actual %p\n", \ - _thh->hh_prev, _prev ); \ - } \ - _bkt_count++; \ - _prev = (char*)(_thh); \ - _thh = _thh->hh_next; \ - } \ - _count += _bkt_count; \ - if ((head)->hh.tbl->buckets[_bkt_i].count != _bkt_count) { \ - HASH_OOPS("invalid bucket count %d, actual %d\n", \ - (head)->hh.tbl->buckets[_bkt_i].count, _bkt_count); \ - } \ - } \ - if (_count != (head)->hh.tbl->num_items) { \ - HASH_OOPS("invalid hh item count %d, actual %d\n", \ - (head)->hh.tbl->num_items, _count ); \ - } \ - /* traverse hh in app order; check next/prev integrity, count */ \ - _count = 0; \ - _prev = NULL; \ - _thh = &(head)->hh; \ - while (_thh) { \ - _count++; \ - if (_prev !=(char*)(_thh->prev)) { \ - HASH_OOPS("invalid prev %p, actual %p\n", \ - _thh->prev, _prev ); \ - } \ - _prev = (char*)ELMT_FROM_HH((head)->hh.tbl, _thh); \ - _thh = ( _thh->next ? (UT_hash_handle*)((char*)(_thh->next) + \ - (head)->hh.tbl->hho) : NULL ); \ - } \ - if (_count != (head)->hh.tbl->num_items) { \ - HASH_OOPS("invalid app item count %d, actual %d\n", \ - (head)->hh.tbl->num_items, _count ); \ - } \ - } \ -} while (0) -#else -#define HASH_FSCK(hh,head) -#endif - -/* When compiled with -DHASH_EMIT_KEYS, length-prefixed keys are emitted to - * the descriptor to which this macro is defined for tuning the hash function. - * The app can #include to get the prototype for write(2). */ -#ifdef HASH_EMIT_KEYS -#define HASH_EMIT_KEY(hh,head,keyptr,fieldlen) \ -do { \ - unsigned _klen = fieldlen; \ - write(HASH_EMIT_KEYS, &_klen, sizeof(_klen)); \ - write(HASH_EMIT_KEYS, keyptr, fieldlen); \ -} while (0) -#else -#define HASH_EMIT_KEY(hh,head,keyptr,fieldlen) -#endif - -/* default to MurmurHash unless overridden e.g. DHASH_FUNCTION=HASH_SAX */ -#ifdef HASH_FUNCTION -#define HASH_FCN HASH_FUNCTION -#else -#define HASH_FCN HASH_MUR -#endif - -/* The Bernstein hash function, used in Perl prior to v5.6 */ -#define HASH_BER(key,keylen,num_bkts,hashv,bkt) \ -do { \ - unsigned _hb_keylen=keylen; \ - char *_hb_key=(char*)key; \ - (hashv) = 0; \ - while (_hb_keylen--) { (hashv) = ((hashv) * 33) + *_hb_key++; } \ - bkt = (hashv) & (num_bkts-1); \ -} while (0) - - -/* SAX/FNV/OAT/JEN hash functions are macro variants of those listed at - * http://eternallyconfuzzled.com/tuts/algorithms/jsw_tut_hashing.aspx */ -#define HASH_SAX(key,keylen,num_bkts,hashv,bkt) \ -do { \ - unsigned _sx_i; \ - char *_hs_key=(char*)key; \ - hashv = 0; \ - for(_sx_i=0; _sx_i < keylen; _sx_i++) \ - hashv ^= (hashv << 5) + (hashv >> 2) + _hs_key[_sx_i]; \ - bkt = hashv & (num_bkts-1); \ -} while (0) - -#define HASH_FNV(key,keylen,num_bkts,hashv,bkt) \ -do { \ - unsigned _fn_i; \ - char *_hf_key=(char*)key; \ - hashv = 2166136261UL; \ - for(_fn_i=0; _fn_i < keylen; _fn_i++) \ - hashv = (hashv * 16777619) ^ _hf_key[_fn_i]; \ - bkt = hashv & (num_bkts-1); \ -} while(0); - -#define HASH_OAT(key,keylen,num_bkts,hashv,bkt) \ -do { \ - unsigned _ho_i; \ - char *_ho_key=(char*)key; \ - hashv = 0; \ - for(_ho_i=0; _ho_i < keylen; _ho_i++) { \ - hashv += _ho_key[_ho_i]; \ - hashv += (hashv << 10); \ - hashv ^= (hashv >> 6); \ - } \ - hashv += (hashv << 3); \ - hashv ^= (hashv >> 11); \ - hashv += (hashv << 15); \ - bkt = hashv & (num_bkts-1); \ -} while(0) - -#define HASH_JEN_MIX(a,b,c) \ -do { \ - a -= b; a -= c; a ^= ( c >> 13 ); \ - b -= c; b -= a; b ^= ( a << 8 ); \ - c -= a; c -= b; c ^= ( b >> 13 ); \ - a -= b; a -= c; a ^= ( c >> 12 ); \ - b -= c; b -= a; b ^= ( a << 16 ); \ - c -= a; c -= b; c ^= ( b >> 5 ); \ - a -= b; a -= c; a ^= ( c >> 3 ); \ - b -= c; b -= a; b ^= ( a << 10 ); \ - c -= a; c -= b; c ^= ( b >> 15 ); \ -} while (0) - -#define HASH_JEN(key,keylen,num_bkts,hashv,bkt) \ -do { \ - unsigned _hj_i,_hj_j,_hj_k; \ - char *_hj_key=(char*)key; \ - hashv = 0xfeedbeef; \ - _hj_i = _hj_j = 0x9e3779b9; \ - _hj_k = keylen; \ - while (_hj_k >= 12) { \ - _hj_i += (_hj_key[0] + ( (unsigned)_hj_key[1] << 8 ) \ - + ( (unsigned)_hj_key[2] << 16 ) \ - + ( (unsigned)_hj_key[3] << 24 ) ); \ - _hj_j += (_hj_key[4] + ( (unsigned)_hj_key[5] << 8 ) \ - + ( (unsigned)_hj_key[6] << 16 ) \ - + ( (unsigned)_hj_key[7] << 24 ) ); \ - hashv += (_hj_key[8] + ( (unsigned)_hj_key[9] << 8 ) \ - + ( (unsigned)_hj_key[10] << 16 ) \ - + ( (unsigned)_hj_key[11] << 24 ) ); \ - \ - HASH_JEN_MIX(_hj_i, _hj_j, hashv); \ - \ - _hj_key += 12; \ - _hj_k -= 12; \ - } \ - hashv += keylen; \ - switch ( _hj_k ) { \ - case 11: hashv += ( (unsigned)_hj_key[10] << 24 ); \ - case 10: hashv += ( (unsigned)_hj_key[9] << 16 ); \ - case 9: hashv += ( (unsigned)_hj_key[8] << 8 ); \ - case 8: _hj_j += ( (unsigned)_hj_key[7] << 24 ); \ - case 7: _hj_j += ( (unsigned)_hj_key[6] << 16 ); \ - case 6: _hj_j += ( (unsigned)_hj_key[5] << 8 ); \ - case 5: _hj_j += _hj_key[4]; \ - case 4: _hj_i += ( (unsigned)_hj_key[3] << 24 ); \ - case 3: _hj_i += ( (unsigned)_hj_key[2] << 16 ); \ - case 2: _hj_i += ( (unsigned)_hj_key[1] << 8 ); \ - case 1: _hj_i += _hj_key[0]; \ - } \ - HASH_JEN_MIX(_hj_i, _hj_j, hashv); \ - bkt = hashv & (num_bkts-1); \ -} while(0) - -/* The Paul Hsieh hash function */ -#undef get16bits -#if (defined(__GNUC__) && defined(__i386__)) || defined(__WATCOMC__) \ - || defined(_MSC_VER) || defined (__BORLANDC__) || defined (__TURBOC__) -#define get16bits(d) (*((const uint16_t *) (d))) -#endif - -#if !defined (get16bits) -#define get16bits(d) ((((uint32_t)(((const uint8_t *)(d))[1])) << 8)\ - +(uint32_t)(((const uint8_t *)(d))[0]) ) -#endif -#define HASH_SFH(key,keylen,num_bkts,hashv,bkt) \ -do { \ - char *_sfh_key=(char*)key; \ - hashv = 0xcafebabe; \ - uint32_t _sfh_tmp, _sfh_len = keylen; \ - \ - int _sfh_rem = _sfh_len & 3; \ - _sfh_len >>= 2; \ - \ - /* Main loop */ \ - for (;_sfh_len > 0; _sfh_len--) { \ - hashv += get16bits (_sfh_key); \ - _sfh_tmp = (get16bits (_sfh_key+2) << 11) ^ hashv; \ - hashv = (hashv << 16) ^ _sfh_tmp; \ - _sfh_key += 2*sizeof (uint16_t); \ - hashv += hashv >> 11; \ - } \ - \ - /* Handle end cases */ \ - switch (_sfh_rem) { \ - case 3: hashv += get16bits (_sfh_key); \ - hashv ^= hashv << 16; \ - hashv ^= _sfh_key[sizeof (uint16_t)] << 18; \ - hashv += hashv >> 11; \ - break; \ - case 2: hashv += get16bits (_sfh_key); \ - hashv ^= hashv << 11; \ - hashv += hashv >> 17; \ - break; \ - case 1: hashv += *_sfh_key; \ - hashv ^= hashv << 10; \ - hashv += hashv >> 1; \ - } \ - \ - /* Force "avalanching" of final 127 bits */ \ - hashv ^= hashv << 3; \ - hashv += hashv >> 5; \ - hashv ^= hashv << 4; \ - hashv += hashv >> 17; \ - hashv ^= hashv << 25; \ - hashv += hashv >> 6; \ - bkt = hashv & (num_bkts-1); \ -} while(0); - -/* Austin Appleby's MurmurHash */ -#define HASH_MUR(key,keylen,num_bkts,hashv,bkt) \ -do { \ - const unsigned int _mur_m = 0x5bd1e995; \ - const int _mur_r = 24; \ - hashv = 0xcafebabe ^ keylen; \ - char *_mur_key = (char *)key; \ - uint32_t _mur_tmp, _mur_len = keylen; \ - \ - for (;_mur_len >= 4; _mur_len-=4) { \ - _mur_tmp = *(uint32_t *)_mur_key; \ - _mur_tmp *= _mur_m; \ - _mur_tmp ^= _mur_tmp >> _mur_r; \ - _mur_tmp *= _mur_m; \ - hashv *= _mur_m; \ - hashv ^= _mur_tmp; \ - _mur_key += 4; \ - } \ - \ - switch(_mur_len) \ - { \ - case 3: hashv ^= _mur_key[2] << 16; \ - case 2: hashv ^= _mur_key[1] << 8; \ - case 1: hashv ^= _mur_key[0]; \ - hashv *= _mur_m; \ - }; \ - \ - hashv ^= hashv >> 13; \ - hashv *= _mur_m; \ - hashv ^= hashv >> 15; \ - \ - bkt = hashv & (num_bkts-1); \ -} while(0) - -/* key comparison function; return 0 if keys equal */ -#define HASH_KEYCMP(a,b,len) memcmp(a,b,len) - -/* iterate over items in a known bucket to find desired item */ -#define HASH_FIND_IN_BKT(tbl,hh,head,keyptr,keylen_in,out) \ -out = TYPEOF(out)((head.hh_head) ? ELMT_FROM_HH(tbl,head.hh_head) : NULL); \ -while (out) { \ - if (out->hh.keylen == keylen_in) { \ - if ((HASH_KEYCMP(out->hh.key,keyptr,keylen_in)) == 0) break; \ - } \ - out= TYPEOF(out)((out->hh.hh_next) ? \ - ELMT_FROM_HH(tbl,out->hh.hh_next) : NULL); \ -} - -/* add an item to a bucket */ -#define HASH_ADD_TO_BKT(head,addhh) \ -do { \ - head.count++; \ - (addhh)->hh_next = head.hh_head; \ - (addhh)->hh_prev = NULL; \ - if (head.hh_head) { (head).hh_head->hh_prev = (addhh); } \ - (head).hh_head=addhh; \ - if (head.count >= ((head.expand_mult+1) * HASH_BKT_CAPACITY_THRESH) \ - && (addhh)->tbl->noexpand != 1) { \ - HASH_EXPAND_BUCKETS((addhh)->tbl); \ - } \ -} while(0) - -/* remove an item from a given bucket */ -#define HASH_DEL_IN_BKT(hh,head,hh_del) \ - (head).count--; \ - if ((head).hh_head == hh_del) { \ - (head).hh_head = hh_del->hh_next; \ - } \ - if (hh_del->hh_prev) { \ - hh_del->hh_prev->hh_next = hh_del->hh_next; \ - } \ - if (hh_del->hh_next) { \ - hh_del->hh_next->hh_prev = hh_del->hh_prev; \ - } - -/* Bucket expansion has the effect of doubling the number of buckets - * and redistributing the items into the new buckets. Ideally the - * items will distribute more or less evenly into the new buckets - * (the extent to which this is true is a measure of the quality of - * the hash function as it applies to the key domain). - * - * With the items distributed into more buckets, the chain length - * (item count) in each bucket is reduced. Thus by expanding buckets - * the hash keeps a bound on the chain length. This bounded chain - * length is the essence of how a hash provides constant time lookup. - * - * The calculation of tbl->ideal_chain_maxlen below deserves some - * explanation. First, keep in mind that we're calculating the ideal - * maximum chain length based on the *new* (doubled) bucket count. - * In fractions this is just n/b (n=number of items,b=new num buckets). - * Since the ideal chain length is an integer, we want to calculate - * ceil(n/b). We don't depend on floating point arithmetic in this - * hash, so to calculate ceil(n/b) with integers we could write - * - * ceil(n/b) = (n/b) + ((n%b)?1:0) - * - * and in fact a previous version of this hash did just that. - * But now we have improved things a bit by recognizing that b is - * always a power of two. We keep its base 2 log handy (call it lb), - * so now we can write this with a bit shift and logical AND: - * - * ceil(n/b) = (n>>lb) + ( (n & (b-1)) ? 1:0) - * - */ -#define HASH_EXPAND_BUCKETS(tbl) \ -do { \ - unsigned _he_bkt; \ - unsigned _he_bkt_i; \ - struct UT_hash_handle *_he_thh, *_he_hh_nxt; \ - UT_hash_bucket *_he_new_buckets, *_he_newbkt; \ - _he_new_buckets = (UT_hash_bucket*)uthash_bkt_malloc( \ - 2 * tbl->num_buckets * sizeof(struct UT_hash_bucket)); \ - if (!_he_new_buckets) { uthash_fatal( "out of memory"); } \ - memset(_he_new_buckets, 0, \ - 2 * tbl->num_buckets * sizeof(struct UT_hash_bucket)); \ - tbl->ideal_chain_maxlen = \ - (tbl->num_items >> (tbl->log2_num_buckets+1)) + \ - ((tbl->num_items & ((tbl->num_buckets*2)-1)) ? 1 : 0); \ - tbl->nonideal_items = 0; \ - for(_he_bkt_i = 0; _he_bkt_i < tbl->num_buckets; _he_bkt_i++) \ - { \ - _he_thh = tbl->buckets[ _he_bkt_i ].hh_head; \ - while (_he_thh) { \ - _he_hh_nxt = _he_thh->hh_next; \ - HASH_TO_BKT( _he_thh->hashv, tbl->num_buckets*2, _he_bkt); \ - _he_newbkt = &(_he_new_buckets[ _he_bkt ]); \ - if (++(_he_newbkt->count) > tbl->ideal_chain_maxlen) { \ - tbl->nonideal_items++; \ - _he_newbkt->expand_mult = _he_newbkt->count / \ - tbl->ideal_chain_maxlen; \ - } \ - _he_thh->hh_prev = NULL; \ - _he_thh->hh_next = _he_newbkt->hh_head; \ - if (_he_newbkt->hh_head) _he_newbkt->hh_head->hh_prev = \ - _he_thh; \ - _he_newbkt->hh_head = _he_thh; \ - _he_thh = _he_hh_nxt; \ - } \ - } \ - tbl->num_buckets *= 2; \ - tbl->log2_num_buckets++; \ - uthash_bkt_free( tbl->buckets ); \ - tbl->buckets = _he_new_buckets; \ - tbl->ineff_expands = (tbl->nonideal_items > (tbl->num_items >> 1)) ? \ - (tbl->ineff_expands+1) : 0; \ - if (tbl->ineff_expands > 1) { \ - tbl->noexpand=1; \ - uthash_noexpand_fyi(tbl); \ - } \ - uthash_expand_fyi(tbl); \ -} while(0) - - -/* This is an adaptation of Simon Tatham's O(n log(n)) mergesort */ -/* Note that HASH_SORT assumes the hash handle name to be hh. - * HASH_SRT was added to allow the hash handle name to be passed in. */ -#define HASH_SORT(head,cmpfcn) HASH_SRT(hh,head,cmpfcn) -#define HASH_SRT(hh,head,cmpfcn) \ -do { \ - unsigned _hs_i; \ - unsigned _hs_looping,_hs_nmerges,_hs_insize,_hs_psize,_hs_qsize; \ - struct UT_hash_handle *_hs_p, *_hs_q, *_hs_e, *_hs_list, *_hs_tail; \ - if (head) { \ - _hs_insize = 1; \ - _hs_looping = 1; \ - _hs_list = &((head)->hh); \ - while (_hs_looping) { \ - _hs_p = _hs_list; \ - _hs_list = NULL; \ - _hs_tail = NULL; \ - _hs_nmerges = 0; \ - while (_hs_p) { \ - _hs_nmerges++; \ - _hs_q = _hs_p; \ - _hs_psize = 0; \ - for ( _hs_i = 0; _hs_i < _hs_insize; _hs_i++ ) { \ - _hs_psize++; \ - _hs_q = (UT_hash_handle*)((_hs_q->next) ? \ - ((void*)((char*)(_hs_q->next) + \ - (head)->hh.tbl->hho)) : NULL); \ - if (! (_hs_q) ) break; \ - } \ - _hs_qsize = _hs_insize; \ - while ((_hs_psize > 0) || ((_hs_qsize > 0) && _hs_q )) { \ - if (_hs_psize == 0) { \ - _hs_e = _hs_q; \ - _hs_q = (UT_hash_handle*)((_hs_q->next) ? \ - ((void*)((char*)(_hs_q->next) + \ - (head)->hh.tbl->hho)) : NULL); \ - _hs_qsize--; \ - } else if ( (_hs_qsize == 0) || !(_hs_q) ) { \ - _hs_e = _hs_p; \ - _hs_p = (UT_hash_handle*)((_hs_p->next) ? \ - ((void*)((char*)(_hs_p->next) + \ - (head)->hh.tbl->hho)) : NULL); \ - _hs_psize--; \ - } else if (( \ - cmpfcn(TYPEOF(head)(ELMT_FROM_HH((head)->hh.tbl,_hs_p)), \ - TYPEOF(head)(ELMT_FROM_HH((head)->hh.tbl,_hs_q))) \ - ) <= 0) { \ - _hs_e = _hs_p; \ - _hs_p = (UT_hash_handle*)((_hs_p->next) ? \ - ((void*)((char*)(_hs_p->next) + \ - (head)->hh.tbl->hho)) : NULL); \ - _hs_psize--; \ - } else { \ - _hs_e = _hs_q; \ - _hs_q = (UT_hash_handle*)((_hs_q->next) ? \ - ((void*)((char*)(_hs_q->next) + \ - (head)->hh.tbl->hho)) : NULL); \ - _hs_qsize--; \ - } \ - if ( _hs_tail ) { \ - _hs_tail->next = ((_hs_e) ? \ - ELMT_FROM_HH((head)->hh.tbl,_hs_e) : NULL); \ - } else { \ - _hs_list = _hs_e; \ - } \ - _hs_e->prev = ((_hs_tail) ? \ - ELMT_FROM_HH((head)->hh.tbl,_hs_tail) : NULL); \ - _hs_tail = _hs_e; \ - } \ - _hs_p = _hs_q; \ - } \ - _hs_tail->next = NULL; \ - if ( _hs_nmerges <= 1 ) { \ - _hs_looping=0; \ - (head)->hh.tbl->tail = _hs_tail; \ - (head) = TYPEOF(head)ELMT_FROM_HH((head)->hh.tbl, _hs_list); \ - } \ - _hs_insize *= 2; \ - } \ - HASH_FSCK(hh,head); \ - } \ -} while (0) - -/* This function selects items from one hash into another hash. - * The end result is that the selected items have dual presence - * in both hashes. There is no copy of the items made; rather - * they are added into the new hash through a secondary hash - * hash handle that must be present in the structure. */ -#define HASH_SELECT(hh_dst, dst, hh_src, src, cond) \ -do { \ - unsigned _src_bkt, _dst_bkt; \ - void *_last_elt=NULL, *_elt; \ - UT_hash_handle *_src_hh, *_dst_hh, *_last_elt_hh=NULL; \ - ptrdiff_t _dst_hho = ((char*)(&(dst)->hh_dst) - (char*)(dst)); \ - if (src) { \ - for(_src_bkt=0; _src_bkt < (src)->hh_src.tbl->num_buckets; _src_bkt++) { \ - for(_src_hh = (src)->hh_src.tbl->buckets[_src_bkt].hh_head; \ - _src_hh; \ - _src_hh = _src_hh->hh_next) { \ - _elt = ELMT_FROM_HH((src)->hh_src.tbl, _src_hh); \ - if (cond(_elt)) { \ - _dst_hh = (UT_hash_handle*)(((char*)_elt) + _dst_hho); \ - _dst_hh->key = _src_hh->key; \ - _dst_hh->keylen = _src_hh->keylen; \ - _dst_hh->hashv = _src_hh->hashv; \ - _dst_hh->prev = _last_elt; \ - _dst_hh->next = NULL; \ - if (_last_elt_hh) { _last_elt_hh->next = _elt; } \ - if (!dst) { \ - dst = TYPEOF(dst)_elt; \ - HASH_MAKE_TABLE(hh_dst,dst); \ - } else { \ - _dst_hh->tbl = (dst)->hh_dst.tbl; \ - } \ - HASH_TO_BKT(_dst_hh->hashv, _dst_hh->tbl->num_buckets, _dst_bkt); \ - HASH_ADD_TO_BKT(_dst_hh->tbl->buckets[_dst_bkt],_dst_hh); \ - (dst)->hh_dst.tbl->num_items++; \ - _last_elt = _elt; \ - _last_elt_hh = _dst_hh; \ - } \ - } \ - } \ - } \ - HASH_FSCK(hh_dst,dst); \ -} while (0) - -#define HASH_CLEAR(hh,head) \ -do { \ - if (head) { \ - uthash_bkt_free((head)->hh.tbl->buckets ); \ - uthash_tbl_free((head)->hh.tbl); \ - (head)=NULL; \ - } \ -} while(0) - -/* obtain a count of items in the hash */ -#define HASH_COUNT(head) HASH_CNT(hh,head) -#define HASH_CNT(hh,head) (head?(head->hh.tbl->num_items):0) - -typedef struct UT_hash_bucket { - struct UT_hash_handle *hh_head; - unsigned count; - - /* expand_mult is normally set to 0. In this situation, the max chain length - * threshold is enforced at its default value, HASH_BKT_CAPACITY_THRESH. (If - * the bucket's chain exceeds this length, bucket expansion is triggered). - * However, setting expand_mult to a non-zero value delays bucket expansion - * (that would be triggered by additions to this particular bucket) - * until its chain length reaches a *multiple* of HASH_BKT_CAPACITY_THRESH. - * (The multiplier is simply expand_mult+1). The whole idea of this - * multiplier is to reduce bucket expansions, since they are expensive, in - * situations where we know that a particular bucket tends to be overused. - * It is better to let its chain length grow to a longer yet-still-bounded - * value, than to do an O(n) bucket expansion too often. - */ - unsigned expand_mult; - -} UT_hash_bucket; - -typedef struct UT_hash_table { - UT_hash_bucket *buckets; - unsigned num_buckets, log2_num_buckets; - unsigned num_items; - struct UT_hash_handle *tail; /* tail hh in app order, for fast append */ - ptrdiff_t hho; /* hash handle offset (byte pos of hash handle in element */ - - /* in an ideal situation (all buckets used equally), no bucket would have - * more than ceil(#items/#buckets) items. that's the ideal chain length. */ - unsigned ideal_chain_maxlen; - - /* nonideal_items is the number of items in the hash whose chain position - * exceeds the ideal chain maxlen. these items pay the penalty for an uneven - * hash distribution; reaching them in a chain traversal takes >ideal steps */ - unsigned nonideal_items; - - /* ineffective expands occur when a bucket doubling was performed, but - * afterward, more than half the items in the hash had nonideal chain - * positions. If this happens on two consecutive expansions we inhibit any - * further expansion, as it's not helping; this happens when the hash - * function isn't a good fit for the key domain. When expansion is inhibited - * the hash will still work, albeit no longer in constant time. */ - unsigned ineff_expands, noexpand; - - -} UT_hash_table; - - -typedef struct UT_hash_handle { - struct UT_hash_table *tbl; - void *prev; /* prev element in app order */ - void *next; /* next element in app order */ - struct UT_hash_handle *hh_prev; /* previous hh in bucket order */ - struct UT_hash_handle *hh_next; /* next hh in bucket order */ - void *key; /* ptr to enclosing struct's key */ - unsigned keylen; /* enclosing struct's key len */ - unsigned hashv; /* result of hash-fcn(key) */ -} UT_hash_handle; - -#endif /* UTHASH_H */ diff --git a/src/rt/uthash/utlist.h b/src/rt/uthash/utlist.h deleted file mode 100644 index a33615e1ba054..0000000000000 --- a/src/rt/uthash/utlist.h +++ /dev/null @@ -1,280 +0,0 @@ -/* -Copyright (c) 2007-2009, Troy D. Hanson -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS -IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED -TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A -PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER -OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR -PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -#ifndef UTLIST_H -#define UTLIST_H - -#define UTLIST_VERSION 1.0 - -/* C++ requires extra stringent casting */ -#if defined __cplusplus -#define LTYPEOF(x) (typeof(x)) -#else -#define LTYPEOF(x) -#endif -/* - * This file contains macros to manipulate singly and doubly-linked lists. - * - * 1. LL_ macros: singly-linked lists. - * 2. DL_ macros: doubly-linked lists. - * 3. CDL_ macros: circular doubly-linked lists. - * - * To use singly-linked lists, your structure must have a "next" pointer. - * To use doubly-linked lists, your structure must "prev" and "next" pointers. - * Either way, the pointer to the head of the list must be initialized to NULL. - * - * ----------------.EXAMPLE ------------------------- - * struct item { - * int id; - * struct item *prev, *next; - * } - * - * struct item *list = NULL: - * - * int main() { - * struct item *item; - * ... allocate and populate item ... - * DL_APPEND(list, item); - * } - * -------------------------------------------------- - * - * For doubly-linked lists, the append and delete macros are O(1) - * For singly-linked lists, append and delete are O(n) but prepend is O(1) - * The sort macro is O(n log(n)) for all types of single/double/circular lists. - */ - -/****************************************************************************** - * The SORT macros * - *****************************************************************************/ -#define LL_SORT(l,cmp) \ - LISTSORT(l,0,0,FIELD_OFFSET(l,next),cmp) -#define DL_SORT(l,cmp) \ - LISTSORT(l,0,FIELD_OFFSET(l,prev),FIELD_OFFSET(l,next),cmp) -#define CDL_SORT(l,cmp) \ - LISTSORT(l,1,FIELD_OFFSET(l,prev),FIELD_OFFSET(l,next),cmp) - -/* The macros can't assume or cast to the caller's list element type. So we use - * a couple tricks when we need to deal with those element's prev/next pointers. - * Basically we use char pointer arithmetic to get those field offsets. */ -#define FIELD_OFFSET(ptr,field) ((char*)&((ptr)->field) - (char*)(ptr)) -#define LNEXT(e,no) (*(char**)(((char*)e) + no)) -#define LPREV(e,po) (*(char**)(((char*)e) + po)) -/****************************************************************************** - * The LISTSORT macro is an adaptation of Simon Tatham's O(n log(n)) mergesort* - * Unwieldy variable names used here to avoid shadowing passed-in variables. * - *****************************************************************************/ -#define LISTSORT(list, is_circular, po, no, cmp) \ -do { \ - void *_ls_p, *_ls_q, *_ls_e, *_ls_tail, *_ls_oldhead; \ - int _ls_insize, _ls_nmerges, _ls_psize, _ls_qsize, _ls_i, _ls_looping; \ - int _ls_is_double = (po==0) ? 0 : 1; \ - if (list) { \ - _ls_insize = 1; \ - _ls_looping = 1; \ - while (_ls_looping) { \ - _ls_p = list; \ - _ls_oldhead = list; \ - list = NULL; \ - _ls_tail = NULL; \ - _ls_nmerges = 0; \ - while (_ls_p) { \ - _ls_nmerges++; \ - _ls_q = _ls_p; \ - _ls_psize = 0; \ - for (_ls_i = 0; _ls_i < _ls_insize; _ls_i++) { \ - _ls_psize++; \ - if (is_circular) { \ - _ls_q = ((LNEXT(_ls_q,no) == _ls_oldhead) ? NULL : LNEXT(_ls_q,no)); \ - } else { \ - _ls_q = LNEXT(_ls_q,no); \ - } \ - if (!_ls_q) break; \ - } \ - _ls_qsize = _ls_insize; \ - while (_ls_psize > 0 || (_ls_qsize > 0 && _ls_q)) { \ - if (_ls_psize == 0) { \ - _ls_e = _ls_q; _ls_q = LNEXT(_ls_q,no); _ls_qsize--; \ - if (is_circular && _ls_q == _ls_oldhead) { _ls_q = NULL; } \ - } else if (_ls_qsize == 0 || !_ls_q) { \ - _ls_e = _ls_p; _ls_p = LNEXT(_ls_p,no); _ls_psize--; \ - if (is_circular && (_ls_p == _ls_oldhead)) { _ls_p = NULL; } \ - } else if (cmp(LTYPEOF(list)_ls_p,LTYPEOF(list)_ls_q) <= 0) { \ - _ls_e = _ls_p; _ls_p = LNEXT(_ls_p,no); _ls_psize--; \ - if (is_circular && (_ls_p == _ls_oldhead)) { _ls_p = NULL; } \ - } else { \ - _ls_e = _ls_q; _ls_q = LNEXT(_ls_q,no); _ls_qsize--; \ - if (is_circular && (_ls_q == _ls_oldhead)) { _ls_q = NULL; } \ - } \ - if (_ls_tail) { \ - LNEXT(_ls_tail,no) = (char*)_ls_e; \ - } else { \ - list = LTYPEOF(list)_ls_e; \ - } \ - if (_ls_is_double) { \ - LPREV(_ls_e,po) = (char*)_ls_tail; \ - } \ - _ls_tail = _ls_e; \ - } \ - _ls_p = _ls_q; \ - } \ - if (is_circular) { \ - LNEXT(_ls_tail,no) = (char*)list; \ - if (_ls_is_double) { \ - LPREV(list,po) = (char*)_ls_tail; \ - } \ - } else { \ - LNEXT(_ls_tail,no) = NULL; \ - } \ - if (_ls_nmerges <= 1) { \ - _ls_looping=0; \ - } \ - _ls_insize *= 2; \ - } \ - } \ -} while (0) - -/****************************************************************************** - * singly linked list macros (non-circular) * - *****************************************************************************/ -#define LL_PREPEND(head,add) \ -do { \ - (add)->next = head; \ - head = add; \ -} while (0) - -#define LL_APPEND(head,add) \ -do { \ - (add)->next=NULL; \ - if (head) { \ - char *_lla_el = (char*)(head); \ - unsigned _lla_no = FIELD_OFFSET(head,next); \ - while (LNEXT(_lla_el,_lla_no)) { _lla_el = LNEXT(_lla_el,_lla_no); } \ - LNEXT(_lla_el,_lla_no)=(char*)(add); \ - } else { \ - (head)=(add); \ - } \ -} while (0) - -#define LL_DELETE(head,del) \ -do { \ - if ((head) == (del)) { \ - (head)=(head)->next; \ - } else { \ - char *_lld_el = (char*)(head); \ - unsigned _lld_no = FIELD_OFFSET(head,next); \ - while (LNEXT(_lld_el,_lld_no) && (LNEXT(_lld_el,_lld_no) != (char*)(del))) { \ - _lld_el = LNEXT(_lld_el,_lld_no); \ - } \ - if (LNEXT(_lld_el,_lld_no)) { \ - LNEXT(_lld_el,_lld_no) = (char*)((del)->next); \ - } \ - } \ -} while (0) - -#define LL_FOREACH(head,el) \ - for(el=head;el;el=el->next) - -/****************************************************************************** - * doubly linked list macros (non-circular) * - *****************************************************************************/ -#define DL_PREPEND(head,add) \ -do { \ - (add)->next = head; \ - if (head) { \ - (add)->prev = (head)->prev; \ - (head)->prev = (add); \ - } else { \ - (add)->prev = (add); \ - } \ - (head) = (add); \ -} while (0) - -#define DL_APPEND(head,add) \ -do { \ - if (head) { \ - (add)->prev = (head)->prev; \ - (head)->prev->next = (add); \ - (head)->prev = (add); \ - (add)->next = NULL; \ - } else { \ - (head)=(add); \ - (head)->prev = (head); \ - (head)->next = NULL; \ - } \ -} while (0); - -#define DL_DELETE(head,del) \ -do { \ - if ((del)->prev == (del)) { \ - (head)=NULL; \ - } else if ((del)==(head)) { \ - (del)->next->prev = (del)->prev; \ - (head) = (del)->next; \ - } else { \ - (del)->prev->next = (del)->next; \ - if ((del)->next) { \ - (del)->next->prev = (del)->prev; \ - } else { \ - (head)->prev = (del)->prev; \ - } \ - } \ -} while (0); - - -#define DL_FOREACH(head,el) \ - for(el=head;el;el=el->next) - -/****************************************************************************** - * circular doubly linked list macros * - *****************************************************************************/ -#define CDL_PREPEND(head,add) \ -do { \ - if (head) { \ - (add)->prev = (head)->prev; \ - (add)->next = (head); \ - (head)->prev = (add); \ - (add)->prev->next = (add); \ - } else { \ - (add)->prev = (add); \ - (add)->next = (add); \ - } \ -(head)=(add); \ -} while (0) - -#define CDL_DELETE(head,del) \ -do { \ - if ( ((head)==(del)) && ((head)->next == (head))) { \ - (head) = 0L; \ - } else { \ - (del)->next->prev = (del)->prev; \ - (del)->prev->next = (del)->next; \ - if ((del) == (head)) (head)=(del)->next; \ - } \ -} while (0); - -#define CDL_FOREACH(head,el) \ - for(el=head;el;el= (el->next==head ? 0L : el->next)) - - -#endif /* UTLIST_H */ - diff --git a/src/rt/util/hash_map.h b/src/rt/util/hash_map.h deleted file mode 100644 index e5bef45c1c3c5..0000000000000 --- a/src/rt/util/hash_map.h +++ /dev/null @@ -1,207 +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. - -/** - * A C++ wrapper around uthash. - */ - -#ifndef HASH_MAP -#define HASH_MAP - -#include -#include "../uthash/uthash.h" - -template class hash_map { - struct map_entry { - K key; - V value; - UT_hash_handle hh; - }; - map_entry * _head; -private: - // private and left undefined to disable copying - hash_map(const hash_map& rhs); - hash_map& operator=(const hash_map& rhs); -public: - hash_map(); - ~hash_map(); - - /** - * Associates a value with the specified key in this hash map. - * If a mapping already exists the old value is replaced. - * - * returns: - * true if the mapping was successfully created and false otherwise. - */ - bool put(K key, V value); - - /** - * Updates the value associated with the specified key in this hash map. - * - * returns: - * true if the value was updated, or false if the key was not found. - */ - bool set(K key, V value); - - /** - * Gets the value associated with the specified key in this hash map. - * - * returns: - * true if the value was found and updates the specified *value parameter - * with the associated value, or false otherwise. - */ - bool get(K key, V *value) const; - - /** - * Removes a key-value pair from this hash map. - * - * returns: - * true if a key-value pair exists and updates the specified - * *key and *value parameters, or false otherwise. - */ - bool pop(K *key, V *value); - - /** - * Checks if the specified key exists in this hash map. - * - * returns: - * true if the specified key exists in this hash map, or false otherwise. - */ - bool contains(K key) const; - - /** - * Removes the value associated with the specified key from this hash map. - * - * returns: - * true if the specified key exists and updates the specified *old_value - * parameter with the associated value, or false otherwise. - */ - bool remove(K key, V *old_value); - bool remove(K key); - - /** - * Returns the number of key-value pairs in this hash map. - */ - size_t count() const; - - bool is_empty() const { - return count() == 0; - } - - /** - * Clears all the key-value pairs in this hash map. - * - * returns: - * the number of deleted key-value pairs. - */ - size_t clear(); -}; - -template -hash_map::hash_map() { - _head = NULL; -} - -template -hash_map::~hash_map() { - clear(); -} - -template bool -hash_map::put(K key, V value) { - if (contains(key)) { - return set(key, value); - } - map_entry *entry = (map_entry *) malloc(sizeof(map_entry)); - entry->key = key; - entry->value = value; - HASH_ADD(hh, _head, key, sizeof(K), entry); - return true; -} - -template bool -hash_map::get(K key, V *value) const { - map_entry *entry = NULL; - HASH_FIND(hh, _head, &key, sizeof(K), entry); - if (entry == NULL) { - return false; - } - *value = entry->value; - return true; -} - -template bool -hash_map::set(K key, V value) { - map_entry *entry = NULL; - HASH_FIND(hh, _head, &key, sizeof(K), entry); - if (entry == NULL) { - return false; - } - entry->value = value; - return true; -} - -template bool -hash_map::contains(K key) const { - V value; - return get(key, &value); -} - -template bool -hash_map::remove(K key, V *old_value) { - map_entry *entry = NULL; - HASH_FIND(hh, _head, &key, sizeof(K), entry); - if (entry == NULL) { - return false; - } - *old_value = entry->value; - HASH_DEL(_head, entry); - free(entry); - return true; -} - -template bool -hash_map::pop(K *key, V *value) { - if (is_empty()) { - return false; - } - map_entry *entry = _head; - HASH_DEL(_head, entry); - *key = entry->key; - *value = entry->value; - free(entry); - return true; -} - -template bool -hash_map::remove(K key) { - V old_value; - return remove(key, &old_value); -} - -template size_t -hash_map::count() const { - return HASH_CNT(hh, _head); -} - -template size_t -hash_map::clear() { - size_t deleted_entries = 0; - while (_head != NULL) { - map_entry *entry = _head; - HASH_DEL(_head, entry); - free(entry); - deleted_entries ++; - } - assert(count() == 0); - return deleted_entries; -} - -#endif /* HASH_MAP */ diff --git a/src/test/auxiliary/cci_capture_clause.rs b/src/test/auxiliary/cci_capture_clause.rs index fd319aacd05f8..f2749ed1d0c05 100644 --- a/src/test/auxiliary/cci_capture_clause.rs +++ b/src/test/auxiliary/cci_capture_clause.rs @@ -8,11 +8,11 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use core::pipes::*; +use core::comm::*; -pub fn foo(x: T) -> Port { +pub fn foo(x: T) -> Port { let (p, c) = stream(); - do task::spawn() |copy x| { + do task::spawn() { c.send(x); } p diff --git a/src/test/auxiliary/cci_class_6.rs b/src/test/auxiliary/cci_class_6.rs index f4b27e04c1304..3ab101bc0b4e8 100644 --- a/src/test/auxiliary/cci_class_6.rs +++ b/src/test/auxiliary/cci_class_6.rs @@ -27,7 +27,7 @@ pub mod kitties { cat { meows: in_x, how_hungry: in_y, - info: move in_info + info: in_info } } } diff --git a/src/test/auxiliary/cci_class_cast.rs b/src/test/auxiliary/cci_class_cast.rs index c0140bff5b13a..5256944b18ecb 100644 --- a/src/test/auxiliary/cci_class_cast.rs +++ b/src/test/auxiliary/cci_class_cast.rs @@ -17,7 +17,7 @@ pub mod kitty { name : ~str, } - pub impl cat : ToStr { + pub impl ToStr for cat { pure fn to_str(&self) -> ~str { copy self.name } } diff --git a/src/test/auxiliary/cci_nested_lib.rs b/src/test/auxiliary/cci_nested_lib.rs index 8f1c3d5bb5f52..1be18459e407c 100644 --- a/src/test/auxiliary/cci_nested_lib.rs +++ b/src/test/auxiliary/cci_nested_lib.rs @@ -16,11 +16,11 @@ pub struct Entry {key: A, value: B} pub struct alist { eq_fn: fn@(A,A) -> bool, data: DVec> } -pub fn alist_add(lst: alist, k: A, v: B) { +pub fn alist_add(lst: alist, k: A, v: B) { lst.data.push(Entry{key:k, value:v}); } -pub fn alist_get(lst: alist, k: A) -> B { +pub fn alist_get(lst: alist, k: A) -> B { let eq_fn = lst.eq_fn; for lst.data.each |entry| { if eq_fn(entry.key, k) { return entry.value; } @@ -29,13 +29,13 @@ pub fn alist_get(lst: alist, k: A) -> B { } #[inline] -pub fn new_int_alist() -> alist { +pub fn new_int_alist() -> alist { fn eq_int(&&a: int, &&b: int) -> bool { a == b } return alist {eq_fn: eq_int, data: DVec()}; } #[inline] -pub fn new_int_alist_2() -> alist { +pub fn new_int_alist_2() -> alist { #[inline] fn eq_int(&&a: int, &&b: int) -> bool { a == b } return alist {eq_fn: eq_int, data: DVec()}; diff --git a/src/test/auxiliary/crate-method-reexport-grrrrrrr2.rs b/src/test/auxiliary/crate-method-reexport-grrrrrrr2.rs index 847b6d5b2bbae..2b3fd47e5bc49 100644 --- a/src/test/auxiliary/crate-method-reexport-grrrrrrr2.rs +++ b/src/test/auxiliary/crate-method-reexport-grrrrrrr2.rs @@ -19,7 +19,7 @@ pub mod name_pool { fn add(s: ~str); } - pub impl name_pool: add { + pub impl add for name_pool { fn add(s: ~str) { } } @@ -34,7 +34,7 @@ pub mod rust { fn cx(); } - pub impl rt: cx { + pub impl cx for rt { fn cx() { } } diff --git a/src/test/auxiliary/issue-2526.rs b/src/test/auxiliary/issue-2526.rs index f9d08713852e4..958fb75b9d233 100644 --- a/src/test/auxiliary/issue-2526.rs +++ b/src/test/auxiliary/issue-2526.rs @@ -23,13 +23,13 @@ impl Drop for arc_destruct { fn finalize(&self) {} } -fn arc_destruct(data: int) -> arc_destruct { +fn arc_destruct(data: int) -> arc_destruct { arc_destruct { _data: data } } -fn arc(_data: T) -> arc_destruct { +fn arc(_data: T) -> arc_destruct { arc_destruct(0) } diff --git a/src/test/auxiliary/issue-2631-a.rs b/src/test/auxiliary/issue-2631-a.rs index 8679d3a778607..b1fb7a82c5c8b 100644 --- a/src/test/auxiliary/issue-2631-a.rs +++ b/src/test/auxiliary/issue-2631-a.rs @@ -19,6 +19,6 @@ use std::oldmap::HashMap; pub type header_map = HashMap<~str, @DVec<@~str>>; // the unused ty param is necessary so this gets monomorphized -pub fn request(req: header_map) { +pub fn request(req: header_map) { let _x = copy *(copy *req.get(&~"METHOD"))[0u]; } diff --git a/src/test/auxiliary/issue-3012-1.rs b/src/test/auxiliary/issue-3012-1.rs index 618b9391ba14a..cbc1c4b2fec44 100644 --- a/src/test/auxiliary/issue-3012-1.rs +++ b/src/test/auxiliary/issue-3012-1.rs @@ -16,7 +16,7 @@ pub mod socket { sockfd: libc::c_int, } - pub impl socket_handle : Drop { + pub impl Drop for socket_handle { fn finalize(&self) { /* c::close(self.sockfd); */ } diff --git a/src/test/auxiliary/issue2170lib.rs b/src/test/auxiliary/issue2170lib.rs index bf5a664320429..d664ad62edf1d 100644 --- a/src/test/auxiliary/issue2170lib.rs +++ b/src/test/auxiliary/issue2170lib.rs @@ -15,7 +15,7 @@ pub struct rsrc { x: i32, } -pub impl rsrc : Drop { +pub impl Drop for rsrc { fn finalize(&self) { foo(self.x); } diff --git a/src/test/auxiliary/issue4516_ty_param_lib.rs b/src/test/auxiliary/issue4516_ty_param_lib.rs index 2e3c7eedfcc38..0e2105243e703 100644 --- a/src/test/auxiliary/issue4516_ty_param_lib.rs +++ b/src/test/auxiliary/issue4516_ty_param_lib.rs @@ -8,6 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -pub fn to_closure(x: A) -> @fn() -> A { +pub fn to_closure(x: A) -> @fn() -> A { fn@() -> A { copy x } } diff --git a/src/test/auxiliary/issue_3882.rs b/src/test/auxiliary/issue_3882.rs index c2b95e4e7d653..6d232c34b47e0 100644 --- a/src/test/auxiliary/issue_3882.rs +++ b/src/test/auxiliary/issue_3882.rs @@ -10,10 +10,10 @@ mod issue_3882 { struct Completions { - mut len: libc::size_t, + len: libc::size_t, } extern mod c { - fn linenoiseAddCompletion(lc: *Completions); + fn linenoiseAddCompletion(lc: *mut Completions); } } diff --git a/src/test/auxiliary/static-methods-crate.rs b/src/test/auxiliary/static-methods-crate.rs index f06f2e31b710f..dbfff4e8acaaf 100644 --- a/src/test/auxiliary/static-methods-crate.rs +++ b/src/test/auxiliary/static-methods-crate.rs @@ -33,7 +33,7 @@ impl read for bool { } } -pub fn read(s: ~str) -> T { +pub fn read(s: ~str) -> T { match read::readMaybe(s) { Some(x) => x, _ => fail!(~"read failed!") diff --git a/src/test/auxiliary/trait_inheritance_auto_xc_aux.rs b/src/test/auxiliary/trait_inheritance_auto_xc_aux.rs index 97a363f6b0c45..3e26a09fb8f0d 100644 --- a/src/test/auxiliary/trait_inheritance_auto_xc_aux.rs +++ b/src/test/auxiliary/trait_inheritance_auto_xc_aux.rs @@ -14,4 +14,4 @@ trait Baz { fn h() -> int; } trait Quux: Foo Bar Baz { } -impl Quux for T { } +impl Quux for T { } diff --git a/src/test/auxiliary/trait_inheritance_overloading_xc.rs b/src/test/auxiliary/trait_inheritance_overloading_xc.rs index 950f4b6bbe72c..2ed3b3b1f5c98 100644 --- a/src/test/auxiliary/trait_inheritance_overloading_xc.rs +++ b/src/test/auxiliary/trait_inheritance_overloading_xc.rs @@ -17,25 +17,25 @@ pub struct MyInt { val: int } -pub impl MyInt : Add { +pub impl Add for MyInt { pure fn add(&self, other: &MyInt) -> MyInt { mi(self.val + other.val) } } -pub impl MyInt : Sub { +pub impl Sub for MyInt { pure fn sub(&self, other: &MyInt) -> MyInt { mi(self.val - other.val) } } -pub impl MyInt : Mul { +pub impl Mul for MyInt { pure fn mul(&self, other: &MyInt) -> MyInt { mi(self.val * other.val) } } -pub impl MyInt : Eq { +pub 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) } } -pub impl MyInt : MyNum; +pub impl MyNum for MyInt; pure fn mi(v: int) -> MyInt { MyInt { val: v } } diff --git a/src/test/bench/core-map.rs b/src/test/bench/core-map.rs index 68ba40749f2dd..92e91929f1a29 100644 --- a/src/test/bench/core-map.rs +++ b/src/test/bench/core-map.rs @@ -302,10 +302,10 @@ fn main() { } }; - let seed = ~[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; + let seed = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; { - let rng = rand::seeded_rng(&seed); + 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); @@ -313,7 +313,7 @@ fn main() { } { - let rng = rand::seeded_rng(&seed); + 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); @@ -321,7 +321,7 @@ fn main() { } { - let rng = rand::seeded_rng(&seed); + 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); diff --git a/src/test/bench/core-set.rs b/src/test/bench/core-set.rs new file mode 100644 index 0000000000000..2845596e78007 --- /dev/null +++ b/src/test/bench/core-set.rs @@ -0,0 +1,180 @@ +// 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. + +extern mod std; +use core::hashmap::linear::LinearSet; +use std::bitv::BitvSet; +use std::treemap::TreeSet; +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); +} + +impl Results { + fn bench_int>(&mut self, rng: @rand::Rng, num_keys: uint, + rand_cap: uint, f: fn() -> T) { + { + let mut set = f(); + do timed(&mut self.sequential_ints) { + for uint::range(0, num_keys) |i| { + set.insert(i); + } + + for uint::range(0, num_keys) |i| { + assert set.contains(&i); + } + } + } + + { + let mut set = f(); + do timed(&mut self.random_ints) { + for num_keys.times { + set.insert((rng.next() as uint) % rand_cap); + } + } + } + + { + let mut set = f(); + for uint::range(0, num_keys) |i| { + set.insert(i); + } + + do timed(&mut self.delete_ints) { + for uint::range(0, num_keys) |i| { + assert set.remove(&i); + } + } + } + } + + fn bench_str>(&mut self, rng: @rand::Rng, num_keys: uint, + f: fn() -> T) { + { + let mut set = f(); + do timed(&mut self.sequential_strings) { + for uint::range(0, num_keys) |i| { + let s = uint::to_str(i); + set.insert(s); + } + + for uint::range(0, num_keys) |i| { + let s = uint::to_str(i); + assert set.contains(&s); + } + } + } + + { + let mut set = f(); + do timed(&mut self.random_strings) { + for num_keys.times { + let s = uint::to_str(rng.next() as uint); + set.insert(s); + } + } + } + + { + let mut set = f(); + for uint::range(0, num_keys) |i| { + set.insert(uint::to_str(i)); + } + do timed(&mut self.delete_strings) { + for uint::range(0, num_keys) |i| { + assert set.remove(&uint::to_str(i)); + } + } + } + } +} + +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, + } +} + +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]; + let max = 200000; + + { + let rng = rand::seeded_rng(seed); + let mut results = empty_results(); + results.bench_int(rng, num_keys, max, || LinearSet::new::()); + results.bench_str(rng, num_keys, || LinearSet::new::<~str>()); + write_results("core::hashmap::LinearSet", &results); + } + + { + let rng = rand::seeded_rng(seed); + let mut results = empty_results(); + results.bench_int(rng, num_keys, max, || TreeSet::new::()); + results.bench_str(rng, num_keys, || TreeSet::new::<~str>()); + write_results("std::treemap::TreeSet", &results); + } + + { + let rng = rand::seeded_rng(seed); + let mut results = empty_results(); + results.bench_int(rng, num_keys, max, || BitvSet::new()); + write_results("std::bitv::BitvSet", &results); + } +} diff --git a/src/test/bench/core-std.rs b/src/test/bench/core-std.rs index fafda39993ee2..bd8757d51b743 100644 --- a/src/test/bench/core-std.rs +++ b/src/test/bench/core-std.rs @@ -24,7 +24,7 @@ macro_rules! bench ( fn main() { let argv = os::args(); - let tests = vec::view(argv, 1, argv.len()); + let tests = vec::slice(argv, 1, argv.len()); bench!(shift_push); bench!(read_line); diff --git a/src/test/bench/core-vec-append.rs b/src/test/bench/core-vec-append.rs index b8766d86b017a..1dfcb31f19638 100644 --- a/src/test/bench/core-vec-append.rs +++ b/src/test/bench/core-vec-append.rs @@ -27,7 +27,7 @@ fn collect_dvec(num: uint) -> ~[uint] { for uint::range(0u, num) |i| { result.push(i); } - return dvec::unwrap(move result); + return dvec::unwrap(result); } fn main() { diff --git a/src/test/bench/graph500-bfs.rs b/src/test/bench/graph500-bfs.rs index e88cb62db7345..52d08c548d72a 100644 --- a/src/test/bench/graph500-bfs.rs +++ b/src/test/bench/graph500-bfs.rs @@ -1,3 +1,5 @@ +// xfail-pretty + // 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. @@ -23,7 +25,6 @@ use std::time; use std::oldmap; use std::oldmap::Map; use std::oldmap::HashMap; -use std::deque; use std::deque::Deque; use std::par; use core::io::WriterUtil; @@ -124,24 +125,24 @@ fn bfs(graph: graph, key: node_id) -> bfs_result { let mut marks : ~[node_id] = vec::from_elem(vec::len(graph), -1i64); - let Q = deque::create(); + let mut q = Deque::new(); - Q.add_back(key); + q.add_back(key); marks[key] = key; - while Q.size() > 0 { - let t = Q.pop_front(); + while !q.is_empty() { + let t = q.pop_front(); do graph[t].each() |k| { if marks[*k] == -1i64 { marks[*k] = t; - Q.add_back(*k); + q.add_back(*k); } true }; } - move marks + marks } /** @@ -260,7 +261,7 @@ fn pbfs(&&graph: arc::ARC, key: node_id) -> bfs_result { i += 1; let old_len = colors.len(); - let color = arc::ARC(move colors); + let color = arc::ARC(colors); let color_vec = arc::get(&color); // FIXME #3387 requires this temp colors = do par::mapi(*color_vec) { diff --git a/src/test/bench/msgsend-pipes-shared.rs b/src/test/bench/msgsend-pipes-shared.rs index 5b6c5210dbffb..4bbd22786a563 100644 --- a/src/test/bench/msgsend-pipes-shared.rs +++ b/src/test/bench/msgsend-pipes-shared.rs @@ -24,10 +24,10 @@ extern mod std; use io::Writer; use io::WriterUtil; -use pipes::{Port, Chan, SharedChan}; +use comm::{Port, Chan, SharedChan}; macro_rules! move_out ( - { $x:expr } => { unsafe { let y = move *ptr::addr_of(&($x)); move y } } + { $x:expr } => { unsafe { let y = *ptr::addr_of(&($x)); y } } ) enum request { @@ -36,7 +36,7 @@ enum request { stop } -fn server(requests: Port, responses: pipes::Chan) { +fn server(requests: Port, responses: comm::Chan) { let mut count = 0u; let mut done = false; while !done { @@ -55,10 +55,10 @@ fn server(requests: Port, responses: pipes::Chan) { } fn run(args: &[~str]) { - let (from_child, to_parent) = pipes::stream(); - let (from_parent, to_child) = pipes::stream(); + let (from_child, to_parent) = comm::stream(); + let (from_parent, to_child) = comm::stream(); - let to_child = SharedChan(move to_child); + let to_child = SharedChan(to_child); let size = uint::from_str(args[1]).get(); let workers = uint::from_str(args[2]).get(); @@ -68,8 +68,8 @@ fn run(args: &[~str]) { for uint::range(0, workers) |_i| { let to_child = to_child.clone(); do task::task().future_result(|+r| { - worker_results.push(move r); - }).spawn |move to_child| { + worker_results.push(r); + }).spawn || { for uint::range(0, size / workers) |_i| { //error!("worker %?: sending %? bytes", i, num_bytes); to_child.send(bytes(num_bytes)); @@ -77,7 +77,7 @@ fn run(args: &[~str]) { //error!("worker %? exiting", i); }; } - do task::spawn |move from_parent, move to_parent| { + do task::spawn || { server(from_parent, to_parent); } diff --git a/src/test/bench/msgsend-pipes.rs b/src/test/bench/msgsend-pipes.rs index 269d02ae45f33..a969368ebaca3 100644 --- a/src/test/bench/msgsend-pipes.rs +++ b/src/test/bench/msgsend-pipes.rs @@ -20,10 +20,10 @@ extern mod std; use io::Writer; use io::WriterUtil; -use pipes::{Port, PortSet, Chan}; +use comm::{Port, PortSet, Chan, stream}; macro_rules! move_out ( - { $x:expr } => { unsafe { let y = move *ptr::addr_of(&($x)); move y } } + { $x:expr } => { unsafe { let y = *ptr::addr_of(&($x)); y } } ) enum request { @@ -32,7 +32,7 @@ enum request { stop } -fn server(requests: PortSet, responses: pipes::Chan) { +fn server(requests: PortSet, responses: Chan) { let mut count = 0; let mut done = false; while !done { @@ -51,10 +51,10 @@ fn server(requests: PortSet, responses: pipes::Chan) { } fn run(args: &[~str]) { - let (from_child, to_parent) = pipes::stream(); - let (from_parent_, to_child) = pipes::stream(); + let (from_child, to_parent) = stream(); + let (from_parent_, to_child) = stream(); let from_parent = PortSet(); - from_parent.add(move from_parent_); + from_parent.add(from_parent_); let size = uint::from_str(args[1]).get(); let workers = uint::from_str(args[2]).get(); @@ -62,11 +62,11 @@ fn run(args: &[~str]) { let start = std::time::precise_time_s(); let mut worker_results = ~[]; for uint::range(0, workers) |_i| { - let (from_parent_, to_child) = pipes::stream(); - from_parent.add(move from_parent_); + let (from_parent_, to_child) = stream(); + from_parent.add(from_parent_); do task::task().future_result(|+r| { - worker_results.push(move r); - }).spawn |move to_child| { + worker_results.push(r); + }).spawn || { for uint::range(0, size / workers) |_i| { //error!("worker %?: sending %? bytes", i, num_bytes); to_child.send(bytes(num_bytes)); @@ -74,7 +74,7 @@ fn run(args: &[~str]) { //error!("worker %? exiting", i); }; } - do task::spawn |move from_parent, move to_parent| { + do task::spawn || { server(from_parent, to_parent); } diff --git a/src/test/bench/msgsend-ring-mutex-arcs.rs b/src/test/bench/msgsend-ring-mutex-arcs.rs index 5e1ac20f5eb9f..9b6fee5e23bc1 100644 --- a/src/test/bench/msgsend-ring-mutex-arcs.rs +++ b/src/test/bench/msgsend-ring-mutex-arcs.rs @@ -40,7 +40,7 @@ fn recv(p: &pipe) -> uint { fn init() -> (pipe,pipe) { let m = arc::MutexARC(~[]); - ((&m).clone(), move m) + ((&m).clone(), m) } @@ -48,18 +48,18 @@ fn thread_ring(i: uint, count: uint, +num_chan: pipe, +num_port: pipe) { - let mut num_chan = move Some(move num_chan); - let mut num_port = move Some(move num_port); + let mut num_chan = Some(num_chan); + let mut num_port = Some(num_port); // Send/Receive lots of messages. for uint::range(0u, count) |j| { //error!("task %?, iter %?", i, j); let mut num_chan2 = option::swap_unwrap(&mut num_chan); let mut num_port2 = option::swap_unwrap(&mut num_port); send(&num_chan2, i * j); - num_chan = Some(move num_chan2); + num_chan = Some(num_chan2); let _n = recv(&num_port2); //log(error, _n); - num_port = Some(move num_port2); + num_port = Some(num_port2); }; } @@ -77,7 +77,7 @@ fn main() { let msg_per_task = uint::from_str(args[2]).get(); let (num_chan, num_port) = init(); - let mut num_chan = Some(move num_chan); + let mut num_chan = Some(num_chan); let start = time::precise_time_s(); @@ -89,22 +89,22 @@ fn main() { let (new_chan, num_port) = init(); let num_chan2 = ~mut None; *num_chan2 <-> num_chan; - let num_port = ~mut Some(move num_port); - let new_future = future::spawn(|move num_chan2, move num_port| { + let num_port = ~mut Some(num_port); + let new_future = do future::spawn() || { let mut num_chan = None; num_chan <-> *num_chan2; let mut num_port1 = None; num_port1 <-> *num_port; thread_ring(i, msg_per_task, - option::unwrap(move num_chan), - option::unwrap(move num_port1)) - }); - futures.push(move new_future); - num_chan = Some(move new_chan); + option::unwrap(num_chan), + option::unwrap(num_port1)) + }; + futures.push(new_future); + num_chan = Some(new_chan); }; // do our iteration - thread_ring(0, msg_per_task, option::unwrap(move num_chan), move num_port); + thread_ring(0, msg_per_task, option::unwrap(num_chan), num_port); // synchronize for futures.each |f| { f.get() }; diff --git a/src/test/bench/msgsend-ring-pipes.rs b/src/test/bench/msgsend-ring-pipes.rs index e9281a0c41736..0f7c41f5997a8 100644 --- a/src/test/bench/msgsend-ring-pipes.rs +++ b/src/test/bench/msgsend-ring-pipes.rs @@ -20,7 +20,7 @@ extern mod std; use std::time; use std::future; -use pipes::recv; +use core::pipes::recv; proto! ring ( num:send { @@ -29,15 +29,15 @@ proto! ring ( ) macro_rules! move_out ( - ($x:expr) => { unsafe { let y = move *ptr::addr_of(&$x); move y } } + ($x:expr) => { unsafe { let y = *ptr::addr_of(&$x); y } } ) fn thread_ring(i: uint, count: uint, +num_chan: ring::client::num, +num_port: ring::server::num) { - let mut num_chan = move Some(move num_chan); - let mut num_port = move Some(move num_port); + let mut num_chan = Some(num_chan); + let mut num_port = Some(num_port); // Send/Receive lots of messages. for uint::range(0, count) |j| { //error!("task %?, iter %?", i, j); @@ -45,9 +45,9 @@ fn thread_ring(i: uint, let mut num_port2 = None; num_chan2 <-> num_chan; num_port2 <-> num_port; - num_chan = Some(ring::client::num(option::unwrap(move num_chan2), i * j)); - let port = option::unwrap(move num_port2); - match recv(move port) { + num_chan = Some(ring::client::num(option::unwrap(num_chan2), i * j)); + let port = option::unwrap(num_port2); + match recv(port) { ring::num(_n, p) => { //log(error, _n); num_port = Some(move_out!(p)); @@ -70,7 +70,7 @@ fn main() { let msg_per_task = uint::from_str(args[2]).get(); let (num_chan, num_port) = ring::init(); - let mut num_chan = Some(move num_chan); + let mut num_chan = Some(num_chan); let start = time::precise_time_s(); @@ -82,23 +82,22 @@ fn main() { let (new_chan, num_port) = ring::init(); let num_chan2 = ~mut None; *num_chan2 <-> num_chan; - let num_port = ~mut Some(move num_port); - let new_future = do future::spawn - |move num_chan2, move num_port| { + let num_port = ~mut Some(num_port); + let new_future = do future::spawn || { let mut num_chan = None; num_chan <-> *num_chan2; let mut num_port1 = None; num_port1 <-> *num_port; thread_ring(i, msg_per_task, - option::unwrap(move num_chan), - option::unwrap(move num_port1)) + option::unwrap(num_chan), + option::unwrap(num_port1)) }; - futures.push(move new_future); - num_chan = Some(move new_chan); + futures.push(new_future); + num_chan = Some(new_chan); }; // do our iteration - thread_ring(0, msg_per_task, option::unwrap(move num_chan), move num_port); + thread_ring(0, msg_per_task, option::unwrap(num_chan), num_port); // synchronize for futures.each |f| { f.get() }; diff --git a/src/test/bench/msgsend-ring-rw-arcs.rs b/src/test/bench/msgsend-ring-rw-arcs.rs index ff88eea598dfb..eaae8370d6b8b 100644 --- a/src/test/bench/msgsend-ring-rw-arcs.rs +++ b/src/test/bench/msgsend-ring-rw-arcs.rs @@ -40,7 +40,7 @@ fn recv(p: &pipe) -> uint { fn init() -> (pipe,pipe) { let x = arc::RWARC(~[]); - ((&x).clone(), move x) + ((&x).clone(), x) } @@ -48,18 +48,18 @@ fn thread_ring(i: uint, count: uint, +num_chan: pipe, +num_port: pipe) { - let mut num_chan = move Some(move num_chan); - let mut num_port = move Some(move num_port); + let mut num_chan = Some(num_chan); + let mut num_port = Some(num_port); // Send/Receive lots of messages. for uint::range(0u, count) |j| { //error!("task %?, iter %?", i, j); let mut num_chan2 = option::swap_unwrap(&mut num_chan); let mut num_port2 = option::swap_unwrap(&mut num_port); send(&num_chan2, i * j); - num_chan = Some(move num_chan2); + num_chan = Some(num_chan2); let _n = recv(&num_port2); //log(error, _n); - num_port = Some(move num_port2); + num_port = Some(num_port2); }; } @@ -77,7 +77,7 @@ fn main() { let msg_per_task = uint::from_str(args[2]).get(); let (num_chan, num_port) = init(); - let mut num_chan = Some(move num_chan); + let mut num_chan = Some(num_chan); let start = time::precise_time_s(); @@ -89,23 +89,22 @@ fn main() { let (new_chan, num_port) = init(); let num_chan2 = ~mut None; *num_chan2 <-> num_chan; - let num_port = ~mut Some(move num_port); - let new_future = do future::spawn - |move num_chan2, move num_port| { + let num_port = ~mut Some(num_port); + let new_future = do future::spawn || { let mut num_chan = None; num_chan <-> *num_chan2; let mut num_port1 = None; num_port1 <-> *num_port; thread_ring(i, msg_per_task, - option::unwrap(move num_chan), - option::unwrap(move num_port1)) + option::unwrap(num_chan), + option::unwrap(num_port1)) }; - futures.push(move new_future); - num_chan = Some(move new_chan); + futures.push(new_future); + num_chan = Some(new_chan); }; // do our iteration - thread_ring(0, msg_per_task, option::unwrap(move num_chan), move num_port); + thread_ring(0, msg_per_task, option::unwrap(num_chan), num_port); // synchronize for futures.each |f| { f.get() }; diff --git a/src/test/bench/noise.rs b/src/test/bench/noise.rs index a07dcee35f4d3..39caba9273293 100644 --- a/src/test/bench/noise.rs +++ b/src/test/bench/noise.rs @@ -35,8 +35,8 @@ fn Noise2DContext() -> ~Noise2DContext { r.shuffle_mut(permutations); ~Noise2DContext{ - rgradients: move rgradients, - permutations: move permutations, + rgradients: rgradients, + permutations: permutations, } } diff --git a/src/test/bench/pingpong.rs b/src/test/bench/pingpong.rs index 3d367c546838b..f95bc3fc35a18 100644 --- a/src/test/bench/pingpong.rs +++ b/src/test/bench/pingpong.rs @@ -10,13 +10,11 @@ // Compare bounded and unbounded protocol performance. -#[allow(structural_records)]; // Pipes -// Until a snapshot // xfail-pretty extern mod std; -use pipes::{spawn_service, recv}; +use core::pipes::{spawn_service, recv}; use std::time::precise_time_s; proto! pingpong ( @@ -45,17 +43,17 @@ proto! pingpong_unbounded ( // This stuff should go in libcore::pipes macro_rules! move_it ( - { $x:expr } => { let t = move *ptr::addr_of(&($x)); move t } + { $x:expr } => { let t = *ptr::addr_of(&($x)); t } ) macro_rules! follow ( { $($message:path($($x: ident),+) -> $next:ident $e:expr)+ } => ( - |m| match move m { - $(Some($message($($x,)* move next)) => { - let $next = move next; - move $e })+ + |m| match m { + $(Some($message($($x,)* next)) => { + let $next = next; + $e })+ _ => { fail!() } } ); @@ -63,18 +61,18 @@ macro_rules! follow ( { $($message:path -> $next:ident $e:expr)+ } => ( - |m| match move m { - $(Some($message(move next)) => { - let $next = move next; - move $e })+ + |m| match m { + $(Some($message(next)) => { + let $next = next; + $e })+ _ => { fail!() } } ) ) -fn switch(+endp: pipes::RecvPacketBuffered, +fn switch(+endp: core::pipes::RecvPacketBuffered, f: fn(+v: Option) -> U) -> U { - f(pipes::try_recv(move endp)) + f(core::pipes::try_recv(endp)) } // Here's the benchmark @@ -84,10 +82,10 @@ fn bounded(count: uint) { let mut ch = do spawn_service(init) |ch| { let mut count = count; - let mut ch = move ch; + let mut ch = ch; while count > 0 { - ch = switch(move ch, follow! ( - ping -> next { server::pong(move next) } + ch = switch(ch, follow! ( + ping -> next { server::pong(next) } )); count -= 1; @@ -96,10 +94,10 @@ fn bounded(count: uint) { let mut count = count; while count > 0 { - let ch_ = client::ping(move ch); + let ch_ = client::ping(ch); - ch = switch(move ch_, follow! ( - pong -> next { move next } + ch = switch(ch_, follow! ( + pong -> next { next } )); count -= 1; @@ -111,10 +109,10 @@ fn unbounded(count: uint) { let mut ch = do spawn_service(init) |ch| { let mut count = count; - let mut ch = move ch; + let mut ch = ch; while count > 0 { - ch = switch(move ch, follow! ( - ping -> next { server::pong(move next) } + ch = switch(ch, follow! ( + ping -> next { server::pong(next) } )); count -= 1; @@ -123,10 +121,10 @@ fn unbounded(count: uint) { let mut count = count; while count > 0 { - let ch_ = client::ping(move ch); + let ch_ = client::ping(ch); - ch = switch(move ch_, follow! ( - pong -> next { move next } + ch = switch(ch_, follow! ( + pong -> next { next } )); count -= 1; diff --git a/src/test/bench/shootout-chameneos-redux.rs b/src/test/bench/shootout-chameneos-redux.rs index 27111ff3b6d45..42a1e4b504660 100644 --- a/src/test/bench/shootout-chameneos-redux.rs +++ b/src/test/bench/shootout-chameneos-redux.rs @@ -15,7 +15,7 @@ use std::oldmap; use std::oldmap::HashMap; use std::sort; use std::cell::Cell; -use core::pipes::*; +use core::comm::*; fn print_complements() { let all = ~[Blue, Red, Yellow]; @@ -156,7 +156,7 @@ fn rendezvous(nn: uint, set: ~[color]) { let to_rendezvous_log = to_rendezvous_log.clone(); let (from_rendezvous, to_creature) = stream(); let from_rendezvous = Cell(from_rendezvous); - do task::spawn |move ii, move col| { + do task::spawn || { creature(ii, col, from_rendezvous.take(), to_rendezvous.clone(), to_rendezvous_log.clone()); } diff --git a/src/test/bench/shootout-fasta.rs b/src/test/bench/shootout-fasta.rs index da2f2d5c3d221..509861e2f470f 100644 --- a/src/test/bench/shootout-fasta.rs +++ b/src/test/bench/shootout-fasta.rs @@ -21,10 +21,10 @@ use io::WriterUtil; fn LINE_LENGTH() -> uint { return 60u; } struct MyRandom { - mut last: u32 + last: u32 } -fn myrandom_next(r: @MyRandom, mx: u32) -> u32 { +fn myrandom_next(r: @mut MyRandom, mx: u32) -> u32 { r.last = (r.last * 3877u32 + 29573u32) % 139968u32; mx * r.last / 139968u32 } @@ -59,7 +59,7 @@ fn select_random(r: u32, genelist: ~[AminoAcids]) -> char { fn make_random_fasta(wr: io::Writer, id: ~str, desc: ~str, genelist: ~[AminoAcids], n: int) { wr.write_line(~">" + id + ~" " + desc); - let rng = @MyRandom {mut last: rand::Rng().next()}; + let rng = @mut MyRandom {last: rand::Rng().next()}; let mut op: ~str = ~""; for uint::range(0u, n as uint) |_i| { str::push_char(&mut op, select_random(myrandom_next(rng, 100u32), diff --git a/src/test/bench/shootout-k-nucleotide-pipes.rs b/src/test/bench/shootout-k-nucleotide-pipes.rs index 3afb86210e1b8..3fe5f7057057d 100644 --- a/src/test/bench/shootout-k-nucleotide-pipes.rs +++ b/src/test/bench/shootout-k-nucleotide-pipes.rs @@ -18,7 +18,7 @@ use std::oldmap; use std::oldmap::HashMap; use std::sort; use io::ReaderUtil; -use pipes::{stream, Port, Chan}; +use comm::{stream, Port, Chan}; use cmp::Ord; // given a map, print a sorted version of it @@ -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), + pure 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), + pure fn le_by_key(kv0: &(TT,UU), kv1: &(TT,UU)) -> bool { let (k0, _) = *kv0; let (k1, _) = *kv1; @@ -42,7 +42,7 @@ fn sort_and_fmt(mm: HashMap<~[u8], uint>, total: uint) -> ~str { } // sort by key, then by value - fn sortKV(orig: ~[(TT,UU)]) -> ~[(TT,UU)] { + fn sortKV(orig: ~[(TT,UU)]) -> ~[(TT,UU)] { return sort::merge_sort(sort::merge_sort(orig, le_by_key), le_by_val); } @@ -77,7 +77,7 @@ fn find(mm: HashMap<~[u8], uint>, key: ~str) -> uint { // given a map, increment the counter for a key fn update_freq(mm: HashMap<~[u8], uint>, key: &[u8]) { - let key = vec::slice(key, 0, key.len()); + let key = vec::slice(key, 0, key.len()).to_vec(); mm.update(key, 1, |v,v1| { v+v1 }); } @@ -90,15 +90,15 @@ fn windows_with_carry(bb: &[u8], nn: uint, let len = vec::len(bb); while ii < len - (nn - 1u) { - it(vec::view(bb, ii, ii+nn)); + it(vec::slice(bb, ii, ii+nn)); ii += 1u; } - return vec::slice(bb, len - (nn - 1u), len); + return vec::slice(bb, len - (nn - 1u), len).to_vec(); } -fn make_sequence_processor(sz: uint, from_parent: pipes::Port<~[u8]>, - to_parent: pipes::Chan<~str>) { +fn make_sequence_processor(sz: uint, from_parent: comm::Port<~[u8]>, + to_parent: comm::Chan<~str>) { let freqs: HashMap<~[u8], uint> = oldmap::HashMap(); let mut carry: ~[u8] = ~[]; @@ -128,7 +128,7 @@ fn make_sequence_processor(sz: uint, from_parent: pipes::Port<~[u8]>, _ => { ~"" } }; - to_parent.send(move buffer); + to_parent.send(buffer); } // given a FASTA file on stdin, process sequence THREE @@ -149,23 +149,23 @@ fn main() { // initialize each sequence sorter let sizes = ~[1,2,3,4,6,12,18]; let streams = vec::map(sizes, |_sz| Some(stream())); - let mut streams = move streams; + let mut streams = streams; let mut from_child = ~[]; let to_child = vec::mapi(sizes, |ii, sz| { let sz = *sz; let mut stream = None; stream <-> streams[ii]; - let (from_child_, to_parent_) = option::unwrap(move stream); + let (from_child_, to_parent_) = option::unwrap(stream); - from_child.push(move from_child_); + from_child.push(from_child_); - let (from_parent, to_child) = pipes::stream(); + let (from_parent, to_child) = comm::stream(); - do task::spawn_with(move from_parent) |move to_parent_, from_parent| { + do task::spawn_with(from_parent) |from_parent| { make_sequence_processor(sz, from_parent, to_parent_); }; - move to_child + to_child }); diff --git a/src/test/bench/shootout-mandelbrot.rs b/src/test/bench/shootout-mandelbrot.rs index 76a7688777218..5e472712fda43 100644 --- a/src/test/bench/shootout-mandelbrot.rs +++ b/src/test/bench/shootout-mandelbrot.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. // @@ -12,17 +12,20 @@ // http://shootout.alioth.debian.org/ // u64q/program.php?test=mandelbrot&lang=python3&id=2 // -// takes 2 optional args: +// takes 3 optional args: // square image size, defaults to 80_u // output path, default is "" (no output), "-" means stdout +// depth (max iterations per pixel), defaults to 50_u // -// in the shootout, they use 16000 as image size +// in the shootout, they use 16000 as image size, 50 as depth, +// and write to stdout: +// +// ./shootout_mandelbrot 16000 "-" 50 > /tmp/mandel.pbm // // writes pbm image to output path -extern mod std; use io::WriterUtil; -use std::oldmap::HashMap; +use core::hashmap::linear::LinearMap; struct cmplx { re: f64, @@ -54,28 +57,26 @@ pure fn cabs(x: cmplx) -> f64 x.re*x.re + x.im*x.im } -fn mb(x: cmplx) -> bool +fn mb(x: cmplx, depth: uint) -> bool { - let mut z = cmplx {re: 0f64, im: 0f64}; + let mut z = x; let mut i = 0; - let mut in = true; - while i < 50 { - z = z*z + x; - if cabs(z) >= 4f64 { - in = false; - break; + while i < depth { + if cabs(z) >= 4_f64 { + return false; } + z = z*z + x; i += 1; } - in + true } -fn fillbyte(x: cmplx, incr: f64) -> u8 { +fn fillbyte(x: cmplx, incr: f64, depth: uint) -> u8 { let mut rv = 0_u8; let mut i = 0_u8; while i < 8_u8 { let z = cmplx {re: x.re + (i as f64)*incr, im: x.im}; - if mb(z) { + if mb(z, depth) { rv += 1_u8 << (7_u8 - i); } i += 1_u8; @@ -83,15 +84,16 @@ fn fillbyte(x: cmplx, incr: f64) -> u8 { rv } -fn chanmb(i: uint, size: uint) -> Line +fn chanmb(i: uint, size: uint, depth: uint) -> Line { - let mut crv = ~[]; - let incr = 2f64/(size as f64); - let y = incr*(i as f64) - 1f64; - let xincr = 8f64*incr; - for uint::range(0_u, size/8_u) |j| { - let x = cmplx {re: xincr*(j as f64) - 1.5f64, im: y}; - crv.push(fillbyte(x, incr)); + let bsize = size/8_u; + let mut crv = vec::with_capacity(bsize); + let incr = 2_f64/(size as f64); + let y = incr*(i as f64) - 1_f64; + let xincr = 8_f64*incr; + for uint::range(0_u, bsize) |j| { + let x = cmplx {re: xincr*(j as f64) - 1.5_f64, im: y}; + crv.push(fillbyte(x, incr, depth)); }; Line {i:i, b:crv} } @@ -106,7 +108,7 @@ impl io::Writer for Devnull { fn get_type(&self) -> io::WriterType { io::File } } -fn writer(path: ~str, pport: pipes::Port, size: uint) +fn writer(path: ~str, pport: comm::Port, size: uint) { let cout: io::Writer = match path { ~"" => { @@ -121,34 +123,33 @@ fn writer(path: ~str, pport: pipes::Port, size: uint) ~[io::Create, io::Truncate])) } }; - cout.write_line(~"P4"); + cout.write_line("P4"); cout.write_line(fmt!("%u %u", size, size)); - let lines: HashMap = HashMap(); + let mut lines: LinearMap = LinearMap::new(); let mut done = 0_u; let mut i = 0_u; while i < size { let aline = pport.recv(); if aline.i == done { - debug!("W %u", aline.i); + debug!("W %u", done); cout.write(aline.b); done += 1_u; let mut prev = done; while prev <= i { - if lines.contains_key(&prev) { - debug!("WS %u", prev); - cout.write(lines.get(&prev)); - done += 1_u; - lines.remove(&prev); - prev += 1_u; - } - else { - break - } + match lines.pop(&prev) { + Some(pl) => { + debug!("WS %u", prev); + cout.write(pl.b); + done += 1_u; + prev += 1_u; + } + None => break + }; }; } else { debug!("S %u", aline.i); - lines.insert(aline.i, copy aline.b); // FIXME: bad for perf + lines.insert(aline.i, aline); }; i += 1_u; } @@ -157,22 +158,25 @@ fn writer(path: ~str, pport: pipes::Port, size: uint) fn main() { let args = os::args(); let args = if os::getenv(~"RUST_BENCH").is_some() { - ~[~"", ~"4000"] + ~[~"", ~"4000", ~"50"] } else { args }; + let depth = if vec::len(args) < 4_u { 50_u } + else { uint::from_str(args[3]).get() }; + let path = if vec::len(args) < 3_u { ~"" } else { copy args[2] }; // FIXME: bad for perf let size = if vec::len(args) < 2_u { 80_u } else { uint::from_str(args[1]).get() }; - let (pport, pchan) = pipes::stream(); - let pchan = pipes::SharedChan(pchan); + let (pport, pchan) = comm::stream(); + let pchan = comm::SharedChan(pchan); for uint::range(0_u, size) |j| { let cchan = pchan.clone(); - do task::spawn |move cchan| { cchan.send(chanmb(j, size)) }; + do task::spawn { cchan.send(chanmb(j, size, depth)) }; }; writer(path, pport, size); } diff --git a/src/test/bench/shootout-nbody.rs b/src/test/bench/shootout-nbody.rs index 67d3391ed1336..e7b3547ab8c7e 100644 --- a/src/test/bench/shootout-nbody.rs +++ b/src/test/bench/shootout-nbody.rs @@ -170,67 +170,80 @@ mod Body { // was 4 * PI * PI originally pub const DAYS_PER_YEAR: float = 365.24; - pub struct Props - {mut x: float, - mut y: float, - mut z: float, - mut vx: float, - mut vy: float, - mut vz: float, - mass: float} + pub struct Props { + x: float, + y: float, + z: float, + vx: float, + vy: float, + vz: float, + mass: float + } pub fn jupiter() -> Body::Props { - return Props {mut x: 4.84143144246472090e+00, - mut y: -1.16032004402742839e+00, - mut z: -1.03622044471123109e-01, - mut vx: 1.66007664274403694e-03 * DAYS_PER_YEAR, - mut vy: 7.69901118419740425e-03 * DAYS_PER_YEAR, - mut vz: -6.90460016972063023e-05 * DAYS_PER_YEAR, - mass: 9.54791938424326609e-04 * SOLAR_MASS}; + return Props { + x: 4.84143144246472090e+00, + y: -1.16032004402742839e+00, + z: -1.03622044471123109e-01, + vx: 1.66007664274403694e-03 * DAYS_PER_YEAR, + vy: 7.69901118419740425e-03 * DAYS_PER_YEAR, + vz: -6.90460016972063023e-05 * DAYS_PER_YEAR, + mass: 9.54791938424326609e-04 * SOLAR_MASS + }; } pub fn saturn() -> Body::Props { - return Props {mut x: 8.34336671824457987e+00, - mut y: 4.12479856412430479e+00, - mut z: -4.03523417114321381e-01, - mut vx: -2.76742510726862411e-03 * DAYS_PER_YEAR, - mut vy: 4.99852801234917238e-03 * DAYS_PER_YEAR, - mut vz: 2.30417297573763929e-05 * DAYS_PER_YEAR, - mass: 2.85885980666130812e-04 * SOLAR_MASS}; + return Props { + x: 8.34336671824457987e+00, + y: 4.12479856412430479e+00, + z: -4.03523417114321381e-01, + vx: -2.76742510726862411e-03 * DAYS_PER_YEAR, + vy: 4.99852801234917238e-03 * DAYS_PER_YEAR, + vz: 2.30417297573763929e-05 * DAYS_PER_YEAR, + mass: 2.85885980666130812e-04 * SOLAR_MASS + }; } pub fn uranus() -> Body::Props { - return Props {mut x: 1.28943695621391310e+01, - mut y: -1.51111514016986312e+01, - mut z: -2.23307578892655734e-01, - mut vx: 2.96460137564761618e-03 * DAYS_PER_YEAR, - mut vy: 2.37847173959480950e-03 * DAYS_PER_YEAR, - mut vz: -2.96589568540237556e-05 * DAYS_PER_YEAR, - mass: 4.36624404335156298e-05 * SOLAR_MASS}; + return Props { + x: 1.28943695621391310e+01, + y: -1.51111514016986312e+01, + z: -2.23307578892655734e-01, + vx: 2.96460137564761618e-03 * DAYS_PER_YEAR, + vy: 2.37847173959480950e-03 * DAYS_PER_YEAR, + vz: -2.96589568540237556e-05 * DAYS_PER_YEAR, + mass: 4.36624404335156298e-05 * SOLAR_MASS + }; } pub fn neptune() -> Body::Props { - return Props {mut x: 1.53796971148509165e+01, - mut y: -2.59193146099879641e+01, - mut z: 1.79258772950371181e-01, - mut vx: 2.68067772490389322e-03 * DAYS_PER_YEAR, - mut vy: 1.62824170038242295e-03 * DAYS_PER_YEAR, - mut vz: -9.51592254519715870e-05 * DAYS_PER_YEAR, - mass: 5.15138902046611451e-05 * SOLAR_MASS}; + return Props { + x: 1.53796971148509165e+01, + y: -2.59193146099879641e+01, + z: 1.79258772950371181e-01, + vx: 2.68067772490389322e-03 * DAYS_PER_YEAR, + vy: 1.62824170038242295e-03 * DAYS_PER_YEAR, + vz: -9.51592254519715870e-05 * DAYS_PER_YEAR, + mass: 5.15138902046611451e-05 * SOLAR_MASS + }; } pub fn sun() -> Body::Props { - return Props {mut x: 0.0, - mut y: 0.0, - mut z: 0.0, - mut vx: 0.0, - mut vy: 0.0, - mut vz: 0.0, - mass: SOLAR_MASS}; + return Props { + x: 0.0, + y: 0.0, + z: 0.0, + vx: 0.0, + vy: 0.0, + vz: 0.0, + mass: SOLAR_MASS + }; } pub fn offset_momentum(props: &mut Body::Props, - px: float, py: float, pz: float) { + px: float, + py: float, + pz: float) { props.vx = -px / SOLAR_MASS; props.vy = -py / SOLAR_MASS; props.vz = -pz / SOLAR_MASS; diff --git a/src/test/bench/shootout-pfib.rs b/src/test/bench/shootout-pfib.rs index ac695421059c7..a8383c4647ec1 100644 --- a/src/test/bench/shootout-pfib.rs +++ b/src/test/bench/shootout-pfib.rs @@ -24,12 +24,9 @@ extern mod std; use std::{time, getopts}; -use io::WriterUtil; -use int::range; -use pipes::Port; -use pipes::Chan; -use pipes::send; -use pipes::recv; +use core::int::range; +use core::comm::*; +use core::io::WriterUtil; use core::result; use result::{Ok, Err}; @@ -41,17 +38,17 @@ fn fib(n: int) -> int { } else if n <= 2 { c.send(1); } else { - let p = pipes::PortSet(); + let p = PortSet(); let ch = p.chan(); - task::spawn(|move ch| pfib(ch, n - 1) ); + task::spawn(|| pfib(ch, n - 1) ); let ch = p.chan(); - task::spawn(|move ch| pfib(ch, n - 2) ); + task::spawn(|| pfib(ch, n - 2) ); c.send(p.recv() + p.recv()); } } - let (p, ch) = pipes::stream(); - let _t = task::spawn(|move ch| pfib(ch, n) ); + let (p, ch) = stream(); + let _t = task::spawn(|| pfib(ch, n) ); p.recv() } @@ -86,7 +83,7 @@ fn stress(num_tasks: int) { let mut results = ~[]; for range(0, num_tasks) |i| { do task::task().future_result(|+r| { - results.push(move r); + results.push(r); }).spawn { stress_task(i); } diff --git a/src/test/bench/sudoku.rs b/src/test/bench/sudoku.rs index 885eaf01c4453..05dac339177bb 100644 --- a/src/test/bench/sudoku.rs +++ b/src/test/bench/sudoku.rs @@ -1,3 +1,5 @@ +// xfail-pretty + // 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. @@ -58,7 +60,7 @@ pub fn solve_grid(g: grid_t) { fn next_color(mut g: grid, row: u8, col: u8, start_color: u8) -> bool { if start_color < 10u8 { // colors not yet used - let avail = bitv::Bitv(10u, false); + let mut avail = bitv::Bitv::new(10u, false); for u8::range(start_color, 10u8) |color| { avail.set(color as uint, true); } @@ -80,7 +82,7 @@ pub fn solve_grid(g: grid_t) { // find colors available in neighbourhood of (row, col) fn drop_colors(g: grid, avail: bitv::Bitv, row: u8, col: u8) { - fn drop_color(g: grid, colors: bitv::Bitv, row: u8, col: u8) { + fn drop_color(g: grid, mut colors: bitv::Bitv, row: u8, col: u8) { let color = g[row][col]; if color != 0u8 { colors.set(color as uint, false); } } diff --git a/src/test/bench/task-perf-alloc-unwind.rs b/src/test/bench/task-perf-alloc-unwind.rs index 5f0530871fc83..b4b02c3aaa8d4 100644 --- a/src/test/bench/task-perf-alloc-unwind.rs +++ b/src/test/bench/task-perf-alloc-unwind.rs @@ -99,6 +99,6 @@ fn recurse_or_fail(depth: int, st: Option) { } }; - recurse_or_fail(depth, Some(move st)); + recurse_or_fail(depth, Some(st)); } } diff --git a/src/test/bench/task-perf-jargon-metal-smoke.rs b/src/test/bench/task-perf-jargon-metal-smoke.rs index 06f4213ee7b93..49a06fd491cd0 100644 --- a/src/test/bench/task-perf-jargon-metal-smoke.rs +++ b/src/test/bench/task-perf-jargon-metal-smoke.rs @@ -1,3 +1,5 @@ +// xfail-pretty + // 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. @@ -15,18 +17,18 @@ // // The filename is a song reference; google it in quotes. -fn child_generation(gens_left: uint, -c: pipes::Chan<()>) { +fn child_generation(gens_left: uint, -c: comm::Chan<()>) { // This used to be O(n^2) in the number of generations that ever existed. // With this code, only as many generations are alive at a time as tasks // alive at a time, - let c = ~mut Some(move c); - do task::spawn_supervised |move c| { + let c = ~mut Some(c); + do task::spawn_supervised || { let c = option::swap_unwrap(c); if gens_left & 1 == 1 { task::yield(); // shake things up a bit } if gens_left > 0 { - child_generation(gens_left - 1, move c); // recurse + child_generation(gens_left - 1, c); // recurse } else { c.send(()) } @@ -43,8 +45,8 @@ fn main() { copy args }; - let (p,c) = pipes::stream(); - child_generation(uint::from_str(args[1]).get(), move c); + let (p,c) = comm::stream(); + child_generation(uint::from_str(args[1]).get(), c); if p.try_recv().is_none() { fail!(~"it happened when we slumbered"); } diff --git a/src/test/bench/task-perf-linked-failure.rs b/src/test/bench/task-perf-linked-failure.rs index 4a6195b1ae89c..c6074cc522e6a 100644 --- a/src/test/bench/task-perf-linked-failure.rs +++ b/src/test/bench/task-perf-linked-failure.rs @@ -1,3 +1,5 @@ +// xfail-pretty + // 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. @@ -20,7 +22,7 @@ // Creates in the background 'num_tasks' tasks, all blocked forever. // Doesn't return until all such tasks are ready, but doesn't block forever itself. -use core::pipes::*; +use core::comm::*; fn grandchild_group(num_tasks: uint) { let (po, ch) = stream(); @@ -46,9 +48,9 @@ fn grandchild_group(num_tasks: uint) { fn spawn_supervised_blocking(myname: &str, +f: fn~()) { let mut res = None; - task::task().future_result(|+r| res = Some(move r)).supervised().spawn(move f); + task::task().future_result(|+r| res = Some(r)).supervised().spawn(f); error!("%s group waiting", myname); - let x = option::unwrap(move res).recv(); + let x = option::unwrap(res).recv(); assert x == task::Success; } diff --git a/src/test/bench/task-perf-one-million.rs b/src/test/bench/task-perf-one-million.rs index c5092ecaecc00..8e1cbb9e17bdd 100644 --- a/src/test/bench/task-perf-one-million.rs +++ b/src/test/bench/task-perf-one-million.rs @@ -10,7 +10,7 @@ // Test for concurrent tasks -use core::pipes::*; +use core::comm::*; fn calc(children: uint, parent_wait_chan: &Chan>>) { diff --git a/src/test/compile-fail/ambig_impl_bounds.rs b/src/test/compile-fail/ambig_impl_bounds.rs index d4fe51835aee5..92581d756db03 100644 --- a/src/test/compile-fail/ambig_impl_bounds.rs +++ b/src/test/compile-fail/ambig_impl_bounds.rs @@ -11,7 +11,7 @@ trait A { fn foo(); } trait B { fn foo(); } -fn foo(t: T) { +fn foo(t: T) { t.foo(); //~ ERROR multiple applicable methods in scope //~^ NOTE candidate #1 derives from the bound `A` //~^^ NOTE candidate #2 derives from the bound `B` diff --git a/src/test/compile-fail/bind-by-move-neither-can-live-while-the-other-survives-1.rs b/src/test/compile-fail/bind-by-move-neither-can-live-while-the-other-survives-1.rs index 298e5d53c9401..e9bc4a5e195d7 100644 --- a/src/test/compile-fail/bind-by-move-neither-can-live-while-the-other-survives-1.rs +++ b/src/test/compile-fail/bind-by-move-neither-can-live-while-the-other-survives-1.rs @@ -18,8 +18,8 @@ impl Drop for X { fn main() { let x = Some(X { x: () }); - match move x { - Some(ref _y @ move _z) => { }, //~ ERROR cannot bind by-move and by-ref in the same pattern + match x { + Some(ref _y @ _z) => { }, //~ ERROR cannot bind by-move and by-ref in the same pattern None => fail!() } } diff --git a/src/test/compile-fail/bind-by-move-neither-can-live-while-the-other-survives-2.rs b/src/test/compile-fail/bind-by-move-neither-can-live-while-the-other-survives-2.rs index 162a10a370b78..6548adddf1956 100644 --- a/src/test/compile-fail/bind-by-move-neither-can-live-while-the-other-survives-2.rs +++ b/src/test/compile-fail/bind-by-move-neither-can-live-while-the-other-survives-2.rs @@ -18,8 +18,8 @@ impl Drop for X { fn main() { let x = Some((X { x: () }, X { x: () })); - match move x { - Some((ref _y, move _z)) => { }, //~ ERROR cannot bind by-move and by-ref in the same pattern + match x { + Some((ref _y, _z)) => { }, //~ ERROR cannot bind by-move and by-ref in the same pattern None => fail!() } } diff --git a/src/test/compile-fail/bind-by-move-neither-can-live-while-the-other-survives-3.rs b/src/test/compile-fail/bind-by-move-neither-can-live-while-the-other-survives-3.rs index 1aed491bbf069..aaa9d9f920a6a 100644 --- a/src/test/compile-fail/bind-by-move-neither-can-live-while-the-other-survives-3.rs +++ b/src/test/compile-fail/bind-by-move-neither-can-live-while-the-other-survives-3.rs @@ -20,8 +20,8 @@ enum double_option { some2(T,U), none2 } fn main() { let x = some2(X { x: () }, X { x: () }); - match move x { - some2(ref _y, move _z) => { }, //~ ERROR cannot bind by-move and by-ref in the same pattern + match x { + some2(ref _y, _z) => { }, //~ ERROR cannot bind by-move and by-ref in the same pattern none2 => fail!() } } diff --git a/src/test/compile-fail/bind-by-move-neither-can-live-while-the-other-survives-4.rs b/src/test/compile-fail/bind-by-move-neither-can-live-while-the-other-survives-4.rs index 9c879e297090f..b5686b64c810b 100644 --- a/src/test/compile-fail/bind-by-move-neither-can-live-while-the-other-survives-4.rs +++ b/src/test/compile-fail/bind-by-move-neither-can-live-while-the-other-survives-4.rs @@ -18,8 +18,8 @@ impl Drop for X { fn main() { let x = Some((X { x: () }, X { x: () })); - match move x { - Some((move _y, ref _z)) => { }, //~ ERROR cannot bind by-move and by-ref in the same pattern + match x { + Some((_y, ref _z)) => { }, //~ ERROR cannot bind by-move and by-ref in the same pattern None => fail!() } } diff --git a/src/test/compile-fail/bind-by-move-no-guards.rs b/src/test/compile-fail/bind-by-move-no-guards.rs index 82f4d57911b4c..d428feb2a24de 100644 --- a/src/test/compile-fail/bind-by-move-no-guards.rs +++ b/src/test/compile-fail/bind-by-move-no-guards.rs @@ -9,12 +9,12 @@ // except according to those terms. fn main() { - let (p,c) = pipes::stream(); + let (p,c) = comm::stream(); let x = Some(p); c.send(false); - match move x { - Some(move z) if z.recv() => { fail!() }, //~ ERROR cannot bind by-move into a pattern guard - Some(move z) => { assert !z.recv(); }, + match x { + Some(z) if z.recv() => { fail!() }, //~ ERROR cannot bind by-move into a pattern guard + Some(z) => { assert !z.recv(); }, None => fail!() } } diff --git a/src/test/compile-fail/bind-by-move-no-lvalues-1.rs b/src/test/compile-fail/bind-by-move-no-lvalues-1.rs index 586285d956691..c8537afa1905e 100644 --- a/src/test/compile-fail/bind-by-move-no-lvalues-1.rs +++ b/src/test/compile-fail/bind-by-move-no-lvalues-1.rs @@ -21,7 +21,7 @@ impl Drop for X { fn main() { let x = Some(X { x: () }); match x { - Some(move _z) => { }, //~ ERROR cannot bind by-move when matching an lvalue + Some(_z) => { }, //~ ERROR cannot bind by-move when matching an lvalue None => fail!() } } diff --git a/src/test/compile-fail/bind-by-move-no-lvalues-2.rs b/src/test/compile-fail/bind-by-move-no-lvalues-2.rs index 9ed48fe33e319..26b1084c09172 100644 --- a/src/test/compile-fail/bind-by-move-no-lvalues-2.rs +++ b/src/test/compile-fail/bind-by-move-no-lvalues-2.rs @@ -23,7 +23,7 @@ struct Y { y: Option } fn main() { let x = Y { y: Some(X { x: () }) }; match x.y { - Some(move _z) => { }, //~ ERROR cannot bind by-move when matching an lvalue + Some(_z) => { }, //~ ERROR cannot bind by-move when matching an lvalue None => fail!() } } diff --git a/src/test/compile-fail/bind-by-move-no-sub-bindings.rs b/src/test/compile-fail/bind-by-move-no-sub-bindings.rs index d60ef84f04024..c86158be5ea7f 100644 --- a/src/test/compile-fail/bind-by-move-no-sub-bindings.rs +++ b/src/test/compile-fail/bind-by-move-no-sub-bindings.rs @@ -18,8 +18,8 @@ impl Drop for X { fn main() { let x = Some(X { x: () }); - match move x { - Some(move _y @ ref _z) => { }, //~ ERROR cannot bind by-move with sub-bindings + match x { + Some(_y @ ref _z) => { }, //~ ERROR cannot bind by-move with sub-bindings None => fail!() } } diff --git a/src/test/compile-fail/borrowck-assign-comp.rs b/src/test/compile-fail/borrowck-assign-comp.rs index e4cdf2d7c69c0..283f04a283f4e 100644 --- a/src/test/compile-fail/borrowck-assign-comp.rs +++ b/src/test/compile-fail/borrowck-assign-comp.rs @@ -8,10 +8,10 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -type point = { x: int, y: int }; +struct point { x: int, y: int } fn a() { - let mut p = {x: 3, y: 4}; + let mut p = point {x: 3, y: 4}; let _q = &p; //~ NOTE loan of mutable local variable granted here // This assignment is illegal because the field x is not @@ -20,22 +20,13 @@ fn a() { p.x = 5; //~ ERROR assigning to mutable field prohibited due to outstanding loan } -fn b() { - let mut p = {x: 3, mut y: 4}; - let _q = &p; - - // This assignment is legal because `y` is inherently mutable (and - // hence &_q.y is &mut int). - p.y = 5; -} - fn c() { // this is sort of the opposite. We take a loan to the interior of `p` // and then try to overwrite `p` as a whole. - let mut p = {x: 3, mut y: 4}; + let mut p = point {x: 3, y: 4}; let _q = &p.y; //~ NOTE loan of mutable local variable granted here - p = {x: 5, mut y: 7};//~ ERROR assigning to mutable local variable prohibited due to outstanding loan + p = point {x: 5, y: 7};//~ ERROR assigning to mutable local variable prohibited due to outstanding loan copy p; } @@ -43,7 +34,7 @@ fn d() { // just for completeness's sake, the easy case, where we take the // address of a subcomponent and then modify that subcomponent: - let mut p = {x: 3, mut y: 4}; + let mut p = point {x: 3, y: 4}; let _q = &p.y; //~ NOTE loan of mutable field granted here p.y = 5; //~ ERROR assigning to mutable field prohibited due to outstanding loan copy p; diff --git a/src/test/compile-fail/borrowck-assign-to-subfield.rs b/src/test/compile-fail/borrowck-assign-to-subfield.rs index 9e90995c33abf..736e950cd82df 100644 --- a/src/test/compile-fail/borrowck-assign-to-subfield.rs +++ b/src/test/compile-fail/borrowck-assign-to-subfield.rs @@ -9,11 +9,23 @@ // except according to those terms. fn main() { - let mut p = {a: 1, - w: {a: 1}, - x: @{a: 1}, - y: @const {a: 1}, - z: @mut{a: 1}}; + struct A { + a: int, + w: B, + x: @B, + y: @const B, + z: @mut B + } + struct B { + a: int + } + let mut p = A { + a: 1, + w: B {a: 1}, + x: @B {a: 1}, + y: @const B {a: 1}, + z: @mut B {a: 1} + }; // even though `x` is not declared as a mutable field, // `p` as a whole is mutable, so it can be modified. diff --git a/src/test/compile-fail/borrowck-borrow-from-owned-ptr.rs b/src/test/compile-fail/borrowck-borrow-from-owned-ptr.rs index 47b6b4de64281..005908f86d87d 100644 --- a/src/test/compile-fail/borrowck-borrow-from-owned-ptr.rs +++ b/src/test/compile-fail/borrowck-borrow-from-owned-ptr.rs @@ -18,7 +18,7 @@ struct Bar { int2: int, } -fn make_foo() -> ~Foo { die!() } +fn make_foo() -> ~Foo { fail!() } fn borrow_same_field_twice_mut_mut() { let mut foo = make_foo(); diff --git a/src/test/compile-fail/borrowck-borrow-from-stack-variable.rs b/src/test/compile-fail/borrowck-borrow-from-stack-variable.rs index 30757cc6e7798..035e293bc36b6 100644 --- a/src/test/compile-fail/borrowck-borrow-from-stack-variable.rs +++ b/src/test/compile-fail/borrowck-borrow-from-stack-variable.rs @@ -18,7 +18,7 @@ struct Bar { int2: int, } -fn make_foo() -> Foo { die!() } +fn make_foo() -> Foo { fail!() } fn borrow_same_field_twice_mut_mut() { let mut foo = make_foo(); diff --git a/src/test/compile-fail/borrowck-call-sendfn.rs b/src/test/compile-fail/borrowck-call-sendfn.rs index c83f9230dbb99..51047631ea665 100644 --- a/src/test/compile-fail/borrowck-call-sendfn.rs +++ b/src/test/compile-fail/borrowck-call-sendfn.rs @@ -10,7 +10,7 @@ // xfail-test #2978 -fn call(x: @{mut f: fn~()}) { +fn call(x: @{f: fn~()}) { x.f(); //~ ERROR foo //~^ NOTE bar } 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 0b9375bc543a1..7b6484fd4aadb 100644 --- a/src/test/compile-fail/borrowck-loan-in-overloaded-op.rs +++ b/src/test/compile-fail/borrowck-loan-in-overloaded-op.rs @@ -20,6 +20,6 @@ impl Add for foo { fn main() { let x = foo(~3); - let _y = x + move x; + let _y = x + x; //~^ ERROR moving out of immutable local variable prohibited due to outstanding loan } diff --git a/src/test/compile-fail/borrowck-loan-rcvr.rs b/src/test/compile-fail/borrowck-loan-rcvr.rs index 97b46c714921f..bd4428dc93064 100644 --- a/src/test/compile-fail/borrowck-loan-rcvr.rs +++ b/src/test/compile-fail/borrowck-loan-rcvr.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -type point = { x: int, y: int }; +struct point { x: int, y: int } trait methods { fn impurem(); @@ -27,7 +27,7 @@ impl methods for point { } fn a() { - let mut p = {x: 3, y: 4}; + let mut p = point {x: 3, y: 4}; // Here: it's ok to call even though receiver is mutable, because we // can loan it out. @@ -41,7 +41,7 @@ fn a() { } fn b() { - let mut p = {x: 3, y: 4}; + let mut p = point {x: 3, y: 4}; // Here I create an outstanding loan and check that we get conflicts: @@ -56,7 +56,7 @@ fn b() { fn c() { // Loaning @mut as & is considered legal due to dynamic checks: - let q = @mut {x: 3, y: 4}; + let q = @mut point {x: 3, y: 4}; q.purem(); q.impurem(); } diff --git a/src/test/compile-fail/borrowck-move-from-unsafe-ptr.rs b/src/test/compile-fail/borrowck-move-from-unsafe-ptr.rs index 7154683565960..8f332646bbccd 100644 --- a/src/test/compile-fail/borrowck-move-from-unsafe-ptr.rs +++ b/src/test/compile-fail/borrowck-move-from-unsafe-ptr.rs @@ -9,7 +9,7 @@ // except according to those terms. fn foo(x: *~int) -> ~int { - let y = move *x; //~ ERROR dereference of unsafe pointer requires unsafe function or block + let y = *x; //~ ERROR dereference of unsafe pointer requires unsafe function or block return y; } diff --git a/src/test/compile-fail/borrowck-mut-field-imm-base.rs b/src/test/compile-fail/borrowck-mut-field-imm-base.rs deleted file mode 100644 index 685efcacf0c58..0000000000000 --- a/src/test/compile-fail/borrowck-mut-field-imm-base.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 Foo { - mut x: uint -} - -struct Bar { - foo: Foo -} - -fn main() { - let mut b = Bar { foo: Foo { x: 3 } }; - let p = &b; - let q = &mut b.foo.x; - let r = &p.foo.x; //~ ERROR illegal borrow unless pure - let s = &b.foo.x; //~ ERROR loan of mutable field as immutable conflicts with prior loan - io::println(fmt!("*r = %u", *r)); - io::println(fmt!("*r = %u", *s)); - *q += 1; - io::println(fmt!("*r = %u", *r)); - io::println(fmt!("*r = %u", *s)); -} diff --git a/src/test/compile-fail/borrowck-no-cycle-in-exchange-heap.rs b/src/test/compile-fail/borrowck-no-cycle-in-exchange-heap.rs index 4d87bbf6c722c..4af3bc17240ce 100644 --- a/src/test/compile-fail/borrowck-no-cycle-in-exchange-heap.rs +++ b/src/test/compile-fail/borrowck-no-cycle-in-exchange-heap.rs @@ -8,16 +8,20 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +struct node_ { + a: ~cycle +} + enum cycle { - node({mut a: ~cycle}), + node(node_), empty } fn main() { - let x = ~node({mut a: ~empty}); + let mut x = ~node(node_ {a: ~empty}); // Create a cycle! - match *x { //~ NOTE loan of immutable local variable granted here - node(ref y) => { - y.a = x; //~ ERROR moving out of immutable local variable prohibited due to outstanding loan + match *x { //~ NOTE loan of mutable local variable granted here + node(ref mut y) => { + y.a = x; //~ ERROR moving out of mutable local variable prohibited due to outstanding loan } empty => {} }; diff --git a/src/test/compile-fail/borrowck-uniq-via-box.rs b/src/test/compile-fail/borrowck-uniq-via-box.rs index e4b8214fb984c..9a63c8698c65a 100644 --- a/src/test/compile-fail/borrowck-uniq-via-box.rs +++ b/src/test/compile-fail/borrowck-uniq-via-box.rs @@ -14,10 +14,6 @@ fn box_mut(v: @mut ~int) { borrow(*v); //~ ERROR illegal borrow unless pure } -fn box_rec_mut(v: @{mut f: ~int}) { - borrow(v.f); //~ ERROR illegal borrow unless pure -} - fn box_mut_rec(v: @mut {f: ~int}) { borrow(v.f); //~ ERROR illegal borrow unless pure } @@ -42,14 +38,6 @@ fn box_const(v: @const ~int) { borrow(*v); //~ ERROR illegal borrow unless pure } -fn box_rec_const(v: @{const f: ~int}) { - borrow(v.f); //~ ERROR illegal borrow unless pure -} - -fn box_recs_const(v: @{f: {g: {const h: ~int}}}) { - borrow(v.f.g.h); //~ ERROR illegal borrow unless pure -} - fn box_const_rec(v: @const {f: ~int}) { borrow(v.f); //~ ERROR illegal borrow unless pure } diff --git a/src/test/compile-fail/borrowck-uniq-via-lend.rs b/src/test/compile-fail/borrowck-uniq-via-lend.rs index d61731ccc453b..ee96237a26c82 100644 --- a/src/test/compile-fail/borrowck-uniq-via-lend.rs +++ b/src/test/compile-fail/borrowck-uniq-via-lend.rs @@ -16,12 +16,16 @@ fn local() { } fn local_rec() { - let mut v = {f: ~3}; + struct F { f: ~int } + let mut v = F {f: ~3}; borrow(v.f); } fn local_recs() { - let mut v = {f: {g: {h: ~3}}}; + struct F { f: G } + struct G { g: H } + struct H { h: ~int } + let mut v = F {f: G {g: H {h: ~3}}}; borrow(v.f.g.h); } diff --git a/src/test/compile-fail/borrowck-uniq-via-ref.rs b/src/test/compile-fail/borrowck-uniq-via-ref.rs index 48d39c39e5a47..8d6e7039057f6 100644 --- a/src/test/compile-fail/borrowck-uniq-via-ref.rs +++ b/src/test/compile-fail/borrowck-uniq-via-ref.rs @@ -14,10 +14,6 @@ fn box_mut(v: &mut ~int) { borrow(*v); // OK: &mut -> &imm } -fn box_rec_mut(v: &{mut f: ~int}) { - borrow(v.f); //~ ERROR illegal borrow unless pure -} - fn box_mut_rec(v: &mut {f: ~int}) { borrow(v.f); // OK: &mut -> &imm } @@ -42,14 +38,6 @@ fn box_const(v: &const ~int) { borrow(*v); //~ ERROR illegal borrow unless pure } -fn box_rec_const(v: &{const f: ~int}) { - borrow(v.f); //~ ERROR illegal borrow unless pure -} - -fn box_recs_const(v: &{f: {g: {const h: ~int}}}) { - borrow(v.f.g.h); //~ ERROR illegal borrow unless pure -} - fn box_const_rec(v: &const {f: ~int}) { borrow(v.f); //~ ERROR illegal borrow unless pure } diff --git a/src/test/compile-fail/borrowck-vec-pattern-element-loan.rs b/src/test/compile-fail/borrowck-vec-pattern-element-loan.rs index deebff5f43a3c..cec81d8a6ef5b 100644 --- a/src/test/compile-fail/borrowck-vec-pattern-element-loan.rs +++ b/src/test/compile-fail/borrowck-vec-pattern-element-loan.rs @@ -4,7 +4,7 @@ fn a() -> &[int] { [_a, ..tail] => tail, _ => fail!(~"foo") }; - move tail + tail } fn main() { diff --git a/src/test/compile-fail/borrowck-vec-pattern-tail-element-loan.rs b/src/test/compile-fail/borrowck-vec-pattern-tail-element-loan.rs index e1ed0f0daa1e8..714a80def9358 100644 --- a/src/test/compile-fail/borrowck-vec-pattern-tail-element-loan.rs +++ b/src/test/compile-fail/borrowck-vec-pattern-tail-element-loan.rs @@ -4,7 +4,7 @@ fn a() -> &int { [_a, ..tail] => &tail[0], _ => fail!(~"foo") }; - move tail + tail } fn main() { diff --git a/src/test/compile-fail/copy-a-resource.rs b/src/test/compile-fail/copy-a-resource.rs index 95fd9b938f07b..f1b31d66b3f68 100644 --- a/src/test/compile-fail/copy-a-resource.rs +++ b/src/test/compile-fail/copy-a-resource.rs @@ -23,7 +23,7 @@ fn foo(i:int) -> foo { } fn main() { - let x = move foo(10); + let x = foo(10); let _y = copy x; //~^ ERROR copying a value of non-copyable type `foo` log(error, x); diff --git a/src/test/compile-fail/issue-1451.rs b/src/test/compile-fail/issue-1451.rs index 62bc322f41600..2e80a7b09defa 100644 --- a/src/test/compile-fail/issue-1451.rs +++ b/src/test/compile-fail/issue-1451.rs @@ -9,8 +9,8 @@ // except according to those terms. // xfail-test -type T = { mut f: fn@() }; -type S = { f: fn@() }; +struct T { f: fn@() }; +struct S { f: fn@() }; fn fooS(t: S) { } @@ -23,11 +23,11 @@ fn bar() { fn main() { let x: fn@() = bar; - fooS({f: x}); - fooS({f: bar}); + fooS(S {f: x}); + fooS(S {f: bar}); let x: fn@() = bar; - fooT({mut f: x}); - fooT({mut f: bar}); + fooT(T {f: x}); + fooT(T {f: bar}); } diff --git a/src/test/compile-fail/issue-1896-1.rs b/src/test/compile-fail/issue-1896-1.rs index 5def792558aac..2be04929dc6a2 100644 --- a/src/test/compile-fail/issue-1896-1.rs +++ b/src/test/compile-fail/issue-1896-1.rs @@ -8,10 +8,10 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -type boxedFn = { theFn: fn () -> uint }; +struct boxedFn { theFn: fn~() -> uint } fn createClosure (closedUint: uint) -> boxedFn { - { theFn: fn@ () -> uint { closedUint } } //~ ERROR mismatched types + boxedFn {theFn: fn@ () -> uint { closedUint }} //~ ERROR mismatched types } fn main () { diff --git a/src/test/compile-fail/issue-2548.rs b/src/test/compile-fail/issue-2548.rs index abc734697191f..951944e24857f 100644 --- a/src/test/compile-fail/issue-2548.rs +++ b/src/test/compile-fail/issue-2548.rs @@ -34,7 +34,7 @@ fn main() { let mut res = foo(x); let mut v = ~[]; - v = move ~[(move res)] + v; //~ instantiating a type parameter with an incompatible type `foo`, which does not fulfill `Copy` + v = ~[(res)] + v; //~ instantiating a type parameter with an incompatible type `foo`, which does not fulfill `Copy` assert (v.len() == 2); } diff --git a/src/test/compile-fail/issue-2611-3.rs b/src/test/compile-fail/issue-2611-3.rs index 5da3d08e34c56..c9aeaae0ff934 100644 --- a/src/test/compile-fail/issue-2611-3.rs +++ b/src/test/compile-fail/issue-2611-3.rs @@ -16,7 +16,7 @@ use iter::BaseIter; trait A { - fn b(x: C) -> C; + fn b(x: C) -> C; } struct E { @@ -24,7 +24,7 @@ struct E { } impl A for E { - fn b(_x: F) -> F { fail!() } //~ ERROR in method `b`, type parameter 0 has 1 bound, but + fn b(_x: F) -> F { fail!() } //~ ERROR in method `b`, type parameter 0 has 1 bound, but } fn main() {} diff --git a/src/test/compile-fail/issue-2611-4.rs b/src/test/compile-fail/issue-2611-4.rs index c8f3f9a4a5a3d..fb7c5bd6cb87b 100644 --- a/src/test/compile-fail/issue-2611-4.rs +++ b/src/test/compile-fail/issue-2611-4.rs @@ -13,7 +13,7 @@ use iter::BaseIter; trait A { - fn b(x: C) -> C; + fn b(x: C) -> C; } struct E { @@ -21,7 +21,7 @@ struct E { } impl A for E { - fn b(_x: F) -> F { fail!() } //~ ERROR in method `b`, type parameter 0 has 2 bounds, but + fn b(_x: F) -> F { fail!() } //~ ERROR in method `b`, type parameter 0 has 2 bounds, but } fn main() {} diff --git a/src/test/compile-fail/issue-2611-5.rs b/src/test/compile-fail/issue-2611-5.rs index f8f7704bcd9d0..35015a260f5af 100644 --- a/src/test/compile-fail/issue-2611-5.rs +++ b/src/test/compile-fail/issue-2611-5.rs @@ -13,7 +13,7 @@ use iter::BaseIter; trait A { - fn b(x: C) -> C; + fn b(x: C) -> C; } struct E { @@ -22,7 +22,7 @@ struct E { impl A for E { // n.b. The error message is awful -- see #3404 - fn b(_x: G) -> G { fail!() } //~ ERROR method `b` has an incompatible type + fn b(_x: G) -> G { fail!() } //~ ERROR method `b` has an incompatible type } fn main() {} diff --git a/src/test/compile-fail/issue-2766-a.rs b/src/test/compile-fail/issue-2766-a.rs index 0b63ae5b1bad3..77a840e7e366d 100644 --- a/src/test/compile-fail/issue-2766-a.rs +++ b/src/test/compile-fail/issue-2766-a.rs @@ -9,12 +9,12 @@ // except according to those terms. pub mod stream { - pub enum Stream { send(T, ::stream::server::Stream), } + pub enum Stream { send(T, ::stream::server::Stream), } pub mod server { use core::option; use core::pipes; - impl Stream { + impl Stream { pub fn recv() -> extern fn(+v: Stream) -> ::stream::Stream { // resolve really should report just one error here. // Change the test case when it changes. @@ -28,7 +28,7 @@ pub mod stream { } } - pub type Stream = pipes::RecvPacket<::stream::Stream>; + pub type Stream = pipes::RecvPacket<::stream::Stream>; } } diff --git a/src/test/compile-fail/issue-3021-b.rs b/src/test/compile-fail/issue-3021-b.rs index 09454d4326ab7..a782dd58ee671 100644 --- a/src/test/compile-fail/issue-3021-b.rs +++ b/src/test/compile-fail/issue-3021-b.rs @@ -13,11 +13,11 @@ extern mod std; fn siphash(k0 : u64) { struct siphash { - mut v0: u64, + v0: u64, } impl siphash { - fn reset() { + fn reset(&mut self) { self.v0 = k0 ^ 0x736f6d6570736575; //~ ERROR attempted dynamic environment-capture //~^ ERROR unresolved name: k0 } diff --git a/src/test/compile-fail/issue-3044.rs b/src/test/compile-fail/issue-3044.rs index 46ad7f6458944..fcd5b1deee552 100644 --- a/src/test/compile-fail/issue-3044.rs +++ b/src/test/compile-fail/issue-3044.rs @@ -11,10 +11,10 @@ fn main() { let needlesArr: ~[char] = ~['a', 'f']; do vec::foldr(needlesArr) |x, y| { - //~^ ERROR 2 parameters were supplied (including the closure passed by the `do` keyword) - //~^^ ERROR Unconstrained region variable #2 - // - // this last error is, um, non-ideal. + //~^ ERROR Unconstrained region variable #2 } + //~^ ERROR 2 parameters were supplied (including the closure passed by the `do` keyword) + // + // the first error is, um, non-ideal. } diff --git a/src/test/compile-fail/issue-3177-mutable-struct.rs b/src/test/compile-fail/issue-3177-mutable-struct.rs index 8a65366d2cb43..31c0dc7d9c4e2 100644 --- a/src/test/compile-fail/issue-3177-mutable-struct.rs +++ b/src/test/compile-fail/issue-3177-mutable-struct.rs @@ -10,12 +10,12 @@ // xfail-test // error-pattern: instantiating a type parameter with an incompatible type -struct S { +struct S { s: T, - mut cant_nest: () + cant_nest: () } fn main() { let a1 = ~S{ s: true, cant_nest: () }; - let _a2 = ~S{ s: move a1, cant_nest: () }; + let _a2 = ~S{ s: a1, cant_nest: () }; } diff --git a/src/test/compile-fail/issue-3214.rs b/src/test/compile-fail/issue-3214.rs index ff19551896b86..2dd58906ddb71 100644 --- a/src/test/compile-fail/issue-3214.rs +++ b/src/test/compile-fail/issue-3214.rs @@ -10,7 +10,7 @@ fn foo() { struct foo { - mut x: T, //~ ERROR attempt to use a type argument out of scope + x: T, //~ ERROR attempt to use a type argument out of scope //~^ ERROR use of undeclared type name } diff --git a/src/test/compile-fail/issue-3601.rs b/src/test/compile-fail/issue-3601.rs index 40d65938795ff..3dd070b44a04c 100644 --- a/src/test/compile-fail/issue-3601.rs +++ b/src/test/compile-fail/issue-3601.rs @@ -10,7 +10,7 @@ // xfail-test struct HTMLImageData { - mut image: Option<~str> + image: Option<~str> } struct ElementData { @@ -30,7 +30,7 @@ enum NodeData = { }; fn main() { - let id = HTMLImageData { image: None }; + let mut id = HTMLImageData { image: None }; let ed = ElementData { kind: ~HTMLImageElement(id) }; let n = NodeData({kind : ~Element(ed)}); match n.kind { diff --git a/src/test/compile-fail/issue-3953.rs b/src/test/compile-fail/issue-3953.rs index 2c797691b8d7a..227ea5c1521c0 100644 --- a/src/test/compile-fail/issue-3953.rs +++ b/src/test/compile-fail/issue-3953.rs @@ -19,7 +19,7 @@ trait Hahaha: Eq Eq Eq Eq Eq Eq Eq Eq Eq Eq Eq Eq Eq Eq Eq Eq //~ ERROR Duplicat enum Lol = int; -pub impl Lol: Hahaha { } +pub impl Hahaha for Lol { } impl Eq for Lol { pure fn eq(&self, other: &Lol) -> bool { **self != **other } diff --git a/src/test/compile-fail/issue-3969.rs b/src/test/compile-fail/issue-3969.rs index 675544ea59f93..a003563928738 100644 --- a/src/test/compile-fail/issue-3969.rs +++ b/src/test/compile-fail/issue-3969.rs @@ -16,7 +16,7 @@ trait BikeMethods { fn woops(&const self) -> ~str; } -pub impl Bike : BikeMethods { +pub impl BikeMethods for Bike { static fn woops(&const self) -> ~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 812e0fc8c9660..19244d24bcc71 100644 --- a/src/test/compile-fail/issue-3973.rs +++ b/src/test/compile-fail/issue-3973.rs @@ -11,8 +11,8 @@ // xfail-test struct Point { - mut x: float, - mut y: float, + x: float, + y: float, } impl ToStr for Point { //~ ERROR implements a method not defined in the trait diff --git a/src/test/compile-fail/issue-4935.rs b/src/test/compile-fail/issue-4935.rs new file mode 100644 index 0000000000000..4bb3a5119448e --- /dev/null +++ b/src/test/compile-fail/issue-4935.rs @@ -0,0 +1,14 @@ +// 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. + +// Regresion test for issue #4935 + +fn foo(a: uint) {} +fn main() { foo(5, 6) } //~ ERROR this function takes 1 parameter but 2 parameters were supplied diff --git a/src/test/compile-fail/borrowck-imm-ref-to-mut-rec-field-issue-3162.rs b/src/test/compile-fail/issue-4968.rs similarity index 53% rename from src/test/compile-fail/borrowck-imm-ref-to-mut-rec-field-issue-3162.rs rename to src/test/compile-fail/issue-4968.rs index 17bd4ec1e88e1..315c2affe349c 100644 --- a/src/test/compile-fail/borrowck-imm-ref-to-mut-rec-field-issue-3162.rs +++ b/src/test/compile-fail/issue-4968.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,15 +8,10 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -fn each(x: &[T], op: fn(elem: &T) -> bool) { - uint::range(0, x.len(), |i| op(&x[i])); -} +// Regression test for issue #4968 +const A: (int,int) = (4,2); fn main() { - let x = ~[{mut a: 0}]; - for each(x) |y| { - let z = &y.a; //~ ERROR illegal borrow unless pure - x[0].a = 10; //~ NOTE impure due to assigning to mutable field - log(error, z); - } + 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-nonsendable-1.rs b/src/test/compile-fail/kindck-nonsendable-1.rs index a513e367fe5bc..397b0f682d62c 100644 --- a/src/test/compile-fail/kindck-nonsendable-1.rs +++ b/src/test/compile-fail/kindck-nonsendable-1.rs @@ -13,6 +13,6 @@ fn foo(_x: @uint) {} fn main() { let x = @3u; let _ = fn~() { foo(x); }; //~ ERROR value has non-owned type `@uint` - let _ = fn~(copy x) { foo(x); }; //~ ERROR value has non-owned type `@uint` - let _ = fn~(move x) { foo(x); }; //~ ERROR value has non-owned type `@uint` + let _ = fn~() { foo(x); }; //~ ERROR value has non-owned type `@uint` + let _ = fn~() { foo(x); }; //~ ERROR value has non-owned type `@uint` } diff --git a/src/test/compile-fail/kindck-owned-trait-scoped.rs b/src/test/compile-fail/kindck-owned-trait-scoped.rs index 3d83f13c211ba..f11703ecf02cd 100644 --- a/src/test/compile-fail/kindck-owned-trait-scoped.rs +++ b/src/test/compile-fail/kindck-owned-trait-scoped.rs @@ -25,20 +25,23 @@ fn to_foo(t: T) { // the type of foo includes a region which will be resolved to // the fn body itself. let v = &3; - let x = {f:t} as foo; + struct F { f: T } + let x = F {f:t} as foo; assert x.foo(v) == 3; } 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 - {f:t} as foo //~ ERROR value may contain borrowed pointers; use `&static` bound + struct F { f: T } + 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 - {f:t} as foo + struct F { f: T } + F {f:t} as foo } fn main() { diff --git a/src/test/compile-fail/kindck-owned-trait.rs b/src/test/compile-fail/kindck-owned-trait.rs index 683d66d0d72e9..2bc6a91120424 100644 --- a/src/test/compile-fail/kindck-owned-trait.rs +++ b/src/test/compile-fail/kindck-owned-trait.rs @@ -10,11 +10,11 @@ trait foo { fn foo(); } -fn to_foo(t: T) -> foo { +fn to_foo(t: T) -> foo { 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 65f6f837c83a0..e792917622b3f 100644 --- a/src/test/compile-fail/kindck-owned.rs +++ b/src/test/compile-fail/kindck-owned.rs @@ -8,11 +8,11 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -fn copy1(t: T) -> fn@() -> T { +fn copy1(t: T) -> fn@() -> T { fn@() -> T { t } //~ ERROR value may contain borrowed pointers } -fn copy2(t: T) -> fn@() -> T { +fn copy2(t: T) -> fn@() -> T { fn@() -> T { t } } diff --git a/src/test/compile-fail/liveness-init-in-fru.rs b/src/test/compile-fail/liveness-init-in-fru.rs index f0ab71d0c41e9..1bd42c1cd32a5 100644 --- a/src/test/compile-fail/liveness-init-in-fru.rs +++ b/src/test/compile-fail/liveness-init-in-fru.rs @@ -10,10 +10,10 @@ // except according to those terms. -type point = {x: int, y: int}; +struct point {x: int, y: int} fn main() { let mut origin: point; - origin = {x: 10,.. origin}; //~ ERROR use of possibly uninitialized variable: `origin` + origin = point {x: 10,.. origin}; //~ ERROR use of possibly uninitialized variable: `origin` copy origin; } diff --git a/src/test/compile-fail/liveness-unused.rs b/src/test/compile-fail/liveness-unused.rs index b5157c669a73a..970abf4fd94b0 100644 --- a/src/test/compile-fail/liveness-unused.rs +++ b/src/test/compile-fail/liveness-unused.rs @@ -68,5 +68,5 @@ impl Drop for r { fn main() { let x = r { x: () }; - fn@(move x) { copy x; }; //~ ERROR copying a value of non-copyable type + fn@() { copy x; }; //~ ERROR copying a value of non-copyable type } diff --git a/src/test/compile-fail/liveness-use-after-send.rs b/src/test/compile-fail/liveness-use-after-send.rs index f852fb1d38e42..95dd59eb27f73 100644 --- a/src/test/compile-fail/liveness-use-after-send.rs +++ b/src/test/compile-fail/liveness-use-after-send.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -fn send(ch: _chan, -data: T) { +fn send(ch: _chan, -data: T) { log(debug, ch); log(debug, data); fail!(); diff --git a/src/test/compile-fail/match-struct.rs b/src/test/compile-fail/match-struct.rs new file mode 100644 index 0000000000000..fa406aa278e81 --- /dev/null +++ b/src/test/compile-fail/match-struct.rs @@ -0,0 +1,11 @@ +// error-pattern: mismatched types + +struct S { a: int } +enum E { C(int) } + +fn main() { + match S { a: 1 } { + C(_) => (), + _ => () + } +} diff --git a/src/test/compile-fail/missing-derivable-attr.rs b/src/test/compile-fail/missing-derivable-attr.rs index 3d63b622fcc96..057e6dbc06864 100644 --- a/src/test/compile-fail/missing-derivable-attr.rs +++ b/src/test/compile-fail/missing-derivable-attr.rs @@ -20,7 +20,7 @@ impl MyEq for int { pure fn eq(&self, other: &int) -> bool { *self == *other } } -impl A : MyEq; //~ ERROR missing method +impl MyEq for A; //~ ERROR missing method fn main() { } diff --git a/src/test/compile-fail/mutable-huh-ptr-assign.rs b/src/test/compile-fail/mutable-huh-ptr-assign.rs index d0e7c2339bc1f..ed356f4001dd6 100644 --- a/src/test/compile-fail/mutable-huh-ptr-assign.rs +++ b/src/test/compile-fail/mutable-huh-ptr-assign.rs @@ -16,8 +16,8 @@ fn main() { } unsafe { - let a = 0; - let v = ptr::mut_addr_of(&a); + let mut a = 0; + let v = &mut a; f(v); } } diff --git a/src/test/compile-fail/mutable-huh-variance-ptr.rs b/src/test/compile-fail/mutable-huh-variance-ptr.rs index e2299597c2f58..dba6f9ae3fa0f 100644 --- a/src/test/compile-fail/mutable-huh-variance-ptr.rs +++ b/src/test/compile-fail/mutable-huh-variance-ptr.rs @@ -13,8 +13,8 @@ extern mod std; fn main() { - let a = ~[0]; - let v: *mut ~[int] = ptr::mut_addr_of(&a); + let mut a = ~[0]; + let v: *mut ~[int] = &mut a; fn f(&&v: *mut ~[const int]) { unsafe { diff --git a/src/test/compile-fail/mutable-huh-variance-rec.rs b/src/test/compile-fail/mutable-huh-variance-rec.rs index 1ee2bb18321c3..6d79e23e999a7 100644 --- a/src/test/compile-fail/mutable-huh-variance-rec.rs +++ b/src/test/compile-fail/mutable-huh-variance-rec.rs @@ -10,11 +10,15 @@ // error-pattern: mismatched types +struct S { + g: ~[int] +} + fn main() { - let v = {mut g: ~[0]}; + let v = S {g: ~[0]}; - fn f(&&v: {mut g: ~[const int]}) { - v.g = ~[mut 3] + fn f(&&v: {g: ~[const int]}) { + v.g = ~[3] } f(v); diff --git a/src/test/compile-fail/non-const.rs b/src/test/compile-fail/non-const.rs deleted file mode 100644 index 9bc4ce87787ed..0000000000000 --- a/src/test/compile-fail/non-const.rs +++ /dev/null @@ -1,55 +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. - -// Test that various non const things are rejected. - -fn foo(_x: T) { } - -struct r { - x:int, -} - -impl Drop for r { - fn finalize(&self) {} -} - -fn r(x:int) -> r { - r { - x: x - } -} - -struct r2 { - x:@mut int, -} - -impl Drop for r2 { - fn finalize(&self) {} -} - -fn r2(x:@mut int) -> r2 { - r2 { - x: x - } -} - -fn main() { - foo({f: 3}); - foo({mut f: 3}); //~ ERROR does not fulfill `Const` - foo(~[1]); - foo(~[mut 1]); //~ ERROR does not fulfill `Const` - foo(~1); - foo(~mut 1); //~ ERROR does not fulfill `Const` - foo(@1); - foo(@mut 1); //~ ERROR does not fulfill `Const` - foo(r(1)); // this is okay now. - foo(r2(@mut 1)); //~ ERROR does not fulfill `Const` - foo({f: {mut f: 1}}); //~ ERROR does not fulfill `Const` -} diff --git a/src/test/compile-fail/noncopyable-class.rs b/src/test/compile-fail/noncopyable-class.rs index 115120ff37263..42bad88633cff 100644 --- a/src/test/compile-fail/noncopyable-class.rs +++ b/src/test/compile-fail/noncopyable-class.rs @@ -37,7 +37,7 @@ fn foo(i:int) -> foo { } fn main() { - let x = move foo(10); + let x = foo(10); let _y = copy x; //~ ERROR copying a value of non-copyable type log(error, x); } diff --git a/src/test/compile-fail/obsolete-syntax.rs b/src/test/compile-fail/obsolete-syntax.rs index d92b545d1701f..cd3be9dc3d9d3 100644 --- a/src/test/compile-fail/obsolete-syntax.rs +++ b/src/test/compile-fail/obsolete-syntax.rs @@ -8,16 +8,16 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -fn f1() -> T { } +fn f1() -> T { } //~^ ERROR obsolete syntax: lower-case kind bounds -fn f1() -> T { } +fn f1() -> T { } //~^ ERROR obsolete syntax: lower-case kind bounds -fn f1() -> T { } +fn f1() -> T { } //~^ ERROR obsolete syntax: lower-case kind bounds -fn f1() -> T { } +fn f1() -> T { } //~^ ERROR obsolete syntax: lower-case kind bounds struct s { @@ -51,11 +51,6 @@ fn obsolete_with() { //~^ ERROR obsolete syntax: with let c = S { foo: (), with a }; //~^ ERROR obsolete syntax: with - let a = { foo: (), bar: () }; - let b = { foo: () with a }; - //~^ ERROR obsolete syntax: with - let c = { foo: (), with a }; - //~^ ERROR obsolete syntax: with } fn obsolete_moves() { diff --git a/src/test/compile-fail/pinned-deep-copy.rs b/src/test/compile-fail/pinned-deep-copy.rs index 43515e265297e..03ba317e7318b 100644 --- a/src/test/compile-fail/pinned-deep-copy.rs +++ b/src/test/compile-fail/pinned-deep-copy.rs @@ -27,8 +27,9 @@ fn r(i: @mut int) -> r { fn main() { let i = @mut 0; { + struct A { y: r } // Can't do this copy - let x = ~~~{y: r(i)}; + let x = ~~~A {y: r(i)}; let _z = copy x; //~ ERROR copying a value of non-copyable type log(debug, x); } diff --git a/src/test/compile-fail/pure-modifies-aliased.rs b/src/test/compile-fail/pure-modifies-aliased.rs index 90c507091e932..2aa81dd4fa21e 100644 --- a/src/test/compile-fail/pure-modifies-aliased.rs +++ b/src/test/compile-fail/pure-modifies-aliased.rs @@ -10,20 +10,20 @@ // Check that pure functions cannot modify aliased state. -pure fn modify_in_ref(&&sum: {mut f: int}) { - sum.f = 3; //~ ERROR assigning to mutable field prohibited in pure context +struct S { + f: int, } -pure fn modify_in_box(sum: @mut {f: int}) { +pure fn modify_in_box(sum: @mut S) { sum.f = 3; //~ ERROR assigning to mutable field prohibited in pure context } trait modify_in_box_rec { - pure fn modify_in_box_rec(sum: @{mut f: int}); + pure fn modify_in_box_rec(sum: @mut S); } impl modify_in_box_rec for int { - pure fn modify_in_box_rec(sum: @{mut f: int}) { + pure fn modify_in_box_rec(sum: @mut S) { sum.f = self; //~ ERROR assigning to mutable field prohibited in pure context } } diff --git a/src/test/compile-fail/record-with-resource.rs b/src/test/compile-fail/record-with-resource.rs deleted file mode 100644 index 2a1db52d73312..0000000000000 --- a/src/test/compile-fail/record-with-resource.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 my_resource { - x: int, -} - -impl Drop for my_resource { - fn finalize(&self) { - log(error, self.x); - } -} - -fn my_resource(x: int) -> my_resource { - my_resource { - x: x - } -} - -fn main() { - { - let a = {x: 0, y: my_resource(20)}; - let b = {x: 2,.. copy a}; //~ ERROR copying a value of non-copyable type - log(error, (a, b)); - } -} diff --git a/src/test/compile-fail/regions-addr-of-arg.rs b/src/test/compile-fail/regions-addr-of-arg.rs index 54d7c0b4d18b7..7f2140d96e16c 100644 --- a/src/test/compile-fail/regions-addr-of-arg.rs +++ b/src/test/compile-fail/regions-addr-of-arg.rs @@ -9,11 +9,11 @@ // except according to those terms. fn foo(a: int) { - let _p: &static/int = &a; //~ ERROR illegal borrow + let _p: &'static int = &a; //~ ERROR illegal borrow } fn bar(a: int) { - let _q: &blk/int = &a; + let _q: &'blk int = &a; } fn main() { diff --git a/src/test/compile-fail/regions-addr-of-self.rs b/src/test/compile-fail/regions-addr-of-self.rs index 2b52200908338..c6c89a3ae04a7 100644 --- a/src/test/compile-fail/regions-addr-of-self.rs +++ b/src/test/compile-fail/regions-addr-of-self.rs @@ -9,16 +9,16 @@ // except according to those terms. struct dog { - mut cats_chased: uint, + cats_chased: uint, } impl dog { - fn chase_cat() { - let p: &static/mut uint = &mut self.cats_chased; //~ ERROR illegal borrow + fn chase_cat(&mut self) { + let p: &static/mut uint = &mut self.cats_chased; //~ ERROR cannot infer an appropriate lifetime due to conflicting requirements *p += 1u; } - fn chase_cat_2() { + fn chase_cat_2(&mut self) { let p: &blk/mut uint = &mut self.cats_chased; *p += 1u; } @@ -31,7 +31,7 @@ fn dog() -> dog { } fn main() { - let d = dog(); + let mut d = dog(); d.chase_cat(); debug!("cats_chased: %u", d.cats_chased); } diff --git a/src/test/compile-fail/regions-addr-of-upvar-self.rs b/src/test/compile-fail/regions-addr-of-upvar-self.rs index 5bb82d1ee662d..8e98d4341a8b3 100644 --- a/src/test/compile-fail/regions-addr-of-upvar-self.rs +++ b/src/test/compile-fail/regions-addr-of-upvar-self.rs @@ -9,13 +9,13 @@ // except according to those terms. struct dog { - mut food: uint, + food: uint, } impl dog { - fn chase_cat() { + fn chase_cat(&mut self) { for uint::range(0u, 10u) |_i| { - let p: &static/mut uint = &mut self.food; //~ ERROR illegal borrow + let p: &'static mut uint = &mut self.food; //~ ERROR cannot infer an appropriate lifetime due to conflicting requirements *p = 3u; } } diff --git a/src/test/compile-fail/regions-bounds.rs b/src/test/compile-fail/regions-bounds.rs index ba125f0b3231c..47ddbf38e3de1 100644 --- a/src/test/compile-fail/regions-bounds.rs +++ b/src/test/compile-fail/regions-bounds.rs @@ -13,8 +13,10 @@ // checked. enum an_enum = ∫ -trait a_trait { fn foo() -> &self/int; } -struct a_class { x:&self/int } +trait a_trait { + fn foo() -> &'self int; +} +struct a_class { x:&'self int } fn a_fn1(e: an_enum/&a) -> an_enum/&b { return e; //~ ERROR mismatched types: expected `an_enum/&b` but found `an_enum/&a` diff --git a/src/test/compile-fail/regions-escape-via-trait-or-not.rs b/src/test/compile-fail/regions-escape-via-trait-or-not.rs index 0681680b9c4a2..e4598adca27df 100644 --- a/src/test/compile-fail/regions-escape-via-trait-or-not.rs +++ b/src/test/compile-fail/regions-escape-via-trait-or-not.rs @@ -18,7 +18,7 @@ impl deref for &int { } } -fn with(f: fn(x: &int) -> R) -> int { +fn with(f: fn(x: &int) -> R) -> int { f(&3).get() } diff --git a/src/test/compile-fail/regions-glb-free-free.rs b/src/test/compile-fail/regions-glb-free-free.rs index a8bbc24ffd475..f9ea3c6f933a3 100644 --- a/src/test/compile-fail/regions-glb-free-free.rs +++ b/src/test/compile-fail/regions-glb-free-free.rs @@ -17,7 +17,7 @@ mod argparse { name: &str, desc: &str, max_count: uint, - mut value: uint + value: uint } pub fn flag(name: &r/str, desc: &r/str) -> Flag/&r { diff --git a/src/test/compile-fail/regions-in-enums.rs b/src/test/compile-fail/regions-in-enums.rs index baf072c01eea2..b399ef8a747f9 100644 --- a/src/test/compile-fail/regions-in-enums.rs +++ b/src/test/compile-fail/regions-in-enums.rs @@ -8,16 +8,17 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -enum yes0 { - x3(&uint) +enum yes0<'lt> { + // This will eventually be legal (and in fact the only way): + X3(&'lt uint) //~ ERROR named regions other than `self` are not allowed as part of a type declaration } enum yes1 { - x4(&self/uint) + X4(&'self uint) } enum yes2 { - x5(&foo/uint) //~ ERROR named regions other than `self` are not allowed as part of a type declaration + X5(&'foo uint) //~ ERROR named regions other than `self` are not allowed as part of a type declaration } fn main() {} 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 fabce969b9c3f..bdd9b372e4ef6 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 @@ -9,7 +9,7 @@ // except according to those terms. struct invariant { - mut f: &int + f: &int } fn to_same_lifetime(bi: invariant/&r) { @@ -17,8 +17,8 @@ fn to_same_lifetime(bi: invariant/&r) { } fn to_shorter_lifetime(bi: invariant/&r) { - let bj: invariant/&blk = bi; //~ ERROR mismatched types -} + let bj: invariant/&blk = bi; +} fn to_longer_lifetime(bi: invariant/&r) -> invariant/&static { bi //~ ERROR mismatched types diff --git a/src/test/compile-fail/regions-infer-paramd-method.rs b/src/test/compile-fail/regions-infer-paramd-method.rs index a75e1deb6a2a3..0f1b23b2839c6 100644 --- a/src/test/compile-fail/regions-infer-paramd-method.rs +++ b/src/test/compile-fail/regions-infer-paramd-method.rs @@ -17,14 +17,16 @@ trait foo { fn any_int() -> ∫ } -type with_foo = {mut f: foo}; +struct with_foo { + f: foo +} trait set_foo_foo { - fn set_foo(f: foo); + fn set_foo(&mut self, f: foo); } impl set_foo_foo for with_foo { - fn set_foo(f: foo) { + fn set_foo(&mut self, f: foo) { self.f = f; //~ ERROR mismatched types: expected `@foo/&self` but found `@foo/&` } } @@ -35,14 +37,16 @@ trait bar { fn any_int() -> ∫ } -type with_bar = {mut f: bar}; +struct with_bar { + f: bar +} trait set_foo_bar { - fn set_foo(f: bar); + fn set_foo(&mut self, f: bar); } impl set_foo_bar for with_bar { - fn set_foo(f: bar) { + fn set_foo(&mut self, f: bar) { self.f = f; } } diff --git a/src/test/compile-fail/regions-scoping.rs b/src/test/compile-fail/regions-scoping.rs index 380a9a57d01fe..063bc32f7b446 100644 --- a/src/test/compile-fail/regions-scoping.rs +++ b/src/test/compile-fail/regions-scoping.rs @@ -10,13 +10,13 @@ fn with(t: T, f: fn(T)) { f(t) } -fn nested(x: &x/int) { // (1) +fn nested<'x>(x: &'x int) { // (1) do with( - fn&(x: &x/int, // Refers to the region `x` at (1) - y: &y/int, // A fresh region `y` (2) - z: fn(x: &x/int, // Refers to `x` at (1) - y: &y/int, // Refers to `y` at (2) - z: &z/int) -> &z/int) // A fresh region `z` (3) + fn&(x: &'x int, // Refers to the region `x` at (1) + y: &'y int, // A fresh region `y` (2) + z: fn<'z>(x: &'x int, // Refers to `x` at (1) + y: &'y int, // Refers to `y` at (2) + z: &'z int) -> &'z int) // A fresh region `z` (3) -> &x/int { if false { return z(x, y, x); } @@ -29,13 +29,13 @@ fn nested(x: &x/int) { // (1) } ) |foo| { - let a: &x/int = foo(x, x, |_x, _y, z| z ); - let b: &x/int = foo(x, a, |_x, _y, z| z ); - let c: &x/int = foo(a, a, |_x, _y, z| z ); + let a: &'x int = foo(x, x, |_x, _y, z| z ); + let b: &'x int = foo(x, a, |_x, _y, z| z ); + let c: &'x int = foo(a, a, |_x, _y, z| z ); let z = 3i; - let d: &x/int = foo(x, x, |_x, _y, z| z ); - let e: &x/int = foo(x, &z, |_x, _y, z| z ); + let d: &'x int = foo(x, x, |_x, _y, z| z ); + let e: &'x int = foo(x, &z, |_x, _y, z| z ); // This would result in an error, but it is not reported by typeck // anymore but rather borrowck. Therefore, it doesn't end up diff --git a/src/test/compile-fail/regions-trait-1.rs b/src/test/compile-fail/regions-trait-1.rs index de31c64328f92..4a78fdf97140a 100644 --- a/src/test/compile-fail/regions-trait-1.rs +++ b/src/test/compile-fail/regions-trait-1.rs @@ -8,14 +8,14 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -type ctxt = { v: uint }; +struct ctxt { v: uint } trait get_ctxt { // Here the `&` is bound in the method definition: fn get_ctxt() -> &ctxt; } -type has_ctxt = { c: &ctxt }; +struct has_ctxt { c: &ctxt } impl get_ctxt for has_ctxt { @@ -32,7 +32,7 @@ fn get_v(gc: get_ctxt) -> uint { } fn main() { - let ctxt = { v: 22u }; - let hc = { c: &ctxt }; + let ctxt = ctxt { v: 22u }; + let hc = has_ctxt { c: &ctxt }; assert get_v(hc as get_ctxt) == 22u; } diff --git a/src/test/compile-fail/regions-trait-2.rs b/src/test/compile-fail/regions-trait-2.rs index f19417425aace..2cb1f9deb496f 100644 --- a/src/test/compile-fail/regions-trait-2.rs +++ b/src/test/compile-fail/regions-trait-2.rs @@ -8,21 +8,21 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -type ctxt = { v: uint }; +struct ctxt { v: uint } trait get_ctxt { fn get_ctxt() -> &self/ctxt; } -type has_ctxt = { c: &ctxt }; +struct has_ctxt { c: &ctxt } impl get_ctxt for has_ctxt { fn get_ctxt() -> &self/ctxt { self.c } } fn make_gc() -> get_ctxt { - let ctxt = { v: 22u }; - let hc = { c: &ctxt }; //~ ERROR illegal borrow + let ctxt = ctxt { v: 22u }; + let hc = has_ctxt { c: &ctxt }; //~ ERROR illegal borrow return hc as get_ctxt; } diff --git a/src/test/compile-fail/tps-invariant-class.rs b/src/test/compile-fail/tps-invariant-class.rs index c1a0b2209711c..0411eeb05ebe1 100644 --- a/src/test/compile-fail/tps-invariant-class.rs +++ b/src/test/compile-fail/tps-invariant-class.rs @@ -9,7 +9,7 @@ // except according to those terms. struct box_impl { - mut f: T, + f: T, } fn box_impl(f: T) -> box_impl { diff --git a/src/test/compile-fail/tps-invariant-enum.rs b/src/test/compile-fail/tps-invariant-enum.rs index 1514dc5fd546d..967b201908c4b 100644 --- a/src/test/compile-fail/tps-invariant-enum.rs +++ b/src/test/compile-fail/tps-invariant-enum.rs @@ -8,21 +8,23 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -enum box_impl = { - mut f: T -}; +struct box { + f: T +} + +enum 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>({mut f: @3}); + 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>({mut f: x}); + 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 index f2e030b259ed5..60da6d2208a83 100644 --- a/src/test/compile-fail/tps-invariant-trait.rs +++ b/src/test/compile-fail/tps-invariant-trait.rs @@ -13,9 +13,11 @@ trait box_trait { fn set(t: T); } -enum box_impl = { - mut f: T -}; +struct box { + f: T +} + +enum box_impl = box; impl box_trait for box_impl { fn get() -> T { return self.f; } @@ -31,7 +33,7 @@ fn set_box_impl(b: box_impl<@const T>, v: @const T) { } fn main() { - let b = box_impl::<@int>({mut f: @3}); + 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); diff --git a/src/test/compile-fail/unique-pinned-nocopy.rs b/src/test/compile-fail/unique-pinned-nocopy.rs index 1eebc7701328c..12eef71f38bb3 100644 --- a/src/test/compile-fail/unique-pinned-nocopy.rs +++ b/src/test/compile-fail/unique-pinned-nocopy.rs @@ -17,7 +17,7 @@ impl Drop for r { } fn main() { - let i = move ~r { b: true }; + let i = ~r { b: true }; let _j = copy i; //~ ERROR copying a value of non-copyable type log(debug, i); } diff --git a/src/test/compile-fail/unique-unique-kind.rs b/src/test/compile-fail/unique-unique-kind.rs index 25c42ab4adde5..26058bf89cad7 100644 --- a/src/test/compile-fail/unique-unique-kind.rs +++ b/src/test/compile-fail/unique-unique-kind.rs @@ -8,10 +8,10 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -fn f(_i: T) { +fn f(_i: T) { } fn main() { let i = ~@100; - f(move i); //~ ERROR does not fulfill `Owned` + f(i); //~ ERROR does not fulfill `Owned` } diff --git a/src/test/compile-fail/unique-vec-res.rs b/src/test/compile-fail/unique-vec-res.rs index 28a7b37d6e20b..4ff9dd6f9914e 100644 --- a/src/test/compile-fail/unique-vec-res.rs +++ b/src/test/compile-fail/unique-vec-res.rs @@ -24,8 +24,8 @@ fn f(+_i: ~[T], +_j: ~[T]) { fn main() { let i1 = @mut 0; let i2 = @mut 1; - let r1 = move ~[~r { i: i1 }]; - let r2 = move ~[~r { i: i2 }]; + let r1 = ~[~r { i: i1 }]; + let r2 = ~[~r { i: i2 }]; f(copy r1, copy r2); //~^ ERROR copying a value of non-copyable type //~^^ ERROR copying a value of non-copyable type diff --git a/src/test/compile-fail/unsendable-class.rs b/src/test/compile-fail/unsendable-class.rs index e660884e40b9e..3eebc4647c28b 100644 --- a/src/test/compile-fail/unsendable-class.rs +++ b/src/test/compile-fail/unsendable-class.rs @@ -25,6 +25,6 @@ fn foo(i:int, j: @~str) -> foo { fn main() { let cat = ~"kitty"; - let (_, ch) = pipes::stream(); //~ ERROR does not fulfill `Owned` - ch.send(foo(42, @(move cat))); //~ ERROR does not fulfill `Owned` + let (_, ch) = comm::stream(); //~ ERROR does not fulfill `Owned` + ch.send(foo(42, @(cat))); //~ ERROR does not fulfill `Owned` } diff --git a/src/test/compile-fail/vec-concat-bug.rs b/src/test/compile-fail/vec-concat-bug.rs index f9ad20eaeb9b4..478e01ccd042e 100644 --- a/src/test/compile-fail/vec-concat-bug.rs +++ b/src/test/compile-fail/vec-concat-bug.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -fn concat(v: ~[const ~[const T]]) -> ~[T] { +fn concat(v: ~[const ~[const T]]) -> ~[T] { let mut r = ~[]; // Earlier versions of our type checker accepted this: diff --git a/src/test/compile-fail/vec-res-add.rs b/src/test/compile-fail/vec-res-add.rs index f21a202dcd82b..b06f91d50f25c 100644 --- a/src/test/compile-fail/vec-res-add.rs +++ b/src/test/compile-fail/vec-res-add.rs @@ -22,8 +22,8 @@ impl Drop for r { fn main() { // This can't make sense as it would copy the classes - let i = move ~[r(0)]; - let j = move ~[r(1)]; + let i = ~[r(0)]; + let j = ~[r(1)]; let k = i + j; log(debug, j); } diff --git a/src/test/compile-fail/vtable-res-trait-param.rs b/src/test/compile-fail/vtable-res-trait-param.rs index 7b48eca3dbe23..bd886f44ede84 100644 --- a/src/test/compile-fail/vtable-res-trait-param.rs +++ b/src/test/compile-fail/vtable-res-trait-param.rs @@ -13,16 +13,16 @@ trait TraitA { } trait TraitB { - fn gimme_an_a(a: A) -> int; + fn gimme_an_a(a: A) -> int; } impl TraitB for int { - fn gimme_an_a(a: A) -> int { + fn gimme_an_a(a: A) -> int { a.method_a() + self } } -fn call_it(b: B) -> int { +fn call_it(b: B) -> int { let y = 4u; b.gimme_an_a(y) //~ ERROR failed to find an implementation of trait @TraitA } diff --git a/src/test/pretty/block-disambig.rs b/src/test/pretty/block-disambig.rs index 17a2db5d1f067..5cc8f6e6edc58 100644 --- a/src/test/pretty/block-disambig.rs +++ b/src/test/pretty/block-disambig.rs @@ -16,10 +16,10 @@ fn test1() { let val = @0; { } *val; } fn test2() -> int { let val = @0; { } *val } -struct S { mut eax: int } +struct S { eax: int } fn test3() { - let regs = @S {mut eax: 0}; + let regs = @mut S {eax: 0}; match true { true => { } _ => { } } (*regs).eax = 1; } diff --git a/src/test/pretty/doc-comments.rs b/src/test/pretty/doc-comments.rs index d3e7c7b44dd1b..a866afd240592 100644 --- a/src/test/pretty/doc-comments.rs +++ b/src/test/pretty/doc-comments.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. // @@ -19,6 +19,14 @@ fn b() { //! some single line inner-docs } +////////////////////////////////// +// some single-line non-doc comment preceded by a separator + +////////////////////////////////// +/// some single-line outer-docs preceded by a separator +/// (and trailing whitespaces) +fn c() { } + /* * some multi-line non-doc comment */ @@ -26,17 +34,28 @@ fn b() { /** * some multi-line outer-docs */ -fn c() { } +fn d() { } -fn d() { +fn e() { /*! * some multi-line inner-docs */ } +/********************************/ +/* + * some multi-line non-doc comment preceded by a separator + */ + +/********************************/ +/** + * some multi-line outer-docs preceded by a separator + */ +fn f() { } + #[doc = "unsugared outer doc-comments work also"] -fn e() { } +fn g() { } -fn f() { +fn h() { #[doc = "as do inner ones"]; } diff --git a/src/test/run-fail/bug-2470-bounds-check-overflow.rs b/src/test/run-fail/bug-2470-bounds-check-overflow.rs index fb98a711cac21..6a6402c6a5eea 100644 --- a/src/test/run-fail/bug-2470-bounds-check-overflow.rs +++ b/src/test/run-fail/bug-2470-bounds-check-overflow.rs @@ -20,8 +20,8 @@ fn main() { let x = ~[1u,2u,3u]; do vec::as_imm_buf(x) |p, _len| { - let base = p as uint; // base = 0x1230 say - let idx = base / sys::size_of::(); // idx = 0x0246 say + let base = p as uint; + let idx = base / sys::size_of::(); error!("ov1 base = 0x%x", base); error!("ov1 idx = 0x%x", idx); error!("ov1 sizeof::() = 0x%x", sys::size_of::()); diff --git a/src/test/run-fail/bug-811.rs b/src/test/run-fail/bug-811.rs index 85e0f3dd398ee..4dada6257d4b0 100644 --- a/src/test/run-fail/bug-811.rs +++ b/src/test/run-fail/bug-811.rs @@ -16,6 +16,6 @@ type port_id = int; enum chan_t = {task: task_id, port: port_id}; -fn send(ch: chan_t, data: T) { fail!(); } +fn send(ch: chan_t, data: T) { fail!(); } fn main() { fail!(~"quux"); } diff --git a/src/test/run-fail/linked-failure.rs b/src/test/run-fail/linked-failure.rs index d592fb80f7682..e8bb075ac00fe 100644 --- a/src/test/run-fail/linked-failure.rs +++ b/src/test/run-fail/linked-failure.rs @@ -16,7 +16,7 @@ extern mod std; fn child() { assert (1 == 2); } fn main() { - let (p, _c) = pipes::stream::(); + let (p, _c) = comm::stream::(); task::spawn(|| child() ); let x = p.recv(); } diff --git a/src/test/run-fail/linked-failure2.rs b/src/test/run-fail/linked-failure2.rs index 1402020c357ec..9f09c16ed6a57 100644 --- a/src/test/run-fail/linked-failure2.rs +++ b/src/test/run-fail/linked-failure2.rs @@ -15,7 +15,7 @@ fn child() { fail!(); } fn main() { - let (p, _c) = pipes::stream::<()>(); + let (p, _c) = comm::stream::<()>(); task::spawn(|| child() ); task::yield(); } diff --git a/src/test/run-fail/linked-failure3.rs b/src/test/run-fail/linked-failure3.rs index cb03a71aabcdd..c2c97662b6c96 100644 --- a/src/test/run-fail/linked-failure3.rs +++ b/src/test/run-fail/linked-failure3.rs @@ -15,13 +15,13 @@ fn grandchild() { fail!(~"grandchild dies"); } fn child() { - let (p, _c) = pipes::stream::(); + let (p, _c) = comm::stream::(); task::spawn(|| grandchild() ); let x = p.recv(); } fn main() { - let (p, _c) = pipes::stream::(); + let (p, _c) = comm::stream::(); task::spawn(|| child() ); let x = p.recv(); } diff --git a/src/test/run-fail/linked-failure4.rs b/src/test/run-fail/linked-failure4.rs index 18d6b3c369bc1..97e4edc81bccd 100644 --- a/src/test/run-fail/linked-failure4.rs +++ b/src/test/run-fail/linked-failure4.rs @@ -14,7 +14,7 @@ fn child() { assert (1 == 2); } fn parent() { - let (p, _c) = pipes::stream::(); + let (p, _c) = comm::stream::(); task::spawn(|| child() ); let x = p.recv(); } @@ -22,7 +22,7 @@ fn parent() { // This task is not linked to the failure chain, but since the other // tasks are going to fail the kernel, this one will fail too fn sleeper() { - let (p, _c) = pipes::stream::(); + let (p, _c) = comm::stream::(); let x = p.recv(); } diff --git a/src/test/run-fail/out-of-stack-managed-box.rs b/src/test/run-fail/out-of-stack-managed-box.rs index 85857486cbbb7..9dcdaacb3c1a4 100644 --- a/src/test/run-fail/out-of-stack-managed-box.rs +++ b/src/test/run-fail/out-of-stack-managed-box.rs @@ -15,11 +15,11 @@ // error-pattern:ran out of stack fn main() { - eat(move @0); + eat(@0); } fn eat( +a: @int ) { - eat(move a) + eat(a) } diff --git a/src/test/run-fail/out-of-stack-owned-box.rs b/src/test/run-fail/out-of-stack-owned-box.rs index ef5101d1a9cd5..d4bc70f43ef6e 100644 --- a/src/test/run-fail/out-of-stack-owned-box.rs +++ b/src/test/run-fail/out-of-stack-owned-box.rs @@ -11,11 +11,11 @@ // xfail-test // error-pattern:ran out of stack fn main() { - eat(move ~0); + eat(~0); } fn eat( +a: ~int ) { - eat(move a) + eat(a) } diff --git a/src/test/run-fail/task-comm-recv-block.rs b/src/test/run-fail/task-comm-recv-block.rs index bd866b9f9e7c7..a0896ea7babbd 100644 --- a/src/test/run-fail/task-comm-recv-block.rs +++ b/src/test/run-fail/task-comm-recv-block.rs @@ -17,7 +17,7 @@ fn goodfail() { fn main() { task::spawn(|| goodfail() ); - let (po, _c) = pipes::stream(); + let (po, _c) = comm::stream(); // We shouldn't be able to get past this recv since there's no // message available let i: int = po.recv(); diff --git a/src/test/run-fail/too-much-recursion-unwinding.rs b/src/test/run-fail/too-much-recursion-unwinding.rs index b6a9bce934fa9..fbea8022cfc3c 100644 --- a/src/test/run-fail/too-much-recursion-unwinding.rs +++ b/src/test/run-fail/too-much-recursion-unwinding.rs @@ -39,6 +39,6 @@ fn r(recursed: *mut bool) -> r { fn main() { let mut recursed = false; - let _r = r(ptr::mut_addr_of(&recursed)); + let _r = r(&mut recursed); recurse(); } diff --git a/src/test/run-fail/unwind-box-res.rs b/src/test/run-fail/unwind-box-res.rs index f544438a7cae1..ba8f2fa37cb3b 100644 --- a/src/test/run-fail/unwind-box-res.rs +++ b/src/test/run-fail/unwind-box-res.rs @@ -36,7 +36,7 @@ fn main() { unsafe { let i1 = ~0; let i1p = cast::reinterpret_cast(&i1); - cast::forget(move i1); + cast::forget(i1); let x = @r(i1p); failfn(); log(error, x); diff --git a/src/test/run-fail/unwind-closure.rs b/src/test/run-fail/unwind-closure.rs index 34257b15b7fd8..6d52046b3e2fe 100644 --- a/src/test/run-fail/unwind-closure.rs +++ b/src/test/run-fail/unwind-closure.rs @@ -16,6 +16,6 @@ fn f(a: @int) { fn main() { let b = @0; - let g : fn@() = |move b|f(b); + let g : fn@() = || f(b); g(); } diff --git a/src/test/run-fail/unwind-move.rs b/src/test/run-fail/unwind-move.rs index 539896e831319..b2d30688ec55d 100644 --- a/src/test/run-fail/unwind-move.rs +++ b/src/test/run-fail/unwind-move.rs @@ -15,5 +15,5 @@ fn f(-_a: @int) { fn main() { let a = @0; - f(move a); + f(a); } diff --git a/src/test/run-fail/unwind-resource-fail.rs b/src/test/run-fail/unwind-resource-fail.rs index 8b9d1a6645714..0d57e9279bc72 100644 --- a/src/test/run-fail/unwind-resource-fail.rs +++ b/src/test/run-fail/unwind-resource-fail.rs @@ -19,5 +19,5 @@ fn r(i: int) -> r { r { i: i } } fn main() { @0; - let r = move r(0); + let r = r(0); } diff --git a/src/test/run-fail/unwind-resource-fail2.rs b/src/test/run-fail/unwind-resource-fail2.rs index 9c2c1a24a5e66..0b33326abe719 100644 --- a/src/test/run-fail/unwind-resource-fail2.rs +++ b/src/test/run-fail/unwind-resource-fail2.rs @@ -20,6 +20,6 @@ fn r(i: int) -> r { r { i: i } } fn main() { @0; - let r = move r(0); + let r = r(0); fail!(); } diff --git a/src/test/run-pass-fulldeps/issue-1926.rs b/src/test/run-pass-fulldeps/issue-1926.rs index 7d52f13b0750a..95a80630d7c6d 100644 --- a/src/test/run-pass-fulldeps/issue-1926.rs +++ b/src/test/run-pass-fulldeps/issue-1926.rs @@ -20,12 +20,12 @@ use syntax::parse::parser; fn new_parse_sess() -> parser::parse_sess { let cm = codemap::new_codemap(); let handler = diagnostic::mk_handler(option::none); - let sess = @{ + let sess = @mut { cm: cm, - mut next_id: 1, + next_id: 1, span_diagnostic: diagnostic::mk_span_handler(handler, cm), - mut chpos: 0u, - mut byte_pos: 0u + chpos: 0u, + byte_pos: 0u }; return sess; } 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 350132c15b829..2972c425192a8 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 @@ type pair = { a: A, b: B }; -fn f(a: A, b: u16) -> fn@() -> (A, u16) { +fn f(a: A, b: u16) -> fn@() -> (A, u16) { fn@() -> (A, u16) { (a, b) } } diff --git a/src/test/run-pass/alignment-gep-tup-like-2.rs b/src/test/run-pass/alignment-gep-tup-like-2.rs index e16fae776f7e9..2f008e5158695 100644 --- a/src/test/run-pass/alignment-gep-tup-like-2.rs +++ b/src/test/run-pass/alignment-gep-tup-like-2.rs @@ -15,15 +15,15 @@ struct Pair { enum RecEnum = Rec; struct Rec { val: A, - mut rec: Option<@RecEnum> + rec: Option<@mut RecEnum> } fn make_cycle(a: A) { - let g: @RecEnum = @RecEnum(Rec {val: a, mut rec: None}); + let g: @mut RecEnum = @mut RecEnum(Rec {val: a, rec: None}); g.rec = Some(g); } -fn f(a: A, b: B) -> fn@() -> (A, B) { +fn f(a: A, b: B) -> fn@() -> (A, B) { fn@() -> (A, B) { (a, b) } } diff --git a/src/test/run-pass/alloca-from-derived-tydesc.rs b/src/test/run-pass/alloca-from-derived-tydesc.rs index 37fdfca4468ce..ddaa38223ecae 100644 --- a/src/test/run-pass/alloca-from-derived-tydesc.rs +++ b/src/test/run-pass/alloca-from-derived-tydesc.rs @@ -10,8 +10,8 @@ enum option { some(T), none, } -struct R {mut v: ~[option]} +struct R {v: ~[option]} fn f() -> ~[T] { return ~[]; } -pub fn main() { let r: R = R {mut v: ~[]}; r.v = f(); } +pub fn main() { let mut r: R = R {v: ~[]}; r.v = f(); } diff --git a/src/test/run-pass/alt-implicit-copy-unique.rs b/src/test/run-pass/alt-implicit-copy-unique.rs index 58076b59cebfb..e73eb57d607c1 100644 --- a/src/test/run-pass/alt-implicit-copy-unique.rs +++ b/src/test/run-pass/alt-implicit-copy-unique.rs @@ -8,12 +8,12 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -struct Pair { mut a: ~int, mut b: ~int } +struct Pair { a: ~int, b: ~int } pub fn main() { - let x = ~Pair {mut a: ~10, b: ~20}; + let mut x = ~Pair {a: ~10, b: ~20}; match x { - ~Pair {a: ref mut a, b: ref b} => { + ~Pair {a: ref mut a, b: ref mut b} => { assert **a == 10; *a = ~30; assert **a == 30; } } diff --git a/src/test/run-pass/alt-ref-binding-in-guard-3256.rs b/src/test/run-pass/alt-ref-binding-in-guard-3256.rs index a04d8d4618a27..4474aec3d2e50 100644 --- a/src/test/run-pass/alt-ref-binding-in-guard-3256.rs +++ b/src/test/run-pass/alt-ref-binding-in-guard-3256.rs @@ -10,7 +10,7 @@ pub fn main() { let x = Some(private::exclusive(true)); - match move x { + match x { Some(ref z) if z.with(|b| *b) => { do z.with |b| { assert *b; } }, diff --git a/src/test/run-pass/argument-passing.rs b/src/test/run-pass/argument-passing.rs index e58dc29578d5f..95c23753c27e4 100644 --- a/src/test/run-pass/argument-passing.rs +++ b/src/test/run-pass/argument-passing.rs @@ -9,24 +9,23 @@ // except according to those terms. // xfail-fast -#[legacy_modes]; -struct X { mut x: int } +struct X { x: int } -fn f1(a: X, b: &mut int, -c: int) -> int { +fn f1(a: &mut X, b: &mut int, -c: int) -> int { let r = a.x + *b + c; a.x = 0; *b = 10; return r; } -fn f2(a: int, f: fn(int)) -> int { f(1); return a; } +fn f2(a: int, f: &fn(int)) -> int { f(1); return a; } pub fn main() { - let mut a = X {mut x: 1}, b = 2, c = 3; - assert (f1(a, &mut b, move c) == 6); + let mut a = X {x: 1}, b = 2, c = 3; + assert (f1(&mut a, &mut b, c) == 6); assert (a.x == 0); assert (b == 10); - assert (f2(a.x, |x| a.x = 50 ) == 0); + assert (f2(a.x, |x| a.x = 50) == 0); assert (a.x == 50); } diff --git a/src/test/run-pass/auto-encode.rs b/src/test/run-pass/auto-encode.rs index 53c572e75d099..e4004c6dc2217 100644 --- a/src/test/run-pass/auto-encode.rs +++ b/src/test/run-pass/auto-encode.rs @@ -26,7 +26,7 @@ use std::serialize::{Encodable, Decodable}; use std::prettyprint; use std::time; -fn test_prettyprint>( +fn test_prettyprint>( a: &A, expected: &~str ) { @@ -38,15 +38,15 @@ fn test_prettyprint>( } fn test_ebml + Eq + + Encodable + Decodable >(a1: &A) { let bytes = do io::with_bytes_writer |wr| { let ebml_w = &EBWriter::Encoder(wr); a1.encode(ebml_w) }; - let d = EBReader::Doc(@move bytes); + let d = EBReader::Doc(@bytes); let a2: A = Decodable::decode(&EBReader::Decoder(d)); assert *a1 == a2; } diff --git a/src/test/run-pass/auto-instantiate.rs b/src/test/run-pass/auto-instantiate.rs index 8f7a88f19a73a..4075ec5603813 100644 --- a/src/test/run-pass/auto-instantiate.rs +++ b/src/test/run-pass/auto-instantiate.rs @@ -16,7 +16,7 @@ struct Pair { a: T, b: U } struct Triple { x: int, y: int, z: int } -fn f(x: T, y: U) -> Pair { return Pair {a: x, b: y}; } +fn f(x: T, y: U) -> Pair { return Pair {a: x, b: y}; } pub fn main() { log(debug, f(Triple {x: 3, y: 4, z: 5}, 4).a.x); diff --git a/src/test/run-pass/auto-ref-sliceable.rs b/src/test/run-pass/auto-ref-sliceable.rs index 23165d026e812..87f70d00f8c9f 100644 --- a/src/test/run-pass/auto-ref-sliceable.rs +++ b/src/test/run-pass/auto-ref-sliceable.rs @@ -14,7 +14,7 @@ trait Pushable { impl Pushable for ~[T] { fn push_val(&mut self, +t: T) { - self.push(move t); + self.push(t); } } diff --git a/src/test/run-pass/autobind.rs b/src/test/run-pass/autobind.rs index 0b969540d74c0..316627e349be0 100644 --- a/src/test/run-pass/autobind.rs +++ b/src/test/run-pass/autobind.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -fn f(x: ~[T]) -> T { return x[0]; } +fn f(x: ~[T]) -> T { return x[0]; } fn g(act: fn(~[int]) -> int) -> int { return act(~[1, 2, 3]); } diff --git a/src/test/run-pass/autoderef-method-on-trait-monomorphized.rs b/src/test/run-pass/autoderef-method-on-trait-monomorphized.rs index 53dd6f942e860..b44d1cbb78d48 100644 --- a/src/test/run-pass/autoderef-method-on-trait-monomorphized.rs +++ b/src/test/run-pass/autoderef-method-on-trait-monomorphized.rs @@ -16,7 +16,7 @@ impl double for uint { fn double() -> uint { self * 2u } } -fn is_equal(x: @D, exp: uint) { +fn is_equal(x: @D, exp: uint) { assert x.double() == exp; } diff --git a/src/test/run-pass/autoref-intermediate-types-issue-3585.rs b/src/test/run-pass/autoref-intermediate-types-issue-3585.rs index 60f19b4db0a7d..8bc02eb2f9f3f 100644 --- a/src/test/run-pass/autoref-intermediate-types-issue-3585.rs +++ b/src/test/run-pass/autoref-intermediate-types-issue-3585.rs @@ -12,7 +12,7 @@ trait Foo { fn foo(&self) -> ~str; } -impl Foo for @T { +impl Foo for @T { fn foo(&self) -> ~str { fmt!("@%s", (**self).foo()) } diff --git a/src/test/run-pass/bind-by-move.rs b/src/test/run-pass/bind-by-move.rs index bdcc629566462..1e836740f8e81 100644 --- a/src/test/run-pass/bind-by-move.rs +++ b/src/test/run-pass/bind-by-move.rs @@ -17,8 +17,8 @@ fn dispose(+_x: arc::ARC) unsafe { } pub fn main() { let p = arc::arc(true); let x = Some(p); - match move x { - Some(move z) => { dispose(z); }, + match x { + Some(z) => { dispose(z); }, None => fail!() } } diff --git a/src/test/run-pass/binops.rs b/src/test/run-pass/binops.rs index 99379813840ff..2044a5c2346b4 100644 --- a/src/test/run-pass/binops.rs +++ b/src/test/run-pass/binops.rs @@ -86,9 +86,10 @@ extern mod test { pub fn get_task_id() -> libc::intptr_t; } +#[deriving_eq] struct p { - mut x: int, - mut y: int, + x: int, + y: int, } fn p(x: int, y: int) -> p { @@ -98,16 +99,9 @@ fn p(x: int, y: int) -> p { } } -impl cmp::Eq for p { - pure fn eq(&self, other: &p) -> bool { - (*self).x == (*other).x && (*self).y == (*other).y - } - pure fn ne(&self, other: &p) -> bool { !(*self).eq(other) } -} - fn test_class() { - let q = p(1, 2); - let r = p(1, 2); + let mut q = p(1, 2); + let mut r = p(1, 2); unsafe { error!("q = %x, r = %x", diff --git a/src/test/run-pass/bitv-perf-test.rs b/src/test/run-pass/bitv-perf-test.rs index 097db4436fdb0..6cb0cf4e3776d 100644 --- a/src/test/run-pass/bitv-perf-test.rs +++ b/src/test/run-pass/bitv-perf-test.rs @@ -14,8 +14,8 @@ extern mod std; use std::bitv::*; fn bitv_test() -> bool { - let v1 = ~Bitv(31, false); - let v2 = ~Bitv(31, true); + let mut v1 = ~Bitv::new(31, false); + let v2 = ~Bitv::new(31, true); v1.union(v2); true } diff --git a/src/test/run-pass/block-iter-1.rs b/src/test/run-pass/block-iter-1.rs index 6faf4129ba774..b23ce11226784 100644 --- a/src/test/run-pass/block-iter-1.rs +++ b/src/test/run-pass/block-iter-1.rs @@ -9,16 +9,15 @@ // except according to those terms. // xfail-fast -#[legacy_modes]; -fn iter_vec(v: ~[T], f: fn(T)) { for v.each |x| { f(*x); } } +fn iter_vec(v: ~[T], f: fn(&T)) { for v.each |x| { f(x); } } pub fn main() { let v = ~[1, 2, 3, 4, 5, 6, 7]; let mut odds = 0; iter_vec(v, |i| { log(error, i); - if i % 2 == 1 { + if *i % 2 == 1 { odds += 1; } log(error, odds); diff --git a/src/test/run-pass/block-iter-2.rs b/src/test/run-pass/block-iter-2.rs index d57346a329958..df49fc6a4ef5c 100644 --- a/src/test/run-pass/block-iter-2.rs +++ b/src/test/run-pass/block-iter-2.rs @@ -9,17 +9,16 @@ // except according to those terms. // xfail-fast -#[legacy_modes]; -fn iter_vec(v: ~[T], f: fn(T)) { for v.each |x| { f(*x); } } +fn iter_vec(v: ~[T], f: fn(&T)) { for v.each |x| { f(x); } } pub fn main() { let v = ~[1, 2, 3, 4, 5]; let mut sum = 0; iter_vec(copy v, |i| { iter_vec(copy v, |j| { - log(error, i * j); - sum += i * j; + log(error, *i * *j); + sum += *i * *j; }); }); log(error, sum); diff --git a/src/test/run-pass/borrowck-binding-mutbl.rs b/src/test/run-pass/borrowck-binding-mutbl.rs index 6e8b35f76788d..377ed2608e513 100644 --- a/src/test/run-pass/borrowck-binding-mutbl.rs +++ b/src/test/run-pass/borrowck-binding-mutbl.rs @@ -8,13 +8,13 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -struct F { mut f: ~[int] } +struct F { f: ~[int] } fn impure(_v: &[int]) { } pub fn main() { - let x = F {f: ~[3]}; + let mut x = F {f: ~[3]}; match x { F {f: ref mut v} => { diff --git a/src/test/run-pass/borrowck-move-from-unsafe-ptr-ok.rs b/src/test/run-pass/borrowck-move-from-unsafe-ptr-ok.rs index b54791328a0cb..2d83e9746b580 100644 --- a/src/test/run-pass/borrowck-move-from-unsafe-ptr-ok.rs +++ b/src/test/run-pass/borrowck-move-from-unsafe-ptr-ok.rs @@ -12,7 +12,7 @@ fn bar(x: *~int) -> ~int { unsafe { - let y = move *x; + let y = *x; return y; } } diff --git a/src/test/run-pass/borrowck-newtype-issue-2573.rs b/src/test/run-pass/borrowck-newtype-issue-2573.rs index 5dc373aa50fef..7e81345739f64 100644 --- a/src/test/run-pass/borrowck-newtype-issue-2573.rs +++ b/src/test/run-pass/borrowck-newtype-issue-2573.rs @@ -8,9 +8,11 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -enum foo = {mut bar: baz}; +struct foo {bar: baz} -enum baz = @{mut baz: int}; +struct baz_ {baz: int} + +type baz = @mut baz_; trait frob { fn frob(); diff --git a/src/test/run-pass/borrowck-root-while-cond-2.rs b/src/test/run-pass/borrowck-root-while-cond-2.rs index 5b2232daa4a1d..ea165e53ceb1a 100644 --- a/src/test/run-pass/borrowck-root-while-cond-2.rs +++ b/src/test/run-pass/borrowck-root-while-cond-2.rs @@ -8,10 +8,10 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -struct F { mut f: @G } +struct F { f: @G } struct G { g: ~[int] } pub fn main() { - let rec = @F {mut f: @G {g: ~[1, 2, 3]}}; + let rec = @mut F {f: @G {g: ~[1, 2, 3]}}; while rec.f.g.len() == 23 {} } diff --git a/src/test/run-pass/borrowck-root-while-cond.rs b/src/test/run-pass/borrowck-root-while-cond.rs index 432847cc1983c..285796db20e66 100644 --- a/src/test/run-pass/borrowck-root-while-cond.rs +++ b/src/test/run-pass/borrowck-root-while-cond.rs @@ -10,9 +10,9 @@ fn borrow(x: &r/T) -> &r/T {x} -struct Rec { mut f: @int } +struct Rec { f: @int } pub fn main() { - let rec = @Rec {mut f: @22}; + let rec = @mut Rec {f: @22}; while *borrow(rec.f) == 23 {} } diff --git a/src/test/run-pass/borrowed-ptr-pattern.rs b/src/test/run-pass/borrowed-ptr-pattern.rs index fdf4a16156064..b51481f1ea1a1 100644 --- a/src/test/run-pass/borrowed-ptr-pattern.rs +++ b/src/test/run-pass/borrowed-ptr-pattern.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -fn foo(x: &T) -> T{ +fn foo(x: &T) -> T{ match x { &a => a } diff --git a/src/test/run-pass/box-unbox.rs b/src/test/run-pass/box-unbox.rs index 6889d764cbbb0..1efe12c1a3c18 100644 --- a/src/test/run-pass/box-unbox.rs +++ b/src/test/run-pass/box-unbox.rs @@ -12,7 +12,7 @@ struct Box {c: @T} -fn unbox(b: Box) -> T { return *b.c; } +fn unbox(b: Box) -> T { return *b.c; } pub fn main() { let foo: int = 17; diff --git a/src/test/run-pass/boxed-class-type-substitution.rs b/src/test/run-pass/boxed-class-type-substitution.rs index 4fe553ec03958..025bf8fd9d94f 100644 --- a/src/test/run-pass/boxed-class-type-substitution.rs +++ b/src/test/run-pass/boxed-class-type-substitution.rs @@ -12,7 +12,7 @@ // the boxed type parameter type Tree = { - mut parent: Option, + parent: Option, }; fn empty() -> Tree { fail!() } @@ -28,7 +28,7 @@ fn Box() -> Box { } enum layout_data = { - mut box: Option<@Box> + box: Option<@Box> }; pub fn main() { } diff --git a/src/test/run-pass/cap-clause-move.rs b/src/test/run-pass/cap-clause-move.rs index dd4c7ba6a85cb..e27434400c185 100644 --- a/src/test/run-pass/cap-clause-move.rs +++ b/src/test/run-pass/cap-clause-move.rs @@ -11,21 +11,21 @@ pub fn main() { let x = ~1; let y = ptr::addr_of(&(*x)) as uint; - let lam_move = fn@(move x) -> uint { ptr::addr_of(&(*x)) as uint }; + let lam_move = fn@() -> uint { ptr::addr_of(&(*x)) as uint }; assert lam_move() == y; let x = ~2; let y = ptr::addr_of(&(*x)) as uint; - let lam_move: fn@() -> uint = |move x| ptr::addr_of(&(*x)) as uint; + let lam_move: fn@() -> uint = || ptr::addr_of(&(*x)) as uint; assert lam_move() == y; let x = ~3; let y = ptr::addr_of(&(*x)) as uint; - let snd_move = fn~(move x) -> uint { ptr::addr_of(&(*x)) as uint }; + let snd_move = fn~() -> uint { ptr::addr_of(&(*x)) as uint }; assert snd_move() == y; let x = ~4; let y = ptr::addr_of(&(*x)) as uint; - let lam_move: fn~() -> uint = |move x| ptr::addr_of(&(*x)) as uint; + let lam_move: fn~() -> uint = || ptr::addr_of(&(*x)) as uint; assert lam_move() == y; } diff --git a/src/test/run-pass/capture_nil.rs b/src/test/run-pass/capture_nil.rs index 6c052b95a2bc5..99d8fab4bba50 100644 --- a/src/test/run-pass/capture_nil.rs +++ b/src/test/run-pass/capture_nil.rs @@ -24,11 +24,11 @@ // course preferable, as the value itself is // irrelevant). -use core::pipes::*; +use core::comm::*; fn foo(&&x: ()) -> Port<()> { let (p, c) = stream::<()>(); - do task::spawn() |copy x| { + do task::spawn() { c.send(x); } p diff --git a/src/test/run-pass/class-cast-to-trait-cross-crate-2.rs b/src/test/run-pass/class-cast-to-trait-cross-crate-2.rs index 1d1b07ae32461..f81b12b555e4b 100644 --- a/src/test/run-pass/class-cast-to-trait-cross-crate-2.rs +++ b/src/test/run-pass/class-cast-to-trait-cross-crate-2.rs @@ -14,7 +14,7 @@ extern mod cci_class_cast; use core::to_str::ToStr; use cci_class_cast::kitty::*; -fn print_out(thing: T, expected: ~str) { +fn print_out(thing: T, expected: ~str) { let actual = thing.to_str(); debug!("%s", actual); assert(actual == expected); diff --git a/src/test/run-pass/class-cast-to-trait-cross-crate.rs b/src/test/run-pass/class-cast-to-trait-cross-crate.rs index 36e6c6b487d5a..d21ff90e7fbd5 100644 --- a/src/test/run-pass/class-cast-to-trait-cross-crate.rs +++ b/src/test/run-pass/class-cast-to-trait-cross-crate.rs @@ -48,7 +48,7 @@ class cat : to_str { fn to_str() -> str { self.name } } -fn print_out(thing: T, expected: str) { +fn print_out(thing: T, expected: str) { let actual = thing.to_str(); debug!("%s", actual); assert(actual == expected); diff --git a/src/test/run-pass/class-cast-to-trait-multiple-types.rs b/src/test/run-pass/class-cast-to-trait-multiple-types.rs index b72a8e5da2710..f35a91c2b914f 100644 --- a/src/test/run-pass/class-cast-to-trait-multiple-types.rs +++ b/src/test/run-pass/class-cast-to-trait-multiple-types.rs @@ -79,7 +79,7 @@ fn cat(in_x : uint, in_y : int, in_name: ~str) -> cat { } -fn annoy_neighbors(critter: T) { +fn annoy_neighbors(critter: T) { for uint::range(0u, 10u) |i| { critter.speak(); } } 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 01b72c9d99592..09cf008fd099a 100644 --- a/src/test/run-pass/class-impl-very-parameterized-trait.rs +++ b/src/test/run-pass/class-impl-very-parameterized-trait.rs @@ -127,7 +127,7 @@ priv impl cat { } } -fn main() { +pub fn main() { let mut nyan: cat<~str> = cat::new(0, 2, ~"nyan"); for uint::range(1, 5) |_| { nyan.speak(); } assert(*nyan.find(&1).unwrap() == ~"nyan"); diff --git a/src/test/run-pass/class-implement-traits.rs b/src/test/run-pass/class-implement-traits.rs index 06a2dbeb9a499..15564d73e1f70 100644 --- a/src/test/run-pass/class-implement-traits.rs +++ b/src/test/run-pass/class-implement-traits.rs @@ -59,7 +59,7 @@ fn cat(in_x : uint, in_y : int, in_name: ~str) -> cat { } -fn make_speak(c: C) { +fn make_speak(c: C) { c.speak(); } diff --git a/src/test/run-pass/class-implements-multiple-traits.rs b/src/test/run-pass/class-implements-multiple-traits.rs index 6d2fb9843652e..a05b74c9a3c55 100644 --- a/src/test/run-pass/class-implements-multiple-traits.rs +++ b/src/test/run-pass/class-implements-multiple-traits.rs @@ -96,14 +96,14 @@ class cat : noisy, scratchy, bitey { } } -fn annoy_neighbors(critter: T) { +fn annoy_neighbors(critter: T) { for uint::range(0u, 10u) |i| { let what = critter.speak(); debug!("%u %d", i, what); } } -fn bite_everything(critter: T) -> bool { +fn bite_everything(critter: T) -> bool { let mut left : ~[body_part] = ~[finger, toe, nose, ear]; while vec::len(left) > 0u { let part = critter.bite(); @@ -118,7 +118,7 @@ fn bite_everything(critter: T) -> bool { true } -fn scratched_something(critter: T) -> bool { +fn scratched_something(critter: T) -> bool { option::is_some(critter.scratch()) } diff --git a/src/test/run-pass/class-poly-methods.rs b/src/test/run-pass/class-poly-methods.rs index b7e638f40e8c0..5ef5e55b7293e 100644 --- a/src/test/run-pass/class-poly-methods.rs +++ b/src/test/run-pass/class-poly-methods.rs @@ -26,7 +26,7 @@ fn cat(in_x : uint, in_y : int, -in_info: ~[U]) -> cat { cat { meows: in_x, how_hungry: in_y, - info: move in_info + info: in_info } } diff --git a/src/test/run-pass/class-separate-impl.rs b/src/test/run-pass/class-separate-impl.rs index 919fb058a953a..fda358a86a2f5 100644 --- a/src/test/run-pass/class-separate-impl.rs +++ b/src/test/run-pass/class-separate-impl.rs @@ -57,7 +57,7 @@ impl ToStr for cat { pure fn to_str(&self) -> ~str { copy self.name } } -fn print_out(thing: T, expected: ~str) { +fn print_out(thing: T, expected: ~str) { let actual = thing.to_str(); debug!("%s", actual); assert(actual == expected); diff --git a/src/test/run-pass/class-trait-bounded-param.rs b/src/test/run-pass/class-trait-bounded-param.rs index e3c4703432fec..5e39b18db7375 100644 --- a/src/test/run-pass/class-trait-bounded-param.rs +++ b/src/test/run-pass/class-trait-bounded-param.rs @@ -13,7 +13,7 @@ extern mod std; use std::oldmap::{map, hashmap, int_hash}; -class keys> +class keys> : iter::base_iter { let map: M; 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 d218519a4f3e5..32f39177e1c06 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 @@ type pair = { a: A, b: B }; -fn f(a: A, b: u16) -> fn@() -> (A, u16) { +fn f(a: A, b: u16) -> fn@() -> (A, u16) { fn@() -> (A, u16) { (a, b) } } diff --git a/src/test/run-pass/closure-inference.rs b/src/test/run-pass/closure-inference.rs index 99c8fd6e2d301..33202193acbc8 100644 --- a/src/test/run-pass/closure-inference.rs +++ b/src/test/run-pass/closure-inference.rs @@ -9,7 +9,6 @@ // except according to those terms. // xfail-fast -#[legacy_modes]; fn foo(i: int) -> int { i + 1 } diff --git a/src/test/run-pass/comm.rs b/src/test/run-pass/comm.rs index 1af0bb003f2bb..da467ae7ba596 100644 --- a/src/test/run-pass/comm.rs +++ b/src/test/run-pass/comm.rs @@ -9,7 +9,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use core::pipes::*; +use core::comm::*; pub fn main() { let (p, ch) = stream(); diff --git a/src/test/run-pass/const-bound.rs b/src/test/run-pass/const-bound.rs index 2320a5b1aa389..d4467ca0c7a06 100644 --- a/src/test/run-pass/const-bound.rs +++ b/src/test/run-pass/const-bound.rs @@ -12,7 +12,7 @@ // are const. -fn foo(x: T) -> T { x } +fn foo(x: T) -> T { x } struct F { field: int } diff --git a/src/test/compile-fail/issue-3033.rs b/src/test/run-pass/const-enum-newtype-align.rs similarity index 63% rename from src/test/compile-fail/issue-3033.rs rename to src/test/run-pass/const-enum-newtype-align.rs index 1d54e03490175..9c9013ef86082 100644 --- a/src/test/compile-fail/issue-3033.rs +++ b/src/test/run-pass/const-enum-newtype-align.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,9 +8,10 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -type cat = {cat_name: ~str, cat_name: int}; //~ ERROR Duplicate field name cat_name +enum E = u32; +struct S { a: u8, b: E } +const C: S = S { a: 0xA5, b: E(0xDEADBEEF) }; -fn main() -{ - io::println(int::str({x: 1, x: 2}.x)); //~ ERROR Duplicate field name x +pub fn main() { + assert C.b == 0xDEADBEEF; } diff --git a/src/test/run-pass/const-enum-ptr.rs b/src/test/run-pass/const-enum-ptr.rs index 92b74902efb13..6004f9b9001c2 100644 --- a/src/test/run-pass/const-enum-ptr.rs +++ b/src/test/run-pass/const-enum-ptr.rs @@ -11,7 +11,7 @@ enum E { V0, V1(int) } const C: &static/E = &V0; -fn main() { +pub fn main() { match *C { V0 => (), _ => fail!() diff --git a/src/test/run-pass/const-enum-struct.rs b/src/test/run-pass/const-enum-struct.rs index 463b8452bb8ef..f8fb407244bce 100644 --- a/src/test/run-pass/const-enum-struct.rs +++ b/src/test/run-pass/const-enum-struct.rs @@ -12,7 +12,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 }; -fn main() { +pub fn main() { let n = C.b; assert n != 0xBAD; assert n == 0x600D; diff --git a/src/test/run-pass/const-enum-struct2.rs b/src/test/run-pass/const-enum-struct2.rs index f34549326780e..12bc06d5f06ca 100644 --- a/src/test/run-pass/const-enum-struct2.rs +++ b/src/test/run-pass/const-enum-struct2.rs @@ -12,7 +12,7 @@ enum E { V0, V16(u16) } struct S { a: E, b: u16, c: u16 } const C: S = S { a: V0, b: 0x600D, c: 0xBAD }; -fn main() { +pub fn main() { let n = C.b; assert n != 0xBAD; assert n == 0x600D; diff --git a/src/test/run-pass/const-enum-tuple.rs b/src/test/run-pass/const-enum-tuple.rs index a55554921c497..df41f5129caea 100644 --- a/src/test/run-pass/const-enum-tuple.rs +++ b/src/test/run-pass/const-enum-tuple.rs @@ -11,7 +11,7 @@ enum E { V16(u16), V32(u32) } const C: (E, u16, u16) = (V16(0xDEAD), 0x600D, 0xBAD); -fn main() { +pub fn main() { let (_, n, _) = C; assert n != 0xBAD; assert n == 0x600D; diff --git a/src/test/run-pass/const-enum-tuple2.rs b/src/test/run-pass/const-enum-tuple2.rs index c02bdc74cfe44..ec585f1e0d823 100644 --- a/src/test/run-pass/const-enum-tuple2.rs +++ b/src/test/run-pass/const-enum-tuple2.rs @@ -11,7 +11,7 @@ enum E { V0, V16(u16) } const C: (E, u16, u16) = (V0, 0x600D, 0xBAD); -fn main() { +pub fn main() { let (_, n, _) = C; assert n != 0xBAD; assert n == 0x600D; diff --git a/src/test/run-pass/const-enum-tuplestruct.rs b/src/test/run-pass/const-enum-tuplestruct.rs index d9194ff26b1da..db2c637f10eee 100644 --- a/src/test/run-pass/const-enum-tuplestruct.rs +++ b/src/test/run-pass/const-enum-tuplestruct.rs @@ -12,7 +12,7 @@ enum E { V16(u16), V32(u32) } struct S(E, u16, u16); const C: S = S(V16(0xDEAD), 0x600D, 0xBAD); -fn main() { +pub fn main() { let S(_, n, _) = C; assert n != 0xBAD; assert n == 0x600D; diff --git a/src/test/run-pass/const-enum-tuplestruct2.rs b/src/test/run-pass/const-enum-tuplestruct2.rs index b6d9d01479e13..b07ac6cb28f42 100644 --- a/src/test/run-pass/const-enum-tuplestruct2.rs +++ b/src/test/run-pass/const-enum-tuplestruct2.rs @@ -12,7 +12,7 @@ enum E { V0, V16(u16) } struct S(E, u16, u16); const C: S = S(V0, 0x600D, 0xBAD); -fn main() { +pub fn main() { let S(_, n, _) = C; assert n != 0xBAD; assert n == 0x600D; diff --git a/src/test/run-pass/const-enum-vec-index.rs b/src/test/run-pass/const-enum-vec-index.rs index ed9075f4932dd..a9400ef1b6b04 100644 --- a/src/test/run-pass/const-enum-vec-index.rs +++ b/src/test/run-pass/const-enum-vec-index.rs @@ -13,7 +13,7 @@ const C: &[E] = &[V0, V1(0xDEADBEE)]; const C0: E = C[0]; const C1: E = C[1]; -fn main() { +pub fn main() { match C0 { V0 => (), _ => fail!() diff --git a/src/test/run-pass/const-enum-vec-ptr.rs b/src/test/run-pass/const-enum-vec-ptr.rs index 60023889305d4..b143e20f624ab 100644 --- a/src/test/run-pass/const-enum-vec-ptr.rs +++ b/src/test/run-pass/const-enum-vec-ptr.rs @@ -11,7 +11,7 @@ enum E { V1(int), V0 } const C: &static/[E] = &[V0, V1(0xDEADBEE), V0]; -fn main() { +pub fn main() { match C[1] { V1(n) => assert(n == 0xDEADBEE), _ => fail!() diff --git a/src/test/run-pass/const-enum-vector.rs b/src/test/run-pass/const-enum-vector.rs index b95c42fc49389..0556bd0ea48d3 100644 --- a/src/test/run-pass/const-enum-vector.rs +++ b/src/test/run-pass/const-enum-vector.rs @@ -11,7 +11,7 @@ enum E { V1(int), V0 } const C: [E * 3] = [V0, V1(0xDEADBEE), V0]; -fn main() { +pub fn main() { match C[1] { V1(n) => assert(n == 0xDEADBEE), _ => fail!() diff --git a/src/test/run-pass/cycle-collection2.rs b/src/test/run-pass/cycle-collection2.rs index 127a1c9703896..125c3ba1027b7 100644 --- a/src/test/run-pass/cycle-collection2.rs +++ b/src/test/run-pass/cycle-collection2.rs @@ -8,13 +8,13 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -struct foo { mut z : fn@() } +struct foo { z: fn@() } fn nop() { } -fn nop_foo(_x : @foo) { } +fn nop_foo(_x : @mut foo) { } pub fn main() { - let w = @foo{ mut z: || nop() }; - let x : fn@() = || nop_foo(w); + let w = @mut foo{ z: || nop() }; + let x: fn@() = || nop_foo(w); w.z = x; } diff --git a/src/test/run-pass/cycle-collection5.rs b/src/test/run-pass/cycle-collection5.rs index 6f3297c660272..fe0d294f01a7a 100644 --- a/src/test/run-pass/cycle-collection5.rs +++ b/src/test/run-pass/cycle-collection5.rs @@ -8,15 +8,15 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -struct foo { mut z : fn@() } +struct foo { z: fn@() } fn nop() { } -fn nop_foo(_y: @int, _x : @foo) { } +fn nop_foo(_y: @int, _x: @mut foo) { } fn o() -> @int { @10 } pub fn main() { - let w = @foo { mut z: || nop() }; + let w = @mut foo { z: || nop() }; let x : fn@() = || nop_foo(o(), w); w.z = x; } diff --git a/src/test/run-pass/deriving-via-extension-struct-empty.rs b/src/test/run-pass/deriving-via-extension-struct-empty.rs new file mode 100644 index 0000000000000..70a13f972b806 --- /dev/null +++ b/src/test/run-pass/deriving-via-extension-struct-empty.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_eq] +struct Foo; + +pub fn main() { + assert Foo == Foo; + assert !(Foo != Foo); +} \ No newline at end of file diff --git a/src/test/run-pass/deriving-via-extension-struct-tuple.rs b/src/test/run-pass/deriving-via-extension-struct-tuple.rs new file mode 100644 index 0000000000000..3a4f373fed275 --- /dev/null +++ b/src/test/run-pass/deriving-via-extension-struct-tuple.rs @@ -0,0 +1,26 @@ +// 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_eq] +struct Foo(int, int, ~str); + +pub fn main() { + let a1 = Foo(5, 6, ~"abc"); + let a2 = Foo(5, 6, ~"abc"); + let b = Foo(5, 7, ~"def"); + + assert a1 == a1; + assert a1 == a2; + assert !(a1 == b); + + assert a1 != b; + assert !(a1 != a1); + assert !(a1 != a2); +} diff --git a/src/test/run-pass/dvec-test.rs b/src/test/run-pass/dvec-test.rs index a0c6b666554a3..cb8b1c5f25f27 100644 --- a/src/test/run-pass/dvec-test.rs +++ b/src/test/run-pass/dvec-test.rs @@ -31,6 +31,6 @@ pub fn main() { assert *e == exp[i]; } - let v = dvec::unwrap(move d); + let v = dvec::unwrap(d); assert v == exp; } diff --git a/src/test/run-pass/explicit-self-objects-ext-1.rs b/src/test/run-pass/explicit-self-objects-ext-1.rs index 80c18ca0974a4..e226423f84805 100644 --- a/src/test/run-pass/explicit-self-objects-ext-1.rs +++ b/src/test/run-pass/explicit-self-objects-ext-1.rs @@ -13,7 +13,7 @@ pub trait ReaderUtil { fn read_bytes(&self, len: uint); } -impl ReaderUtil for T { +impl ReaderUtil for T { fn read_bytes(&self, len: uint) { let mut count = self.read(&mut [0], len); diff --git a/src/test/run-pass/explicit-self-objects-ext-2.rs b/src/test/run-pass/explicit-self-objects-ext-2.rs index 80c18ca0974a4..e226423f84805 100644 --- a/src/test/run-pass/explicit-self-objects-ext-2.rs +++ b/src/test/run-pass/explicit-self-objects-ext-2.rs @@ -13,7 +13,7 @@ pub trait ReaderUtil { fn read_bytes(&self, len: uint); } -impl ReaderUtil for T { +impl ReaderUtil for T { fn read_bytes(&self, len: uint) { let mut count = self.read(&mut [0], len); diff --git a/src/test/run-pass/explicit-self-objects-ext-3.rs b/src/test/run-pass/explicit-self-objects-ext-3.rs index a32ac955b946b..1a18ee7c6f750 100644 --- a/src/test/run-pass/explicit-self-objects-ext-3.rs +++ b/src/test/run-pass/explicit-self-objects-ext-3.rs @@ -13,7 +13,7 @@ pub trait ReaderUtil { fn read_bytes(len: uint); } -impl ReaderUtil for T { +impl ReaderUtil for T { fn read_bytes(len: uint) { let mut count = self.read(&mut [0], len); diff --git a/src/test/run-pass/explicit-self-objects-ext-4.rs b/src/test/run-pass/explicit-self-objects-ext-4.rs index ca7764f96f4f1..a5d934d998494 100644 --- a/src/test/run-pass/explicit-self-objects-ext-4.rs +++ b/src/test/run-pass/explicit-self-objects-ext-4.rs @@ -13,7 +13,7 @@ pub trait ReaderUtil { fn read_bytes(len: uint); } -impl ReaderUtil for T { +impl ReaderUtil for T { fn read_bytes(len: uint) { let mut count = self.read(&mut [0], len); diff --git a/src/test/run-pass/explicit-self.rs b/src/test/run-pass/explicit-self.rs index f162a1bc48a6a..26e2023e89c50 100644 --- a/src/test/run-pass/explicit-self.rs +++ b/src/test/run-pass/explicit-self.rs @@ -46,7 +46,7 @@ struct thing { x: A } -struct A { mut a: @int } +struct A { a: @int } fn thing(x: A) -> thing { thing { @@ -67,14 +67,14 @@ impl Nus for thing { fn f(&self) {} } pub fn main() { - let x = @thing(A {mut a: @10}); + let x = @thing(A {a: @10}); assert x.foo() == 10; assert x.quux() == 10; - let y = ~thing(A {mut a: @10}); + let y = ~thing(A {a: @10}); assert (copy y).bar() == 10; assert y.quux() == 10; - let z = thing(A {mut a: @11}); + let z = thing(A {a: @11}); assert z.spam() == 11; } diff --git a/src/test/run-pass/expr-alt-generic-box2.rs b/src/test/run-pass/expr-alt-generic-box2.rs index 9176e8672b2e1..e5c82f9edb019 100644 --- a/src/test/run-pass/expr-alt-generic-box2.rs +++ b/src/test/run-pass/expr-alt-generic-box2.rs @@ -11,17 +11,15 @@ // xfail-fast // -*- rust -*- -#[legacy_modes]; - type compare = fn@(T, T) -> bool; -fn test_generic(expected: T, eq: compare) { +fn test_generic(expected: T, eq: compare) { let actual: T = match true { true => { expected }, _ => fail!(~"wat") }; assert (eq(expected, actual)); } fn test_vec() { - fn compare_box(&&v1: @int, &&v2: @int) -> bool { return v1 == v2; } + fn compare_box(v1: @int, v2: @int) -> bool { return v1 == v2; } test_generic::<@int>(@1, compare_box); } diff --git a/src/test/run-pass/expr-alt-generic-unique1.rs b/src/test/run-pass/expr-alt-generic-unique1.rs index 36c591da853b2..ec51fabd4a750 100644 --- a/src/test/run-pass/expr-alt-generic-unique1.rs +++ b/src/test/run-pass/expr-alt-generic-unique1.rs @@ -13,7 +13,7 @@ // -*- rust -*- type compare = fn@(~T, ~T) -> bool; -fn test_generic(expected: ~T, eq: compare) { +fn test_generic(expected: ~T, eq: compare) { let actual: ~T = match true { true => { copy expected }, _ => fail!(~"wat") diff --git a/src/test/run-pass/expr-alt-generic-unique2.rs b/src/test/run-pass/expr-alt-generic-unique2.rs index 2a504c2e2bd4f..7f1c2e17dd524 100644 --- a/src/test/run-pass/expr-alt-generic-unique2.rs +++ b/src/test/run-pass/expr-alt-generic-unique2.rs @@ -11,11 +11,9 @@ // xfail-fast // -*- rust -*- -#[legacy_modes]; - type compare = fn@(T, T) -> bool; -fn test_generic(expected: T, eq: compare) { +fn test_generic(expected: T, eq: compare) { let actual: T = match true { true => copy expected, _ => fail!(~"wat") @@ -24,7 +22,7 @@ fn test_generic(expected: T, eq: compare) { } fn test_vec() { - fn compare_box(&&v1: ~int, &&v2: ~int) -> bool { return v1 == v2; } + fn compare_box(v1: ~int, v2: ~int) -> bool { return v1 == v2; } test_generic::<~int>(~1, compare_box); } diff --git a/src/test/run-pass/expr-alt-generic.rs b/src/test/run-pass/expr-alt-generic.rs index d631e4eac5ebf..dcffcd0ad23f6 100644 --- a/src/test/run-pass/expr-alt-generic.rs +++ b/src/test/run-pass/expr-alt-generic.rs @@ -10,17 +10,16 @@ // xfail-fast // -*- rust -*- -#[legacy_modes]; type compare = fn@(T, T) -> bool; -fn test_generic(expected: T, eq: compare) { +fn test_generic(expected: T, eq: compare) { let actual: T = match true { true => { expected }, _ => fail!(~"wat") }; assert (eq(expected, actual)); } fn test_bool() { - fn compare_bool(&&b1: bool, &&b2: bool) -> bool { return b1 == b2; } + fn compare_bool(b1: bool, b2: bool) -> bool { return b1 == b2; } test_generic::(true, compare_bool); } diff --git a/src/test/run-pass/expr-block-generic-box2.rs b/src/test/run-pass/expr-block-generic-box2.rs index 94627082eb47f..3851578d54748 100644 --- a/src/test/run-pass/expr-block-generic-box2.rs +++ b/src/test/run-pass/expr-block-generic-box2.rs @@ -14,7 +14,7 @@ type compare = fn@(T, T) -> bool; -fn test_generic(expected: T, eq: compare) { +fn test_generic(expected: T, eq: compare) { let actual: T = { expected }; assert (eq(expected, actual)); } diff --git a/src/test/run-pass/expr-block-generic-unique1.rs b/src/test/run-pass/expr-block-generic-unique1.rs index b3637f805356a..c4efe32a31ec1 100644 --- a/src/test/run-pass/expr-block-generic-unique1.rs +++ b/src/test/run-pass/expr-block-generic-unique1.rs @@ -13,7 +13,7 @@ // -*- rust -*- type compare = fn@(~T, ~T) -> bool; -fn test_generic(expected: ~T, eq: compare) { +fn test_generic(expected: ~T, eq: compare) { let actual: ~T = { copy expected }; assert (eq(expected, actual)); } diff --git a/src/test/run-pass/expr-block-generic-unique2.rs b/src/test/run-pass/expr-block-generic-unique2.rs index 39585f7cc6771..b0a056e889180 100644 --- a/src/test/run-pass/expr-block-generic-unique2.rs +++ b/src/test/run-pass/expr-block-generic-unique2.rs @@ -14,7 +14,7 @@ type compare = fn@(T, T) -> bool; -fn test_generic(expected: T, eq: compare) { +fn test_generic(expected: T, eq: compare) { let actual: T = { expected }; assert (eq(expected, actual)); } diff --git a/src/test/run-pass/expr-block-generic.rs b/src/test/run-pass/expr-block-generic.rs index dca3030df14f7..ef726e47df3c9 100644 --- a/src/test/run-pass/expr-block-generic.rs +++ b/src/test/run-pass/expr-block-generic.rs @@ -11,18 +11,17 @@ // xfail-fast -#[legacy_modes]; // Tests for standalone blocks as expressions with dynamic type sizes type compare = fn@(T, T) -> bool; -fn test_generic(expected: T, eq: compare) { +fn test_generic(expected: T, eq: compare) { let actual: T = { expected }; assert (eq(expected, actual)); } fn test_bool() { - fn compare_bool(&&b1: bool, &&b2: bool) -> bool { return b1 == b2; } + fn compare_bool(b1: bool, b2: bool) -> bool { return b1 == b2; } test_generic::(true, compare_bool); } diff --git a/src/test/run-pass/expr-copy.rs b/src/test/run-pass/expr-copy.rs index 56cc5204b0a23..2d370bada286c 100644 --- a/src/test/run-pass/expr-copy.rs +++ b/src/test/run-pass/expr-copy.rs @@ -9,19 +9,19 @@ // except according to those terms. // xfail-fast -#[legacy_modes]; -fn f(arg: A) { +fn f(arg: &mut A) { arg.a = 100; } -struct A { mut a: int } +struct A { a: int } pub fn main() { - let x = A {a: 10}; - f(x); + let mut x = A {a: 10}; + f(&mut x); assert x.a == 100; x.a = 20; - f(copy x); + let mut y = copy x; + f(&mut y); assert x.a == 20; } diff --git a/src/test/run-pass/expr-fn.rs b/src/test/run-pass/expr-fn.rs index 727524f567763..0db78f776c45e 100644 --- a/src/test/run-pass/expr-fn.rs +++ b/src/test/run-pass/expr-fn.rs @@ -19,7 +19,7 @@ fn test_vec() { } fn test_generic() { - fn f(t: T) -> T { t } + fn f(t: T) -> T { t } assert (f(10) == 10); } diff --git a/src/test/run-pass/expr-if-generic-box2.rs b/src/test/run-pass/expr-if-generic-box2.rs index c1bd258930127..5a879071a8814 100644 --- a/src/test/run-pass/expr-if-generic-box2.rs +++ b/src/test/run-pass/expr-if-generic-box2.rs @@ -14,7 +14,7 @@ type compare = fn@(T, T) -> bool; -fn test_generic(expected: T, not_expected: T, eq: compare) { +fn test_generic(expected: T, not_expected: T, eq: compare) { let actual: T = if true { expected } else { not_expected }; assert (eq(expected, actual)); } diff --git a/src/test/run-pass/expr-if-generic.rs b/src/test/run-pass/expr-if-generic.rs index 537f6039af8e6..4e52fec5c1955 100644 --- a/src/test/run-pass/expr-if-generic.rs +++ b/src/test/run-pass/expr-if-generic.rs @@ -10,18 +10,17 @@ // xfail-fast // -*- rust -*- -#[legacy_modes]; // Tests for if as expressions with dynamic type sizes type compare = fn@(T, T) -> bool; -fn test_generic(expected: T, not_expected: T, eq: compare) { +fn test_generic(expected: T, not_expected: T, eq: compare) { let actual: T = if true { expected } else { not_expected }; assert (eq(expected, actual)); } fn test_bool() { - fn compare_bool(&&b1: bool, &&b2: bool) -> bool { return b1 == b2; } + fn compare_bool(b1: bool, b2: bool) -> bool { return b1 == b2; } test_generic::(true, false, compare_bool); } diff --git a/src/test/run-pass/exterior.rs b/src/test/run-pass/exterior.rs index f7faf26bc4c40..2ce67f16c06fb 100644 --- a/src/test/run-pass/exterior.rs +++ b/src/test/run-pass/exterior.rs @@ -12,13 +12,13 @@ // -*- rust -*- -struct Point {x: int, y: int, mut z: int} +struct Point {x: int, y: int, z: int} -fn f(p: @Point) { assert (p.z == 12); p.z = 13; assert (p.z == 13); } +fn f(p: @mut Point) { assert (p.z == 12); p.z = 13; assert (p.z == 13); } pub fn main() { - let a: Point = Point {x: 10, y: 11, mut z: 12}; - let b: @Point = @copy a; + let a: Point = Point {x: 10, y: 11, z: 12}; + let b: @mut Point = @mut copy a; assert (b.z == 12); f(b); assert (a.z == 12); diff --git a/src/test/run-pass/fixed-point-bind-box.rs b/src/test/run-pass/fixed-point-bind-box.rs index 48772aa788973..a1b41ca4b5278 100644 --- a/src/test/run-pass/fixed-point-bind-box.rs +++ b/src/test/run-pass/fixed-point-bind-box.rs @@ -9,7 +9,6 @@ // except according to those terms. // xfail-fast -#[legacy_modes]; fn fix_help(f: extern fn(fn@(A) -> B, A) -> B, x: A) -> B { return f( |a| fix_help(f, a), x); @@ -19,7 +18,7 @@ fn fix(f: extern fn(fn@(A) -> B, A) -> B) -> fn@(A) -> B { return |a| fix_help(f, a); } -fn fact_(f: fn@(&&v: int) -> int, &&n: int) -> int { +fn fact_(f: fn@(v: int) -> int, n: int) -> int { // fun fact 0 = 1 return if n == 0 { 1 } else { n * f(n - 1) }; } diff --git a/src/test/run-pass/fixed-point-bind-unique.rs b/src/test/run-pass/fixed-point-bind-unique.rs index e41fa1af90f7f..dfd52940e73c4 100644 --- a/src/test/run-pass/fixed-point-bind-unique.rs +++ b/src/test/run-pass/fixed-point-bind-unique.rs @@ -9,17 +9,16 @@ // except according to those terms. // xfail-fast -#[legacy_modes]; -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); } -fn fact_(f: fn@(&&v: int) -> int, &&n: int) -> int { +fn fact_(f: fn@(v: int) -> int, n: int) -> int { // fun fact 0 = 1 return if n == 0 { 1 } else { n * f(n - 1) }; } diff --git a/src/test/run-pass/fn-bare-spawn.rs b/src/test/run-pass/fn-bare-spawn.rs index 163063ab745d5..9b2a8d0c68177 100644 --- a/src/test/run-pass/fn-bare-spawn.rs +++ b/src/test/run-pass/fn-bare-spawn.rs @@ -10,8 +10,8 @@ // This is what the signature to spawn should look like with bare functions -fn spawn(val: T, f: extern fn(T)) { - f(move val); +fn spawn(val: T, f: extern fn(T)) { + f(val); } fn f(+i: int) { diff --git a/src/test/run-pass/generic-alias-box.rs b/src/test/run-pass/generic-alias-box.rs index 3830d89616cb3..95902acc8487a 100644 --- a/src/test/run-pass/generic-alias-box.rs +++ b/src/test/run-pass/generic-alias-box.rs @@ -10,7 +10,7 @@ -fn id(t: T) -> T { return t; } +fn id(t: T) -> T { return t; } pub fn main() { let expected = @100; diff --git a/src/test/run-pass/generic-alias-unique.rs b/src/test/run-pass/generic-alias-unique.rs index 0aa1b4dd6510b..3cb6409a254e1 100644 --- a/src/test/run-pass/generic-alias-unique.rs +++ b/src/test/run-pass/generic-alias-unique.rs @@ -10,7 +10,7 @@ -fn id(t: T) -> T { return t; } +fn id(t: T) -> T { return t; } pub fn main() { let expected = ~100; diff --git a/src/test/run-pass/generic-box.rs b/src/test/run-pass/generic-box.rs index 05f4908b3b282..43c6acd3f3da0 100644 --- a/src/test/run-pass/generic-box.rs +++ b/src/test/run-pass/generic-box.rs @@ -10,7 +10,7 @@ -fn box(x: Box) -> @Box { return @x; } +fn box(x: Box) -> @Box { return @x; } struct Box {x: T, y: T, z: T} diff --git a/src/test/run-pass/generic-derived-type.rs b/src/test/run-pass/generic-derived-type.rs index 3667e54974590..264703439e810 100644 --- a/src/test/run-pass/generic-derived-type.rs +++ b/src/test/run-pass/generic-derived-type.rs @@ -10,11 +10,11 @@ -fn g(x: X) -> X { return x; } +fn g(x: X) -> X { return x; } struct Pair {a: T, b: T} -fn f(t: T) -> Pair { +fn f(t: T) -> Pair { let x: Pair = Pair {a: t, b: t}; return g::>(x); diff --git a/src/test/run-pass/generic-drop-glue.rs b/src/test/run-pass/generic-drop-glue.rs index b8de3e0b5e3cd..19e11197fd913 100644 --- a/src/test/run-pass/generic-drop-glue.rs +++ b/src/test/run-pass/generic-drop-glue.rs @@ -11,6 +11,6 @@ struct Pair { x: @int, y: @int } -fn f(t: T) { let t1: T = t; } +fn f(t: T) { let t1: T = t; } pub fn main() { let x = Pair {x: @10, y: @12}; f(x); } diff --git a/src/test/run-pass/generic-exterior-box.rs b/src/test/run-pass/generic-exterior-box.rs index 4c8de2fbffca4..7039fad1a9a2d 100644 --- a/src/test/run-pass/generic-exterior-box.rs +++ b/src/test/run-pass/generic-exterior-box.rs @@ -12,7 +12,7 @@ struct Recbox {x: @T} -fn reclift(t: T) -> Recbox { return Recbox {x: @t}; } +fn reclift(t: T) -> Recbox { return Recbox {x: @t}; } pub fn main() { let foo: int = 17; diff --git a/src/test/run-pass/generic-exterior-unique.rs b/src/test/run-pass/generic-exterior-unique.rs index 741d9f0e17943..3d3cc028f3583 100644 --- a/src/test/run-pass/generic-exterior-unique.rs +++ b/src/test/run-pass/generic-exterior-unique.rs @@ -10,7 +10,7 @@ struct Recbox {x: ~T} -fn reclift(t: T) -> Recbox { return Recbox {x: ~t}; } +fn reclift(t: T) -> Recbox { return Recbox {x: ~t}; } pub fn main() { let foo: int = 17; diff --git a/src/test/run-pass/generic-fn-infer.rs b/src/test/run-pass/generic-fn-infer.rs index 88130af2cccb2..fcd356bcd2d83 100644 --- a/src/test/run-pass/generic-fn-infer.rs +++ b/src/test/run-pass/generic-fn-infer.rs @@ -14,6 +14,6 @@ // -*- rust -*- // Issue #45: infer type parameters in function applications -fn id(x: T) -> T { return x; } +fn id(x: T) -> T { return x; } pub fn main() { let x: int = 42; let y: int = id(x); assert (x == y); } diff --git a/src/test/run-pass/generic-fn-unique.rs b/src/test/run-pass/generic-fn-unique.rs index b58b68ee5aea7..d41cd86bcc147 100644 --- a/src/test/run-pass/generic-fn-unique.rs +++ b/src/test/run-pass/generic-fn-unique.rs @@ -9,6 +9,6 @@ // except according to those terms. -fn f(x: ~T) -> ~T { return x; } +fn f(x: ~T) -> ~T { return x; } pub fn main() { let x = f(~3); log(debug, *x); } diff --git a/src/test/run-pass/generic-fn.rs b/src/test/run-pass/generic-fn.rs index 551fe221edaff..2fad81f4db20a 100644 --- a/src/test/run-pass/generic-fn.rs +++ b/src/test/run-pass/generic-fn.rs @@ -12,7 +12,7 @@ // -*- rust -*- -fn id(x: T) -> T { return x; } +fn id(x: T) -> T { return x; } struct Triple {x: int, y: int, z: int} diff --git a/src/test/run-pass/generic-temporary.rs b/src/test/run-pass/generic-temporary.rs index d2100e8d065f0..d9c6dcef1f5cb 100644 --- a/src/test/run-pass/generic-temporary.rs +++ b/src/test/run-pass/generic-temporary.rs @@ -9,11 +9,10 @@ // except according to those terms. // xfail-fast -#[legacy_modes]; fn mk() -> int { return 1; } -fn chk(&&a: int) { log(debug, a); assert (a == 1); } +fn chk(a: int) { log(debug, a); assert (a == 1); } fn apply(produce: extern fn() -> T, consume: extern fn(T)) { @@ -22,6 +21,6 @@ fn apply(produce: extern fn() -> T, pub fn main() { let produce: extern fn() -> int = mk; - let consume: extern fn(&&v: int) = chk; + let consume: extern fn(v: int) = chk; apply::(produce, consume); } diff --git a/src/test/run-pass/generic-tup.rs b/src/test/run-pass/generic-tup.rs index 8db1c4673bd4b..3f6f8e7af6881 100644 --- a/src/test/run-pass/generic-tup.rs +++ b/src/test/run-pass/generic-tup.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -fn get_third(t: (T, T, T)) -> T { let (_, _, x) = t; return x; } +fn get_third(t: (T, T, T)) -> T { let (_, _, x) = t; return x; } pub fn main() { log(debug, get_third((1, 2, 3))); diff --git a/src/test/run-pass/generic-unique.rs b/src/test/run-pass/generic-unique.rs index 0ae417e711e36..dc88f7acfbdf3 100644 --- a/src/test/run-pass/generic-unique.rs +++ b/src/test/run-pass/generic-unique.rs @@ -10,7 +10,7 @@ struct Triple { x: T, y: T, z: T } -fn box(x: Triple) -> ~Triple { return ~x; } +fn box(x: Triple) -> ~Triple { return ~x; } pub fn main() { let x: ~Triple = box::(Triple{x: 1, y: 2, z: 3}); diff --git a/src/test/run-pass/hashmap-memory.rs b/src/test/run-pass/hashmap-memory.rs index d7a285d58e662..b90633bab01ef 100644 --- a/src/test/run-pass/hashmap-memory.rs +++ b/src/test/run-pass/hashmap-memory.rs @@ -20,14 +20,14 @@ extern mod std; use std::oldmap; use std::oldmap::HashMap; -use core::pipes::*; +use core::comm::*; pub fn map(filename: ~str, emit: map_reduce::putter) { emit(filename, ~"1"); } mod map_reduce { use std::oldmap; use std::oldmap::HashMap; - use core::pipes::*; + use core::comm::*; pub type putter = fn@(~str, ~str); @@ -39,7 +39,7 @@ mod map_reduce { for inputs.each |i| { let ctrl = ctrl.clone(); let i = copy *i; - task::spawn(|move i| map_task(ctrl.clone(), copy i) ); + task::spawn(|| map_task(ctrl.clone(), copy i) ); } } diff --git a/src/test/run-pass/impl-privacy-xc-1.rs b/src/test/run-pass/impl-privacy-xc-1.rs index 33f6cfa1b77ee..df001c7ab212e 100644 --- a/src/test/run-pass/impl-privacy-xc-1.rs +++ b/src/test/run-pass/impl-privacy-xc-1.rs @@ -3,7 +3,7 @@ extern mod impl_privacy_xc_1; -fn main() { +pub fn main() { let fish = impl_privacy_xc_1::Fish { x: 1 }; fish.swim(); } diff --git a/src/test/run-pass/impl-privacy-xc-2.rs b/src/test/run-pass/impl-privacy-xc-2.rs index 8355d4c96ffa1..69bd31ab766da 100644 --- a/src/test/run-pass/impl-privacy-xc-2.rs +++ b/src/test/run-pass/impl-privacy-xc-2.rs @@ -3,7 +3,7 @@ extern mod impl_privacy_xc_2; -fn main() { +pub fn main() { let fish1 = impl_privacy_xc_2::Fish { x: 1 }; let fish2 = impl_privacy_xc_2::Fish { x: 2 }; io::println(if fish1.eq(&fish2) { "yes" } else { "no " }); diff --git a/src/test/run-pass/init-res-into-things.rs b/src/test/run-pass/init-res-into-things.rs index 0605fac3677bf..0185b19b48177 100644 --- a/src/test/run-pass/init-res-into-things.rs +++ b/src/test/run-pass/init-res-into-things.rs @@ -32,7 +32,7 @@ fn r(i: @mut int) -> r { fn test_box() { let i = @mut 0; { - let a = move @r(i); + let a = @r(i); } assert *i == 1; } @@ -40,7 +40,7 @@ fn test_box() { fn test_rec() { let i = @mut 0; { - let a = move Box {x: r(i)}; + let a = Box {x: r(i)}; } assert *i == 1; } @@ -52,7 +52,7 @@ fn test_tag() { let i = @mut 0; { - let a = move t0(r(i)); + let a = t0(r(i)); } assert *i == 1; } @@ -60,7 +60,7 @@ fn test_tag() { fn test_tup() { let i = @mut 0; { - let a = move (r(i), 0); + let a = (r(i), 0); } assert *i == 1; } @@ -68,7 +68,7 @@ fn test_tup() { fn test_unique() { let i = @mut 0; { - let a = move ~r(i); + let a = ~r(i); } assert *i == 1; } @@ -76,7 +76,7 @@ fn test_unique() { fn test_box_rec() { let i = @mut 0; { - let a = move @Box { + let a = @Box { x: r(i) }; } diff --git a/src/test/run-pass/intrinsic-move-val.rs b/src/test/run-pass/intrinsic-move-val.rs index b17eb37438a50..9e8e9d8bc15be 100644 --- a/src/test/run-pass/intrinsic-move-val.rs +++ b/src/test/run-pass/intrinsic-move-val.rs @@ -18,7 +18,7 @@ pub fn main() { unsafe { let mut x = @1; let mut y = @2; - rusti::move_val(&mut y, move x); + rusti::move_val(&mut y, x); assert *y == 1; } } diff --git a/src/test/run-pass/issue-1257.rs b/src/test/run-pass/issue-1257.rs index 77e540454aa1c..9acdd9297d24e 100644 --- a/src/test/run-pass/issue-1257.rs +++ b/src/test/run-pass/issue-1257.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -fn main () { +pub fn main () { let mut line = ~""; let mut i = 0; while line != ~"exit" { diff --git a/src/test/run-pass/issue-1895.rs b/src/test/run-pass/issue-1895.rs index 3d20eb813d8b5..42c6ae38b6afb 100644 --- a/src/test/run-pass/issue-1895.rs +++ b/src/test/run-pass/issue-1895.rs @@ -10,7 +10,7 @@ pub fn main() { let x = 1; - let y = fn@(move x) -> int { + let y = fn@() -> int { x }(); } diff --git a/src/test/run-pass/issue-2185.rs b/src/test/run-pass/issue-2185.rs index ff35b81aad1f6..a8533b574e86c 100644 --- a/src/test/run-pass/issue-2185.rs +++ b/src/test/run-pass/issue-2185.rs @@ -14,8 +14,6 @@ // However, the condition it was testing seemed complex enough to // warrant still having a test, so I inlined the old definitions. -#[legacy_modes]; - trait iterable { fn iter(blk: fn(A)); } @@ -34,12 +32,12 @@ fn filter>(self: IA, prd: fn@(A) -> bool, blk: fn(A)) { } } -fn foldl>(self: IA, +b0: B, blk: fn(B, A) -> B) -> B { - let mut b = move b0; +fn foldl>(self: IA, b0: B, blk: fn(B, A) -> B) -> B { + let mut b = b0; do self.iter |a| { - b = move blk(b, a); + b = blk(b, a); } - move b + b } fn range(lo: uint, hi: uint, it: fn(uint)) { @@ -52,7 +50,7 @@ fn range(lo: uint, hi: uint, it: fn(uint)) { pub fn main() { let range: fn@(fn&(uint)) = |a| range(0u, 1000u, a); - let filt: fn@(fn&(&&v: uint)) = |a| filter( + let filt: fn@(fn&(v: uint)) = |a| filter( range, |&&n: uint| n % 3u != 0u && n % 5u != 0u, a); diff --git a/src/test/run-pass/issue-2284.rs b/src/test/run-pass/issue-2284.rs index 1c4f21c628867..ebf7eec470c3e 100644 --- a/src/test/run-pass/issue-2284.rs +++ b/src/test/run-pass/issue-2284.rs @@ -12,7 +12,7 @@ trait Send { fn f(); } -fn f(t: T) { +fn f(t: T) { t.f(); } diff --git a/src/test/run-pass/issue-2288.rs b/src/test/run-pass/issue-2288.rs index 99c9828bfeaa0..375259baaf527 100644 --- a/src/test/run-pass/issue-2288.rs +++ b/src/test/run-pass/issue-2288.rs @@ -8,25 +8,25 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -trait clam { +trait clam { fn chowder(y: A); } struct foo { x: A, } -impl clam for foo { +impl clam for foo { fn chowder(y: A) { } } -fn foo(b: A) -> foo { +fn foo(b: A) -> foo { foo { x: b } } -fn f(x: clam, a: A) { +fn f(x: clam, a: A) { x.chowder(a); } diff --git a/src/test/run-pass/issue-2311-2.rs b/src/test/run-pass/issue-2311-2.rs index 8e4036b36be6b..b4141b47b4d67 100644 --- a/src/test/run-pass/issue-2311-2.rs +++ b/src/test/run-pass/issue-2311-2.rs @@ -8,18 +8,18 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -trait clam { } +trait clam { } struct foo { x: A, } -impl foo { +impl foo { fn bar>(c: C) -> B { fail!(); } } -fn foo(b: A) -> foo { +fn foo(b: A) -> foo { foo { x: b } diff --git a/src/test/run-pass/issue-2383.rs b/src/test/run-pass/issue-2383.rs index e45d9d6055520..a7afa1d6f3494 100644 --- a/src/test/run-pass/issue-2383.rs +++ b/src/test/run-pass/issue-2383.rs @@ -11,10 +11,9 @@ // except according to those terms. extern mod std; -use std::deque; use std::deque::Deque; pub fn main() { - let Q = deque::create(); - Q.add_back(10); + let mut q = Deque::new(); + q.add_back(10); } diff --git a/src/test/run-pass/issue-2445-b.rs b/src/test/run-pass/issue-2445-b.rs index 2fce24c0670cf..9869b8d330bf1 100644 --- a/src/test/run-pass/issue-2445-b.rs +++ b/src/test/run-pass/issue-2445-b.rs @@ -12,18 +12,18 @@ struct c1 { x: T, } -impl c1 { +impl c1 { fn f1(x: int) { } } -fn c1(x: T) -> c1 { +fn c1(x: T) -> c1 { c1 { x: x } } -impl c1 { +impl c1 { fn f2(x: int) { } } diff --git a/src/test/run-pass/issue-2445.rs b/src/test/run-pass/issue-2445.rs index ea1cec61867e2..4a085a1eb8a97 100644 --- a/src/test/run-pass/issue-2445.rs +++ b/src/test/run-pass/issue-2445.rs @@ -12,17 +12,17 @@ struct c1 { x: T, } -impl c1 { +impl c1 { fn f1(x: T) {} } -fn c1(x: T) -> c1 { +fn c1(x: T) -> c1 { c1 { x: x } } -impl c1 { +impl c1 { fn f2(x: T) {} } diff --git a/src/test/run-pass/issue-2633.rs b/src/test/run-pass/issue-2633.rs index 8ff51b0c28e69..04d75fd08e184 100644 --- a/src/test/run-pass/issue-2633.rs +++ b/src/test/run-pass/issue-2633.rs @@ -9,7 +9,7 @@ // except according to those terms. struct cat { - mut meow: fn@(), + meow: fn@(), } fn cat() -> cat { diff --git a/src/test/run-pass/issue-2718.rs b/src/test/run-pass/issue-2718.rs index 0cae04b60bc74..249d1c21376bd 100644 --- a/src/test/run-pass/issue-2718.rs +++ b/src/test/run-pass/issue-2718.rs @@ -15,11 +15,12 @@ pub mod pipes { use core::cast::{forget, transmute}; pub struct Stuff { - mut state: state, - mut blocked_task: Option, - mut payload: Option + state: state, + blocked_task: Option, + payload: Option } + #[deriving_eq] pub enum state { empty, full, @@ -27,25 +28,18 @@ pub mod pipes { terminated } - pub impl state : cmp::Eq { - pure fn eq(&self, other: &state) -> bool { - ((*self) as uint) == ((*other) as uint) - } - pure fn ne(&self, other: &state) -> bool { !(*self).eq(other) } - } - pub type packet = { - mut state: state, - mut blocked_task: Option, - mut payload: Option + state: state, + blocked_task: Option, + payload: Option }; - pub fn packet() -> *packet { + pub fn packet() -> *packet { unsafe { let p: *packet = cast::transmute(~Stuff{ - mut state: empty, - mut blocked_task: None::, - mut payload: None:: + state: empty, + blocked_task: None::, + payload: None:: }); p } @@ -61,39 +55,39 @@ pub mod pipes { // We should consider moving this to ::core::unsafe, although I // suspect graydon would want us to use void pointers instead. pub unsafe fn uniquify(+x: *T) -> ~T { - unsafe { cast::transmute(move x) } + unsafe { cast::transmute(x) } } pub fn swap_state_acq(+dst: &mut state, src: state) -> state { unsafe { - transmute(rusti::atomic_xchg_acq(transmute(move dst), src as int)) + transmute(rusti::atomic_xchg_acq(transmute(dst), src as int)) } } pub fn swap_state_rel(+dst: &mut state, src: state) -> state { unsafe { - transmute(rusti::atomic_xchg_rel(transmute(move dst), src as int)) + transmute(rusti::atomic_xchg_rel(transmute(dst), src as int)) } } - pub fn send(-p: send_packet, -payload: T) { - let p = p.unwrap(); - let p = unsafe { uniquify(p) }; + pub fn send(mut p: send_packet, -payload: T) { + let mut p = p.unwrap(); + let mut p = unsafe { uniquify(p) }; assert (*p).payload.is_none(); - (*p).payload = move Some(move payload); + (*p).payload = Some(payload); let old_state = swap_state_rel(&mut (*p).state, full); match old_state { empty => { // Yay, fastpath. // The receiver will eventually clean this up. - unsafe { forget(move p); } + unsafe { forget(p); } } full => { fail!(~"duplicate send") } blocked => { // The receiver will eventually clean this up. - unsafe { forget(move p); } + unsafe { forget(p); } } terminated => { // The receiver will never receive this. Rely on drop_glue @@ -102,9 +96,9 @@ pub mod pipes { } } - pub fn recv(-p: recv_packet) -> Option { - let p = p.unwrap(); - let p = unsafe { uniquify(p) }; + pub fn recv(mut p: recv_packet) -> Option { + let mut p = p.unwrap(); + let mut p = unsafe { uniquify(p) }; loop { let old_state = swap_state_acq(&mut (*p).state, blocked); @@ -113,7 +107,7 @@ pub mod pipes { full => { let mut payload = None; payload <-> (*p).payload; - return Some(option::unwrap(move payload)) + return Some(option::unwrap(payload)) } terminated => { assert old_state == terminated; @@ -123,12 +117,12 @@ pub mod pipes { } } - pub fn sender_terminate(p: *packet) { - let p = unsafe { uniquify(p) }; + pub fn sender_terminate(mut p: *packet) { + let mut p = unsafe { uniquify(p) }; match swap_state_rel(&mut (*p).state, terminated) { empty | blocked => { // The receiver will eventually clean up. - unsafe { forget(move p) } + unsafe { forget(p) } } full => { // This is impossible @@ -140,12 +134,12 @@ pub mod pipes { } } - pub fn receiver_terminate(p: *packet) { - let p = unsafe { uniquify(p) }; + pub fn receiver_terminate(mut p: *packet) { + let mut p = unsafe { uniquify(p) }; match swap_state_rel(&mut (*p).state, terminated) { empty => { // the sender will clean up - unsafe { forget(move p) } + unsafe { forget(p) } } blocked => { // this shouldn't happen. @@ -158,62 +152,70 @@ pub mod pipes { } pub struct send_packet { - mut p: Option<*packet>, + p: Option<*packet>, } - pub impl send_packet : Drop { + pub impl Drop for send_packet { fn finalize(&self) { - if self.p != None { - let mut p = None; - p <-> self.p; - sender_terminate(option::unwrap(move p)) + unsafe { + if self.p != None { + let mut p = None; + let self_p: &mut Option<*packet> = + cast::transmute(&self.p); + p <-> *self_p; + sender_terminate(option::unwrap(p)) + } } } } - pub impl send_packet { - fn unwrap() -> *packet { + pub impl send_packet { + fn unwrap(&mut self) -> *packet { let mut p = None; p <-> self.p; - option::unwrap(move p) + option::unwrap(p) } } - pub fn send_packet(p: *packet) -> send_packet { + pub fn send_packet(p: *packet) -> send_packet { send_packet { p: Some(p) } } pub struct recv_packet { - mut p: Option<*packet>, + p: Option<*packet>, } - pub impl recv_packet : Drop { + pub impl Drop for recv_packet { fn finalize(&self) { - if self.p != None { - let mut p = None; - p <-> self.p; - receiver_terminate(option::unwrap(move p)) + unsafe { + if self.p != None { + let mut p = None; + let self_p: &mut Option<*packet> = + cast::transmute(&self.p); + p <-> *self_p; + receiver_terminate(option::unwrap(p)) + } } } } - pub impl recv_packet { - fn unwrap() -> *packet { + pub impl recv_packet { + fn unwrap(&mut self) -> *packet { let mut p = None; p <-> self.p; - option::unwrap(move p) + option::unwrap(p) } } - pub fn recv_packet(p: *packet) -> recv_packet { + pub fn recv_packet(p: *packet) -> recv_packet { recv_packet { p: Some(p) } } - pub fn entangle() -> (send_packet, recv_packet) { + pub fn entangle() -> (send_packet, recv_packet) { let p = packet(); (send_packet(p), recv_packet(p)) } @@ -231,9 +233,9 @@ pub mod pingpong { let addr : *::pipes::send_packet = match &p { &ping(ref x) => { cast::transmute(ptr::addr_of(x)) } }; - let liberated_value = move *addr; - cast::forget(move p); - move liberated_value + let liberated_value = *addr; + cast::forget(p); + liberated_value } } @@ -242,9 +244,9 @@ pub mod pingpong { let addr : *::pipes::send_packet = match &p { &pong(ref x) => { cast::transmute(ptr::addr_of(x)) } }; - let liberated_value = move *addr; - cast::forget(move p); - move liberated_value + let liberated_value = *addr; + cast::forget(p); + liberated_value } } @@ -262,16 +264,16 @@ pub mod pingpong { pub fn do_ping(-c: ping) -> pong { let (sp, rp) = ::pipes::entangle(); - ::pipes::send(move c, pingpong::ping(move sp)); - move rp + ::pipes::send(c, pingpong::ping(sp)); + rp } pub fn do_pong(-c: pong) -> (ping, ()) { - let packet = ::pipes::recv(move c); + let packet = ::pipes::recv(c); if packet.is_none() { fail!(~"sender closed the connection") } - (pingpong::liberate_pong(option::unwrap(move packet)), ()) + (pingpong::liberate_pong(option::unwrap(packet)), ()) } } @@ -282,32 +284,32 @@ pub mod pingpong { pub type pong = ::pipes::send_packet; pub fn do_ping(-c: ping) -> (pong, ()) { - let packet = ::pipes::recv(move c); + let packet = ::pipes::recv(c); if packet.is_none() { fail!(~"sender closed the connection") } - (pingpong::liberate_ping(option::unwrap(move packet)), ()) + (pingpong::liberate_ping(option::unwrap(packet)), ()) } pub fn do_pong(-c: pong) -> ping { let (sp, rp) = ::pipes::entangle(); - ::pipes::send(move c, pingpong::pong(move sp)); - move rp + ::pipes::send(c, pingpong::pong(sp)); + rp } } } fn client(-chan: pingpong::client::ping) { - let chan = pingpong::client::do_ping(move chan); + let chan = pingpong::client::do_ping(chan); log(error, ~"Sent ping"); - let (_chan, _data) = pingpong::client::do_pong(move chan); + let (_chan, _data) = pingpong::client::do_pong(chan); log(error, ~"Received pong"); } fn server(-chan: pingpong::server::ping) { - let (chan, _data) = pingpong::server::do_ping(move chan); + let (chan, _data) = pingpong::server::do_ping(chan); log(error, ~"Received ping"); - let _chan = pingpong::server::do_pong(move chan); + let _chan = pingpong::server::do_pong(chan); log(error, ~"Sent pong"); } @@ -319,12 +321,12 @@ pub fn main() { let client_ = ~mut Some(client_); let server_ = ~mut Some(server_); - task::spawn {|move client_| + task::spawn {|client_| let mut client__ = none; *client_ <-> client__; client(option::unwrap(client__)); }; - task::spawn {|move server_| + task::spawn {|server_| let mut server_ËŠ = none; *server_ <-> server_ËŠ; server(option::unwrap(server_ËŠ)); diff --git a/src/test/run-pass/issue-2734.rs b/src/test/run-pass/issue-2734.rs index ed7b032e7139e..45c6b22544d9c 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.rs b/src/test/run-pass/issue-2735.rs index 8a6f2a0b461bf..7c87c6a31cde1 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-2834.rs b/src/test/run-pass/issue-2834.rs index b78cefe1c95e4..579c4f9f1d124 100644 --- a/src/test/run-pass/issue-2834.rs +++ b/src/test/run-pass/issue-2834.rs @@ -12,14 +12,14 @@ // proto! streamp ( - open:send { + open:send { data(T) -> open } ) fn rendezvous() { let (c, s) = streamp::init(); - let streams: ~[streamp::client::open] = ~[move c]; + let streams: ~[streamp::client::open] = ~[c]; error!("%?", streams[0]); } diff --git a/src/test/run-pass/issue-2904.rs b/src/test/run-pass/issue-2904.rs index eadfa82619acd..9106d39c592f3 100644 --- a/src/test/run-pass/issue-2904.rs +++ b/src/test/run-pass/issue-2904.rs @@ -59,8 +59,8 @@ fn square_from_char(c: char) -> square { } } -fn read_board_grid(+in: rdr) -> ~[~[square]] { - let in = (move in) as io::Reader; +fn read_board_grid(+in: rdr) -> ~[~[square]] { + let in = (in) as io::Reader; let mut grid = ~[]; for in.each_line |line| { let mut row = ~[]; diff --git a/src/test/run-pass/issue-2930.rs b/src/test/run-pass/issue-2930.rs index 4b6985f057ead..6d22a2ea5edcf 100644 --- a/src/test/run-pass/issue-2930.rs +++ b/src/test/run-pass/issue-2930.rs @@ -17,5 +17,5 @@ proto! stream ( pub fn main() { let (bc, _bp) = stream::init(); - stream::client::send(move bc, ~"abc"); + stream::client::send(bc, ~"abc"); } diff --git a/src/test/run-pass/issue-3168.rs b/src/test/run-pass/issue-3168.rs index 02b147e65fce1..e0ec62ff255ae 100644 --- a/src/test/run-pass/issue-3168.rs +++ b/src/test/run-pass/issue-3168.rs @@ -11,16 +11,16 @@ // xfail-fast pub fn main() { - let (p,c) = pipes::stream(); - do task::try |move c| { - let (p2,c2) = pipes::stream(); - do task::spawn |move p2| { + let (p,c) = comm::stream(); + do task::try || { + let (p2,c2) = comm::stream(); + do task::spawn || { p2.recv(); error!("sibling fails"); fail!(); } - let (p3,c3) = pipes::stream(); - c.send(move c3); + let (p3,c3) = comm::stream(); + c.send(c3); c2.send(()); error!("child blocks"); p3.recv(); diff --git a/src/test/run-pass/issue-3176.rs b/src/test/run-pass/issue-3176.rs index b5f2a1d22a6e5..e441fa22b3150 100644 --- a/src/test/run-pass/issue-3176.rs +++ b/src/test/run-pass/issue-3176.rs @@ -10,23 +10,23 @@ // xfail-fast -use pipes::{Select2, Selectable}; +use comm::{Select2, Selectable}; pub fn main() { - let (p,c) = pipes::stream(); - do task::try |move c| { - let (p2,c2) = pipes::stream(); - do task::spawn |move p2| { + let (p,c) = comm::stream(); + do task::try || { + let (p2,c2) = comm::stream(); + do task::spawn || { p2.recv(); error!("sibling fails"); fail!(); } - let (p3,c3) = pipes::stream(); - c.send(move c3); + let (p3,c3) = comm::stream(); + c.send(c3); c2.send(()); error!("child blocks"); - let (p, c) = pipes::stream(); - (move p, move p3).select(); + let (p, c) = comm::stream(); + (p, p3).select(); c.send(()); }; error!("parent tries"); diff --git a/src/test/run-pass/issue-3220.rs b/src/test/run-pass/issue-3220.rs index 71c83e02617ff..ef65531e5546f 100644 --- a/src/test/run-pass/issue-3220.rs +++ b/src/test/run-pass/issue-3220.rs @@ -23,5 +23,5 @@ impl thing { fn f(self) {} } pub fn main() { let z = thing(); - (move z).f(); + (z).f(); } diff --git a/src/test/run-pass/issue-3305.rs b/src/test/run-pass/issue-3305.rs index 53dd6f942e860..b44d1cbb78d48 100644 --- a/src/test/run-pass/issue-3305.rs +++ b/src/test/run-pass/issue-3305.rs @@ -16,7 +16,7 @@ impl double for uint { fn double() -> uint { self * 2u } } -fn is_equal(x: @D, exp: uint) { +fn is_equal(x: @D, exp: uint) { assert x.double() == exp; } diff --git a/src/test/run-pass/issue-333.rs b/src/test/run-pass/issue-333.rs index 8b863bd90b64d..1f9dd6e3b6f3c 100644 --- a/src/test/run-pass/issue-333.rs +++ b/src/test/run-pass/issue-333.rs @@ -8,8 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -fn quux(x: T) -> T { let f = id::; return f(x); } +fn quux(x: T) -> T { let f = id::; return f(x); } -fn id(x: T) -> T { return x; } +fn id(x: T) -> T { return x; } pub fn main() { assert (quux(10) == 10); } diff --git a/src/test/run-pass/issue-3389.rs b/src/test/run-pass/issue-3389.rs index b25e6ae2d2d91..5555867073491 100644 --- a/src/test/run-pass/issue-3389.rs +++ b/src/test/run-pass/issue-3389.rs @@ -9,8 +9,8 @@ // except according to those terms. struct trie_node { - mut content: ~[~str], - mut children: ~[trie_node], + content: ~[~str], + children: ~[trie_node], } fn print_str_vector(vector: ~[~str]) { @@ -20,7 +20,7 @@ fn print_str_vector(vector: ~[~str]) { } pub fn main() { - let node: trie_node = trie_node { + let mut node: trie_node = trie_node { content: ~[], children: ~[] }; diff --git a/src/test/run-pass/issue-3447.rs b/src/test/run-pass/issue-3447.rs index 18b47e2925dd2..0d1b0b9d0029e 100644 --- a/src/test/run-pass/issue-3447.rs +++ b/src/test/run-pass/issue-3447.rs @@ -10,17 +10,17 @@ struct list { element: &self/T, - mut next: Option<@list> + next: Option<@mut list> } impl list{ - fn addEnd(&self, element: &self/T) { + fn addEnd(&mut self, element: &self/T) { let newList = list { element: element, next: option::None }; - self.next = Some(@(move newList)); + self.next = Some(@mut newList); } } diff --git a/src/test/run-pass/issue-3480.rs b/src/test/run-pass/issue-3480.rs index 252ebb86685ec..e813cde7c2760 100644 --- a/src/test/run-pass/issue-3480.rs +++ b/src/test/run-pass/issue-3480.rs @@ -9,14 +9,14 @@ // except according to those terms. // xfail-test -type IMap = ~[(K, V)]; +type IMap = ~[(K, V)]; -trait ImmutableMap +trait ImmutableMap { pure fn contains_key(key: K) -> bool; } -impl IMap : ImmutableMap +impl IMap : ImmutableMap { pure fn contains_key(key: K) -> bool { diff --git a/src/test/run-pass/issue-3563-3.rs b/src/test/run-pass/issue-3563-3.rs index 88f31189a0c8f..c4f4aa46a8a42 100644 --- a/src/test/run-pass/issue-3563-3.rs +++ b/src/test/run-pass/issue-3563-3.rs @@ -23,8 +23,7 @@ extern mod std; use io::WriterUtil; // Represents a position on a canvas. -struct Point -{ +struct Point { x: int, y: int, } @@ -108,8 +107,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 AsciiArt : ToStr -{ +impl ToStr for AsciiArt { pure fn to_str(&self) -> ~str { // Convert each line into a string. @@ -139,8 +137,7 @@ trait Canvas // Here we provide an implementation of the Canvas methods for AsciiArt. // Other implementations could also be provided (e.g. for PDF or Apple's Quartz) // and code can use them polymorphically via the Canvas trait. -impl AsciiArt : Canvas -{ +impl Canvas for AsciiArt { fn add_point(&mut self, shape: Point) { self.add_pt(shape.x, shape.y); diff --git a/src/test/run-pass/issue-3609.rs b/src/test/run-pass/issue-3609.rs index 0eacb34b1ef88..83703dacc36e3 100644 --- a/src/test/run-pass/issue-3609.rs +++ b/src/test/run-pass/issue-3609.rs @@ -1,6 +1,6 @@ extern mod std; -use pipes::Chan; +use comm::Chan; type RingBuffer = ~[float]; type SamplesFn = fn~ (samples: &RingBuffer); @@ -12,7 +12,6 @@ enum Msg fn foo(name: ~str, samples_chan: Chan) { do task::spawn - |copy name| { let callback: SamplesFn = |buffer| diff --git a/src/test/run-pass/issue-3878.rs b/src/test/run-pass/issue-3878.rs index dd41d696b3a93..a5791e3834351 100644 --- a/src/test/run-pass/issue-3878.rs +++ b/src/test/run-pass/issue-3878.rs @@ -11,5 +11,5 @@ pub fn main() { let y = ~1; - move y; + y; } diff --git a/src/test/run-pass/issue-3888-2.rs b/src/test/run-pass/issue-3888-2.rs index 19f05c61ba4ca..06e652cc7cd55 100644 --- a/src/test/run-pass/issue-3888-2.rs +++ b/src/test/run-pass/issue-3888-2.rs @@ -10,8 +10,8 @@ fn vec_peek(v: &r/[T]) -> &r/[T] { // This doesn't work, and should. -// v.view(1, 5) - vec::view(v, 1, 5) +// v.slice(1, 5) + vec::slice(v, 1, 5) } pub fn main() {} diff --git a/src/test/run-pass/issue-3904.rs b/src/test/run-pass/issue-3904.rs index 885b8da9325da..8f2b13b6eb028 100644 --- a/src/test/run-pass/issue-3904.rs +++ b/src/test/run-pass/issue-3904.rs @@ -20,7 +20,7 @@ fn exit(+print: ErrPrinter, prog: &str, arg: &str) { } struct X { - mut err: ErrPrinter + err: ErrPrinter } impl X { diff --git a/src/test/run-pass/issue-3979-generics.rs b/src/test/run-pass/issue-3979-generics.rs index ab042922df942..ce0ae64856236 100644 --- a/src/test/run-pass/issue-3979-generics.rs +++ b/src/test/run-pass/issue-3979-generics.rs @@ -10,7 +10,7 @@ // xfail-test trait Positioned { - fn SetX(&self, S); + fn SetX(&mut self, S); fn X(&self) -> S; } @@ -21,10 +21,10 @@ trait Movable: Positioned { } } -struct Point { mut x: int, mut y: int } +struct Point { x: int, y: int } impl Positioned for Point { - fn SetX(&self, x: int) { + fn SetX(&mut self, x: int) { self.x = x; } fn X(&self) -> int { diff --git a/src/test/run-pass/issue-3979-xcrate.rs b/src/test/run-pass/issue-3979-xcrate.rs index 07cf9d68d167c..18ad14153d760 100644 --- a/src/test/run-pass/issue-3979-xcrate.rs +++ b/src/test/run-pass/issue-3979-xcrate.rs @@ -13,10 +13,10 @@ extern mod issue_3979_traits; use issue_3979_traits::*; -struct Point { mut x: int, mut y: int } +struct Point { x: int, y: int } impl Positioned for Point { - fn SetX(&self, x: int) { + fn SetX(&mut self, x: int) { self.x = x; } fn X(&self) -> int { @@ -24,10 +24,10 @@ impl Positioned for Point { } } -impl Point: Movable; +impl Movable for Point; pub fn main() { - let p = Point{ x: 1, y: 2}; + let mut p = Point{ x: 1, y: 2}; p.translate(3); assert p.X() == 4; } diff --git a/src/test/run-pass/issue-3979.rs b/src/test/run-pass/issue-3979.rs index 3ea2ef83296a9..6d6be35bfa06a 100644 --- a/src/test/run-pass/issue-3979.rs +++ b/src/test/run-pass/issue-3979.rs @@ -1,3 +1,6 @@ +// xfail-test +// Reason: ICE with explicit self + // 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. @@ -9,21 +12,22 @@ // except according to those terms. trait Positioned { - fn SetX(&self, int); + fn SetX(&mut self, int); fn X(&self) -> int; } #[allow(default_methods)] trait Movable: Positioned { - fn translate(&self, dx: int) { - self.SetX(self.X() + dx); + fn translate(&mut self, dx: int) { + let x = self.X(); + self.SetX(x + dx); } } -struct Point { mut x: int, mut y: int } +struct Point { x: int, y: int } impl Positioned for Point { - fn SetX(&self, x: int) { + fn SetX(&mut self, x: int) { self.x = x; } fn X(&self) -> int { @@ -31,10 +35,10 @@ impl Positioned for Point { } } -impl Point: Movable; +impl Movable for Point; pub fn main() { - let p = Point{ x: 1, y: 2}; + let mut p = Point{ x: 1, y: 2}; p.translate(3); assert p.X() == 4; } diff --git a/src/test/run-pass/issue-4016.rs b/src/test/run-pass/issue-4016.rs index 515b342faf3df..69cd1a2a19d86 100644 --- a/src/test/run-pass/issue-4016.rs +++ b/src/test/run-pass/issue-4016.rs @@ -18,9 +18,9 @@ use std::serialization::{Deserializable, deserialize}; trait JD : Deserializable { } //type JD = Deserializable; -fn exec() { +fn exec() { let doc = result::unwrap(json::from_str("")); - let _v: T = deserialize(&json::Deserializer(move doc)); + let _v: T = deserialize(&json::Deserializer(doc)); fail!() } diff --git a/src/test/compile-fail/mutable-huh-field-assign.rs b/src/test/run-pass/issue-4875.rs similarity index 62% rename from src/test/compile-fail/mutable-huh-field-assign.rs rename to src/test/run-pass/issue-4875.rs index f66d52499fed1..51c23e7680826 100644 --- a/src/test/compile-fail/mutable-huh-field-assign.rs +++ b/src/test/run-pass/issue-4875.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,13 +8,15 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -fn main() { - fn f(&&v: {const field: int}) { - // This shouldn't be possible - v.field = 1 //~ ERROR assigning to const field - } +// regression test for issue 4875 - let v = {field: 0}; +pub struct Foo { + data: T, +} + +fn foo(Foo{_}: Foo) { +} - f(v); +pub fn main() { } + diff --git a/src/test/run-pass/ivec-add.rs b/src/test/run-pass/ivec-add.rs index f06185f37272e..aa61a35d6e350 100644 --- a/src/test/run-pass/ivec-add.rs +++ b/src/test/run-pass/ivec-add.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -fn double(a: T) -> ~[T] { return ~[a] + ~[a]; } +fn double(a: T) -> ~[T] { return ~[a] + ~[a]; } fn double_int(a: int) -> ~[int] { return ~[a] + ~[a]; } diff --git a/src/test/run-pass/ivec-tag.rs b/src/test/run-pass/ivec-tag.rs index 9971b098bb0f5..017d90cbcd736 100644 --- a/src/test/run-pass/ivec-tag.rs +++ b/src/test/run-pass/ivec-tag.rs @@ -1,4 +1,4 @@ -use core::pipes::*; +use core::comm::*; fn producer(c: &Chan<~[u8]>) { c.send( diff --git a/src/test/run-pass/lambda-infer-unresolved.rs b/src/test/run-pass/lambda-infer-unresolved.rs index e6c2ff2814214..b68ec3755d5b3 100644 --- a/src/test/run-pass/lambda-infer-unresolved.rs +++ b/src/test/run-pass/lambda-infer-unresolved.rs @@ -12,10 +12,10 @@ // resolved when we finish typechecking the fn@. -struct Refs { mut refs: ~[int], n: int } +struct Refs { refs: ~[int], n: int } pub fn main() { - let e = @Refs{mut refs: ~[], n: 0}; + let e = @mut Refs{refs: ~[], n: 0}; let f = fn@ () { log(error, e.n); }; e.refs += ~[1]; } diff --git a/src/test/run-pass/last-use-in-block.rs b/src/test/run-pass/last-use-in-block.rs index 9c04ccdcba0aa..e8083dd3f6b21 100644 --- a/src/test/run-pass/last-use-in-block.rs +++ b/src/test/run-pass/last-use-in-block.rs @@ -13,14 +13,14 @@ fn lp(s: ~str, f: fn(~str) -> T) -> T { while false { let r = f(s); - return (move r); + return (r); } fail!(); } fn apply(s: ~str, f: fn(~str) -> T) -> T { fn g(s: ~str, f: fn(~str) -> T) -> T {f(s)} - g(s, |v| { let r = f(v); move r }) + g(s, |v| { let r = f(v); r }) } pub fn main() {} diff --git a/src/test/run-pass/last-use-in-cap-clause.rs b/src/test/run-pass/last-use-in-cap-clause.rs index e8cb47b373846..2fd2cc9d22b81 100644 --- a/src/test/run-pass/last-use-in-cap-clause.rs +++ b/src/test/run-pass/last-use-in-cap-clause.rs @@ -15,7 +15,7 @@ struct A { a: ~int } fn foo() -> fn@() -> int { let k = ~22; let _u = A {a: copy k}; - return fn@(move k) -> int { 22 }; + return fn@() -> int { 22 }; } pub fn main() { diff --git a/src/test/run-pass/liveness-move-in-loop.rs b/src/test/run-pass/liveness-move-in-loop.rs index f8166e2443d80..8c4b7d57bc201 100644 --- a/src/test/run-pass/liveness-move-in-loop.rs +++ b/src/test/run-pass/liveness-move-in-loop.rs @@ -15,7 +15,7 @@ fn the_loop() { loop { let x = 5; if x > 3 { - list += ~[take(move x)]; + list += ~[take(x)]; } else { break; } diff --git a/src/test/run-pass/log-linearized.rs b/src/test/run-pass/log-linearized.rs index db0b24fca1d2d..465e5b63d6bdc 100644 --- a/src/test/run-pass/log-linearized.rs +++ b/src/test/run-pass/log-linearized.rs @@ -15,17 +15,17 @@ enum option { some(T), } -struct Smallintmap {mut v: ~[option]} +struct Smallintmap {v: ~[option]} struct V { v: ~[option] } -fn mk() -> @Smallintmap { +fn mk() -> @mut Smallintmap { let mut v: ~[option] = ~[]; - return @Smallintmap {mut v: move v}; + return @mut Smallintmap {v: v}; } fn f() { - let sim = mk::(); + let mut sim = mk::(); log(error, sim); } diff --git a/src/test/run-pass/mlist-cycle.rs b/src/test/run-pass/mlist-cycle.rs index 8e544c09216ac..e886c941a4b6a 100644 --- a/src/test/run-pass/mlist-cycle.rs +++ b/src/test/run-pass/mlist-cycle.rs @@ -12,14 +12,14 @@ // -*- rust -*- extern mod std; -type cell = {mut c: @list}; +type cell = {c: @list}; -enum list { link(@cell), nil, } +enum list { link(@mut cell), nil, } pub fn main() { - let first: @cell = @{mut c: @nil()}; - let second: @cell = @{mut c: @link(first)}; + let first: @cell = @mut {c: @nil()}; + let second: @cell = @mut {c: @link(first)}; first._0 = @link(second); sys.rustrt.gc(); - let third: @cell = @{mut c: @nil()}; + let third: @cell = @mut {c: @nil()}; } diff --git a/src/test/run-pass/monad.rs b/src/test/run-pass/monad.rs index 9447330fe07ed..5f4e6e984a44b 100644 --- a/src/test/run-pass/monad.rs +++ b/src/test/run-pass/monad.rs @@ -9,42 +9,41 @@ // except according to those terms. // xfail-fast -#[legacy_modes]; trait vec_monad { - fn bind(f: fn(A) -> ~[B]) -> ~[B]; + fn bind(f: fn(&A) -> ~[B]) -> ~[B]; } impl vec_monad for ~[A] { - fn bind(f: fn(A) -> ~[B]) -> ~[B] { + fn bind(f: fn(&A) -> ~[B]) -> ~[B] { let mut r = ~[]; - for self.each |elt| { r += f(*elt); } + for self.each |elt| { r += f(elt); } r } } trait option_monad { - fn bind(f: fn(A) -> Option) -> Option; + fn bind(f: fn(&A) -> Option) -> Option; } impl option_monad for Option { - fn bind(f: fn(A) -> Option) -> Option { + fn bind(f: fn(&A) -> Option) -> Option { match self { - Some(ref a) => { f(*a) } + Some(ref a) => { f(a) } None => { None } } } } fn transform(x: Option) -> Option<~str> { - x.bind(|n| Some(n + 1) ).bind(|n| Some(int::str(n)) ) + x.bind(|n| Some(*n + 1) ).bind(|n| Some(int::str(*n)) ) } pub fn main() { assert transform(Some(10)) == Some(~"11"); assert transform(None) == None; assert (~[~"hi"]) - .bind(|x| ~[copy x, x + ~"!"] ) - .bind(|x| ~[copy x, x + ~"?"] ) == + .bind(|x| ~[copy *x, *x + ~"!"] ) + .bind(|x| ~[copy *x, *x + ~"?"] ) == ~[~"hi", ~"hi?", ~"hi!", ~"hi!?"]; } diff --git a/src/test/run-pass/monomorphized-callees-with-ty-params-3314.rs b/src/test/run-pass/monomorphized-callees-with-ty-params-3314.rs index 57f7a3f24db21..88c317a3c0735 100644 --- a/src/test/run-pass/monomorphized-callees-with-ty-params-3314.rs +++ b/src/test/run-pass/monomorphized-callees-with-ty-params-3314.rs @@ -14,18 +14,18 @@ trait Serializer { } trait Serializable { - fn serialize(s: S); + fn serialize(s: S); } impl Serializable for int { - fn serialize(_s: S) { } + fn serialize(_s: S) { } } struct F { a: A } -impl Serializable for F { - fn serialize(s: S) { - self.a.serialize(move s); +impl Serializable for F { + fn serialize(s: S) { + self.a.serialize(s); } } diff --git a/src/test/run-pass/move-1-unique.rs b/src/test/run-pass/move-1-unique.rs index 380c969fa1c7d..45ba5eb974811 100644 --- a/src/test/run-pass/move-1-unique.rs +++ b/src/test/run-pass/move-1-unique.rs @@ -13,7 +13,7 @@ struct Triple { x: int, y: int, z: int } fn test(x: bool, foo: ~Triple) -> int { let bar = foo; let mut y: ~Triple; - if x { y = move bar; } else { y = ~Triple{x: 4, y: 5, z: 6}; } + if x { y = bar; } else { y = ~Triple{x: 4, y: 5, z: 6}; } return y.y; } diff --git a/src/test/run-pass/move-1.rs b/src/test/run-pass/move-1.rs index ea6dc94bb8ef4..35cbe6e080cc8 100644 --- a/src/test/run-pass/move-1.rs +++ b/src/test/run-pass/move-1.rs @@ -13,7 +13,7 @@ struct Triple { x: int, y: int, z: int } fn test(x: bool, foo: @Triple) -> int { let bar = foo; let mut y: @Triple; - if x { y = move bar; } else { y = @Triple{x: 4, y: 5, z: 6}; } + if x { y = bar; } else { y = @Triple{x: 4, y: 5, z: 6}; } return y.y; } diff --git a/src/test/run-pass/move-2-unique.rs b/src/test/run-pass/move-2-unique.rs index 133837089b8a3..bc3b5405f1867 100644 --- a/src/test/run-pass/move-2-unique.rs +++ b/src/test/run-pass/move-2-unique.rs @@ -11,4 +11,4 @@ struct X { x: int, y: int, z: int } -pub fn main() { let x = ~X{x: 1, y: 2, z: 3}; let y = move x; assert (y.y == 2); } +pub fn main() { let x = ~X{x: 1, y: 2, z: 3}; let y = x; assert (y.y == 2); } diff --git a/src/test/run-pass/move-2.rs b/src/test/run-pass/move-2.rs index f2b534765cf51..23ec3a178c15a 100644 --- a/src/test/run-pass/move-2.rs +++ b/src/test/run-pass/move-2.rs @@ -11,4 +11,4 @@ struct X { x: int, y: int, z: int } -pub fn main() { let x = @X {x: 1, y: 2, z: 3}; let y = move x; assert (y.y == 2); } +pub fn main() { let x = @X {x: 1, y: 2, z: 3}; let y = x; assert (y.y == 2); } diff --git a/src/test/run-pass/move-3-unique.rs b/src/test/run-pass/move-3-unique.rs index 40d8f9a9bcef7..82b8d2c960921 100644 --- a/src/test/run-pass/move-3-unique.rs +++ b/src/test/run-pass/move-3-unique.rs @@ -15,7 +15,7 @@ struct Triple { x: int, y: int, z: int } fn test(x: bool, foo: ~Triple) -> int { let bar = foo; let mut y: ~Triple; - if x { y = move bar; } else { y = ~Triple {x: 4, y: 5, z: 6}; } + if x { y = bar; } else { y = ~Triple {x: 4, y: 5, z: 6}; } return y.y; } diff --git a/src/test/run-pass/move-3.rs b/src/test/run-pass/move-3.rs index 0e57d0f612689..161dc55f8a34b 100644 --- a/src/test/run-pass/move-3.rs +++ b/src/test/run-pass/move-3.rs @@ -15,7 +15,7 @@ struct Triple { x: int, y: int, z: int } fn test(x: bool, foo: @Triple) -> int { let bar = foo; let mut y: @Triple; - if x { y = move bar; } else { y = @Triple{x: 4, y: 5, z: 6}; } + if x { y = bar; } else { y = @Triple{x: 4, y: 5, z: 6}; } return y.y; } diff --git a/src/test/run-pass/move-4-unique.rs b/src/test/run-pass/move-4-unique.rs index 7b7b816aeb2ab..8845bdfffe146 100644 --- a/src/test/run-pass/move-4-unique.rs +++ b/src/test/run-pass/move-4-unique.rs @@ -14,9 +14,9 @@ struct Triple {a: int, b: int, c: int} fn test(foo: ~Triple) -> ~Triple { let foo = foo; - let bar = move foo; - let baz = move bar; - let quux = move baz; + let bar = foo; + let baz = bar; + let quux = baz; return quux; } diff --git a/src/test/run-pass/move-4.rs b/src/test/run-pass/move-4.rs index cdb48b43b35ba..1a5432620d308 100644 --- a/src/test/run-pass/move-4.rs +++ b/src/test/run-pass/move-4.rs @@ -15,9 +15,9 @@ struct Triple { a: int, b: int, c: int } fn test(foo: @Triple) -> @Triple { let foo = foo; - let bar = move foo; - let baz = move bar; - let quux = move baz; + let bar = foo; + let baz = bar; + let quux = baz; return quux; } diff --git a/src/test/run-pass/move-arg-2-unique.rs b/src/test/run-pass/move-arg-2-unique.rs index e6a3670804bae..21969418c3451 100644 --- a/src/test/run-pass/move-arg-2-unique.rs +++ b/src/test/run-pass/move-arg-2-unique.rs @@ -13,7 +13,7 @@ fn test(-foo: ~~[int]) { assert (foo[0] == 10); } pub fn main() { let x = ~~[10]; // Test forgetting a local by move-in - test(move x); + test(x); // Test forgetting a temporary by move-in. test(~~[10]); diff --git a/src/test/run-pass/move-arg-2.rs b/src/test/run-pass/move-arg-2.rs index 09dc47ab50e00..8c843d2da682f 100644 --- a/src/test/run-pass/move-arg-2.rs +++ b/src/test/run-pass/move-arg-2.rs @@ -13,7 +13,7 @@ fn test(-foo: @~[int]) { assert (foo[0] == 10); } pub fn main() { let x = @~[10]; // Test forgetting a local by move-in - test(move x); + test(x); // Test forgetting a temporary by move-in. test(@~[10]); diff --git a/src/test/run-pass/move-arg.rs b/src/test/run-pass/move-arg.rs index 8e65981ebdf1c..570fa6ee39166 100644 --- a/src/test/run-pass/move-arg.rs +++ b/src/test/run-pass/move-arg.rs @@ -10,4 +10,4 @@ fn test(-foo: int) { assert (foo == 10); } -pub fn main() { let x = 10; test(move x); } +pub fn main() { let x = 10; test(x); } diff --git a/src/test/run-pass/move-nullary-fn.rs b/src/test/run-pass/move-nullary-fn.rs index 0aac8857c598d..0114eeefbfb2d 100644 --- a/src/test/run-pass/move-nullary-fn.rs +++ b/src/test/run-pass/move-nullary-fn.rs @@ -12,7 +12,7 @@ fn f2(-thing: fn@()) { } fn f(-thing: fn@()) { - f2(move thing); + f2(thing); } pub fn main() { diff --git a/src/test/run-pass/move-scalar.rs b/src/test/run-pass/move-scalar.rs index 533543ad138cc..a7ddc4e4cdbe2 100644 --- a/src/test/run-pass/move-scalar.rs +++ b/src/test/run-pass/move-scalar.rs @@ -12,6 +12,6 @@ pub fn main() { let y: int = 42; let mut x: int; - x = move y; + x = y; assert (x == 42); } diff --git a/src/test/run-pass/move-self.rs b/src/test/run-pass/move-self.rs index 170dd520ed6f4..37ce1bce9e659 100644 --- a/src/test/run-pass/move-self.rs +++ b/src/test/run-pass/move-self.rs @@ -4,7 +4,7 @@ struct S { impl S { fn foo(self) { - (move self).bar(); + self.bar(); } fn bar(self) { diff --git a/src/test/run-pass/nested-patterns.rs b/src/test/run-pass/nested-patterns.rs index 846136c242c36..10d76cdd9775e 100644 --- a/src/test/run-pass/nested-patterns.rs +++ b/src/test/run-pass/nested-patterns.rs @@ -11,17 +11,17 @@ struct A { a: int, b: @int } struct B { a: int, b: C } struct D { a: int, d: C } -struct C { mut c: int } +struct C { c: int } pub fn main() { match A {a: 10, b: @20} { x@A {a, b: @20} => { assert x.a == 10; assert a == 10; } A {b, _} => { fail!(); } } - let x@B {b, _} = B {a: 10, b: C {mut c: 20}}; + let mut x@B {b, _} = B {a: 10, b: C {c: 20}}; x.b.c = 30; assert b.c == 20; - let y@D {d, _} = D {a: 10, d: C {mut c: 20}}; + let mut y@D {d, _} = D {a: 10, d: C {c: 20}}; y.d.c = 30; assert d.c == 20; } diff --git a/src/test/run-pass/newtype-polymorphic.rs b/src/test/run-pass/newtype-polymorphic.rs index dfa1008a69e30..01e554ad04128 100644 --- a/src/test/run-pass/newtype-polymorphic.rs +++ b/src/test/run-pass/newtype-polymorphic.rs @@ -10,9 +10,9 @@ enum myvec = ~[X]; -fn myvec_deref(mv: myvec) -> ~[X] { return copy *mv; } +fn myvec_deref(mv: myvec) -> ~[X] { return copy *mv; } -fn myvec_elt(mv: myvec) -> X { return mv[0]; } +fn myvec_elt(mv: myvec) -> X { return mv[0]; } pub fn main() { let mv = myvec(~[1, 2, 3]); diff --git a/src/test/run-pass/newtype-struct-xc-2.rs b/src/test/run-pass/newtype-struct-xc-2.rs index a7c686daa7f35..1fca01f737327 100644 --- a/src/test/run-pass/newtype-struct-xc-2.rs +++ b/src/test/run-pass/newtype-struct-xc-2.rs @@ -8,7 +8,7 @@ fn f() -> Au { Au(2) } -fn main() { +pub fn main() { let _ = f(); } diff --git a/src/test/run-pass/newtype-struct-xc.rs b/src/test/run-pass/newtype-struct-xc.rs index 8b15d73dc933d..49ce618e37b4c 100644 --- a/src/test/run-pass/newtype-struct-xc.rs +++ b/src/test/run-pass/newtype-struct-xc.rs @@ -3,7 +3,7 @@ extern mod newtype_struct_xc; -fn main() { +pub fn main() { let _ = newtype_struct_xc::Au(2); } diff --git a/src/test/run-pass/non-boolean-pure-fns.rs b/src/test/run-pass/non-boolean-pure-fns.rs index 3fb9a557fa18c..931c4cbad79c4 100644 --- a/src/test/run-pass/non-boolean-pure-fns.rs +++ b/src/test/run-pass/non-boolean-pure-fns.rs @@ -14,15 +14,15 @@ extern mod std; use std::list::*; -pure fn pure_length_go(ls: @List, acc: uint) -> uint { +pure 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) } +pure fn pure_length(ls: @List) -> uint { pure_length_go(ls, 0u) } -pure fn nonempty_list(ls: @List) -> bool { pure_length(ls) > 0u } +pure fn nonempty_list(ls: @List) -> bool { pure_length(ls) > 0u } -fn safe_head(ls: @List) -> T { +fn safe_head(ls: @List) -> T { assert !is_empty(ls); return head(ls); } diff --git a/src/test/run-pass/non-legacy-modes.rs b/src/test/run-pass/non-legacy-modes.rs index 6db971121b758..2a1f94a1d8cdf 100644 --- a/src/test/run-pass/non-legacy-modes.rs +++ b/src/test/run-pass/non-legacy-modes.rs @@ -13,7 +13,7 @@ struct X { } fn apply(x: T, f: fn(T)) { - f(move x); + f(x); } fn check_int(x: int) { diff --git a/src/test/compile-fail/borrowck-imm-ref-to-mut-rec-field-issue-3162-b.rs b/src/test/run-pass/one-tuple.rs similarity index 54% rename from src/test/compile-fail/borrowck-imm-ref-to-mut-rec-field-issue-3162-b.rs rename to src/test/run-pass/one-tuple.rs index f808f9ced32f1..9d01fbface0dd 100644 --- a/src/test/compile-fail/borrowck-imm-ref-to-mut-rec-field-issue-3162-b.rs +++ b/src/test/run-pass/one-tuple.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,15 +8,17 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -fn each(x: &[T], op: fn(elem: &T) -> bool) { - uint::range(0, x.len(), |i| op(&x[i])); -} +// Why one-tuples? Because macros. fn main() { - let x = [{mut a: 0}]; - for each(x) |y| { - let z = &y.a; //~ ERROR illegal borrow unless pure - x[0].a = 10; //~ NOTE impure due to assigning to mutable field - log(error, z); + match ('c',) { + (x,) => { + assert x == 'c'; + } } + // test the 1-tuple type too + let x: (char,) = ('d',); + let (y,) = x; + assert y == 'd'; } + diff --git a/src/test/run-pass/operator-overloading.rs b/src/test/run-pass/operator-overloading.rs index 3c6a347137752..c9e8c6f4b1491 100644 --- a/src/test/run-pass/operator-overloading.rs +++ b/src/test/run-pass/operator-overloading.rs @@ -9,7 +9,6 @@ // except according to those terms. // xfail-fast -#[legacy_modes]; struct Point { x: int, diff --git a/src/test/run-pass/option-unwrap.rs b/src/test/run-pass/option-unwrap.rs index 9f787c915e59d..7616ff5007eee 100644 --- a/src/test/run-pass/option-unwrap.rs +++ b/src/test/run-pass/option-unwrap.rs @@ -21,8 +21,8 @@ impl Drop for dtor { } fn unwrap(+o: Option) -> T { - match move o { - Some(move v) => move v, + match o { + Some(v) => v, None => fail!() } } @@ -32,7 +32,7 @@ pub fn main() { { let b = Some(dtor { x:x }); - let c = unwrap(move b); + let c = unwrap(b); } assert *x == 0; diff --git a/src/test/run-pass/pipe-bank-proto.rs b/src/test/run-pass/pipe-bank-proto.rs index d79160a41c44a..b74c70d3ea716 100644 --- a/src/test/run-pass/pipe-bank-proto.rs +++ b/src/test/run-pass/pipe-bank-proto.rs @@ -15,7 +15,8 @@ // // http://theincredibleholk.wordpress.com/2012/07/06/rusty-pipes/ -use pipes::try_recv; +use core::pipes; +use core::pipes::try_recv; pub type username = ~str; pub type password = ~str; @@ -44,21 +45,21 @@ proto! bank ( ) macro_rules! move_it ( - { $x:expr } => { unsafe { let y = move *ptr::addr_of(&($x)); move y } } + { $x:expr } => { unsafe { let y = *ptr::addr_of(&($x)); y } } ) -fn switch(+endp: pipes::RecvPacket, +fn switch(+endp: pipes::RecvPacket, f: fn(+v: Option) -> U) -> U { - f(pipes::try_recv(move endp)) + f(pipes::try_recv(endp)) } -fn move_it(-x: T) -> T { move x } +fn move_it(-x: T) -> T { x } macro_rules! follow ( { $($message:path$(($($x: ident),+))||* -> $next:ident $e:expr)+ } => ( - |m| match move m { + |m| match m { $(Some($message($($($x,)+)* next)) => { let $next = move_it!(next); $e })+ @@ -70,15 +71,15 @@ macro_rules! follow ( fn client_follow(+bank: bank::client::login) { use bank::*; - let bank = client::login(move bank, ~"theincredibleholk", ~"1234"); - let bank = switch(move bank, follow! ( - ok -> connected { move connected } + let bank = client::login(bank, ~"theincredibleholk", ~"1234"); + let bank = switch(bank, follow! ( + ok -> connected { connected } invalid -> _next { fail!(~"bank closed the connected") } )); - let bank = client::deposit(move bank, 100.00); - let bank = client::withdrawal(move bank, 50.00); - switch(move bank, follow! ( + let bank = client::deposit(bank, 100.00); + let bank = client::withdrawal(bank, 50.00); + switch(bank, follow! ( money(m) -> _next { io::println(~"Yay! I got money!"); } @@ -91,8 +92,8 @@ fn client_follow(+bank: bank::client::login) { fn bank_client(+bank: bank::client::login) { use bank::*; - let bank = client::login(move bank, ~"theincredibleholk", ~"1234"); - let bank = match try_recv(move bank) { + let bank = client::login(bank, ~"theincredibleholk", ~"1234"); + let bank = match try_recv(bank) { Some(ok(connected)) => { move_it!(connected) } @@ -100,9 +101,9 @@ fn bank_client(+bank: bank::client::login) { None => { fail!(~"bank closed the connection") } }; - let bank = client::deposit(move bank, 100.00); - let bank = client::withdrawal(move bank, 50.00); - match try_recv(move bank) { + let bank = client::deposit(bank, 100.00); + let bank = client::withdrawal(bank, 50.00); + match try_recv(bank) { Some(money(*)) => { io::println(~"Yay! I got money!"); } diff --git a/src/test/run-pass/pipe-detect-term.rs b/src/test/run-pass/pipe-detect-term.rs index 6831170734d14..6afa9e29349f3 100644 --- a/src/test/run-pass/pipe-detect-term.rs +++ b/src/test/run-pass/pipe-detect-term.rs @@ -14,13 +14,12 @@ // xfail-win32 -#[legacy_records]; - extern mod std; use std::timer::sleep; use std::uv; -use pipes::{try_recv, recv}; +use core::pipes; +use core::pipes::{try_recv, recv}; proto! oneshot ( waiting:send { @@ -32,7 +31,7 @@ pub fn main() { let iotask = &uv::global_loop::get(); pipes::spawn_service(oneshot::init, |p| { - match try_recv(move p) { + match try_recv(p) { Some(*) => { fail!() } None => { } } @@ -47,11 +46,11 @@ pub fn main() { fn failtest() { let (c, p) = oneshot::init(); - do task::spawn_with(move c) |_c| { + do task::spawn_with(c) |_c| { fail!(); } - error!("%?", recv(move p)); + error!("%?", recv(p)); // make sure we get killed if we missed it in the receive. loop { task::yield() } } diff --git a/src/test/run-pass/pipe-peek.rs b/src/test/run-pass/pipe-peek.rs index 7dc1feb24179b..25fa1a956bf78 100644 --- a/src/test/run-pass/pipe-peek.rs +++ b/src/test/run-pass/pipe-peek.rs @@ -10,11 +10,10 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#[legacy_records]; - extern mod std; use std::timer::sleep; use std::uv; +use core::pipes; proto! oneshot ( waiting:send { @@ -27,7 +26,7 @@ pub fn main() { assert !pipes::peek(&p); - oneshot::client::signal(move c); + oneshot::client::signal(c); assert pipes::peek(&p); } diff --git a/src/test/run-pass/pipe-pingpong-bounded.rs b/src/test/run-pass/pipe-pingpong-bounded.rs index a3b03daf02fbf..2ada6df76a6a8 100644 --- a/src/test/run-pass/pipe-pingpong-bounded.rs +++ b/src/test/run-pass/pipe-pingpong-bounded.rs @@ -17,26 +17,26 @@ // This was generated initially by the pipe compiler, but it's been // modified in hopefully straightforward ways. -#[legacy_records]; mod pingpong { + use core::pipes; use core::pipes::*; use core::ptr; - pub type packets = { + pub struct Packets { ping: Packet, pong: Packet, - }; + } pub fn init() -> (client::ping, server::ping) { let buffer = ~Buffer { header: BufferHeader(), - data: { + data: Packets { ping: mk_packet::(), pong: mk_packet::() } }; - do pipes::entangle_buffer(move buffer) |buffer, data| { + do pipes::entangle_buffer(buffer) |buffer, data| { data.ping.set_buffer(buffer); data.pong.set_buffer(buffer); ptr::addr_of(&(data.ping)) @@ -45,6 +45,7 @@ mod pingpong { pub enum ping = server::pong; pub enum pong = client::ping; pub mod client { + use core::pipes; use core::pipes::*; use core::ptr; @@ -53,72 +54,73 @@ mod pingpong { let b = pipe.reuse_buffer(); let s = SendPacketBuffered(ptr::addr_of(&(b.buffer.data.pong))); let c = RecvPacketBuffered(ptr::addr_of(&(b.buffer.data.pong))); - let message = ::pingpong::ping(move s); - ::pipes::send(move pipe, move message); - move c + let message = ::pingpong::ping(s); + send(pipe, message); + c } } pub type ping = pipes::SendPacketBuffered<::pingpong::ping, - ::pingpong::packets>; + ::pingpong::Packets>; pub type pong = pipes::RecvPacketBuffered<::pingpong::pong, - ::pingpong::packets>; + ::pingpong::Packets>; } pub mod server { + use core::pipes; use core::pipes::*; use core::ptr; pub type ping = pipes::RecvPacketBuffered<::pingpong::ping, - ::pingpong::packets>; + ::pingpong::Packets>; pub fn pong(+pipe: pong) -> ping { { let b = pipe.reuse_buffer(); let s = SendPacketBuffered(ptr::addr_of(&(b.buffer.data.ping))); let c = RecvPacketBuffered(ptr::addr_of(&(b.buffer.data.ping))); - let message = ::pingpong::pong(move s); - ::pipes::send(move pipe, move message); - move c + let message = ::pingpong::pong(s); + send(pipe, message); + c } } pub type pong = pipes::SendPacketBuffered<::pingpong::pong, - ::pingpong::packets>; + ::pingpong::Packets>; } } mod test { - use pipes::recv; + use core::pipes::recv; use pingpong::{ping, pong}; pub fn client(-chan: ::pingpong::client::ping) { use pingpong::client; - let chan = client::ping(move chan); return; + let chan = client::ping(chan); return; log(error, "Sent ping"); - let pong(_chan) = recv(move chan); + let pong(_chan) = recv(chan); log(error, "Received pong"); } pub fn server(-chan: ::pingpong::server::ping) { use pingpong::server; - let ping(chan) = recv(move chan); return; + let ping(chan) = recv(chan); return; log(error, "Received ping"); - let _chan = server::pong(move chan); + let _chan = server::pong(chan); log(error, "Sent pong"); } } pub fn main() { let (client_, server_) = ::pingpong::init(); - let client_ = ~mut Some(move client_); - let server_ = ~mut Some(move server_); - do task::spawn |move client_| { + let client_ = ~mut Some(client_); + let server_ = ~mut Some(server_); + do task::spawn || { let mut client__ = None; *client_ <-> client__; - test::client(option::unwrap(move client__)); + test::client(option::unwrap(client__)); }; - do task::spawn |move server_| { + do task::spawn || { let mut server_ËŠ = None; *server_ <-> server_ËŠ; - test::server(option::unwrap(move server_ËŠ)); + test::server(option::unwrap(server_ËŠ)); }; } diff --git a/src/test/run-pass/pipe-pingpong-proto.rs b/src/test/run-pass/pipe-pingpong-proto.rs index 97afbba42c5b5..050ff76ef9b75 100644 --- a/src/test/run-pass/pipe-pingpong-proto.rs +++ b/src/test/run-pass/pipe-pingpong-proto.rs @@ -12,8 +12,6 @@ // An example to make sure the protocol parsing syntax extension works. -#[legacy_records]; - use core::option; proto! pingpong ( @@ -33,35 +31,35 @@ mod test { pub fn client(-chan: ::pingpong::client::ping) { use pingpong::client; - let chan = client::ping(move chan); + let chan = client::ping(chan); log(error, ~"Sent ping"); - let pong(_chan) = recv(move chan); + let pong(_chan) = recv(chan); log(error, ~"Received pong"); } pub fn server(-chan: ::pingpong::server::ping) { use pingpong::server; - let ping(chan) = recv(move chan); + let ping(chan) = recv(chan); log(error, ~"Received ping"); - let _chan = server::pong(move chan); + let _chan = server::pong(chan); log(error, ~"Sent pong"); } } pub fn main() { let (client_, server_) = pingpong::init(); - let client_ = ~mut Some(move client_); - let server_ = ~mut Some(move server_); + let client_ = ~mut Some(client_); + let server_ = ~mut Some(server_); - do task::spawn |move client_| { + do task::spawn || { let mut client__ = None; *client_ <-> client__; - test::client(option::unwrap(move client__)); + test::client(option::unwrap(client__)); }; - do task::spawn |move server_| { + do task::spawn || { let mut server_ËŠ = None; *server_ <-> server_ËŠ; - test::server(option::unwrap(move server_ËŠ)); + test::server(option::unwrap(server_ËŠ)); }; } diff --git a/src/test/run-pass/pipe-presentation-examples.rs b/src/test/run-pass/pipe-presentation-examples.rs index 401c32b67f9d4..85ab1f89dbeca 100644 --- a/src/test/run-pass/pipe-presentation-examples.rs +++ b/src/test/run-pass/pipe-presentation-examples.rs @@ -15,8 +15,6 @@ // Code is easier to write in emacs, and it's good to be sure all the // code samples compile (or not) as they should. -#[legacy_records]; - use double_buffer::client::*; use double_buffer::give_buffer; @@ -34,10 +32,10 @@ macro_rules! select_if ( ], )* } => { if $index == $count { - match move pipes::try_recv(move $port) { - $(Some($message($($(move $x,)+)* move next)) => { - let $next = move next; - move $e + match core::pipes::try_recv($port) { + $(Some($message($($($x,)+)* next)) => { + let $next = next; + $e })+ _ => fail!() } @@ -68,7 +66,7 @@ macro_rules! select ( -> $next:ident $e:expr),+ } )+ } => ({ - let index = pipes::selecti([$(($port).header()),+]); + let index = core::comm::selecti([$(($port).header()),+]); select_if!(index, 0, $( $port => [ $($message$(($($x),+))dont_type_this* -> $next $e),+ ], )+) @@ -81,7 +79,7 @@ pub struct Buffer { } -pub impl Buffer : Drop { +pub impl Drop for Buffer { fn finalize(&self) {} } @@ -105,33 +103,33 @@ fn render(_buffer: &Buffer) { } fn draw_frame(+channel: double_buffer::client::acquire) { - let channel = request(move channel); + let channel = request(channel); select! ( channel => { give_buffer(buffer) -> channel { render(&buffer); - release(move channel, move buffer) + release(channel, buffer) } } ); } fn draw_two_frames(+channel: double_buffer::client::acquire) { - let channel = request(move channel); + let channel = request(channel); let channel = select! ( channel => { give_buffer(buffer) -> channel { render(&buffer); - release(move channel, move buffer) + release(channel, buffer) } } ); - let channel = request(move channel); + let channel = request(channel); select! ( channel => { give_buffer(buffer) -> channel { render(&buffer); - release(move channel, move buffer) + release(channel, buffer) } } ); @@ -152,7 +150,7 @@ fn draw_two_frames_bad1(+channel: double_buffer::client::acquire) { channel => { give_buffer(buffer) -> channel { render(&buffer); - release(channel, move buffer) + release(channel, buffer) } } ); @@ -165,9 +163,9 @@ fn draw_two_frames_bad2(+channel: double_buffer::client::acquire) { channel => { give_buffer(buffer) -> channel { render(&buffer); - release(channel, move buffer); + release(channel, buffer); render(&buffer); - release(channel, move buffer); + release(channel, buffer); } } ); diff --git a/src/test/run-pass/pipe-select.rs b/src/test/run-pass/pipe-select.rs index 62765d71398fc..e6a7edd7a6b6b 100644 --- a/src/test/run-pass/pipe-select.rs +++ b/src/test/run-pass/pipe-select.rs @@ -13,13 +13,12 @@ // xfail-pretty // xfail-win32 -#[legacy_records]; - extern mod std; use std::timer::sleep; use std::uv; -use pipes::{recv, select}; +use core::pipes; +use core::pipes::{recv, select}; proto! oneshot ( waiting:send { @@ -41,24 +40,24 @@ pub fn main() { let c = pipes::spawn_service(stream::init, |p| { error!("waiting for pipes"); - let stream::send(x, p) = recv(move p); + let stream::send(x, p) = recv(p); error!("got pipes"); let (left, right) : (oneshot::server::waiting, oneshot::server::waiting) - = move x; + = x; error!("selecting"); - let (i, _, _) = select(~[move left, move right]); + let (i, _, _) = select(~[left, right]); error!("selected"); assert i == 0; error!("waiting for pipes"); - let stream::send(x, _) = recv(move p); + let stream::send(x, _) = recv(p); error!("got pipes"); let (left, right) : (oneshot::server::waiting, oneshot::server::waiting) - = move x; + = x; error!("selecting"); - let (i, m, _) = select(~[move left, move right]); + let (i, m, _) = select(~[left, right]); error!("selected %?", i); if m.is_some() { assert i == 1; @@ -68,20 +67,20 @@ pub fn main() { let (c1, p1) = oneshot::init(); let (_c2, p2) = oneshot::init(); - let c = send(move c, (move p1, move p2)); + let c = send(c, (p1, p2)); sleep(iotask, 100); - signal(move c1); + signal(c1); let (_c1, p1) = oneshot::init(); let (c2, p2) = oneshot::init(); - send(move c, (move p1, move p2)); + send(c, (p1, p2)); sleep(iotask, 100); - signal(move c2); + signal(c2); test_select2(); } @@ -90,26 +89,26 @@ fn test_select2() { let (ac, ap) = stream::init(); let (bc, bp) = stream::init(); - stream::client::send(move ac, 42); + stream::client::send(ac, 42); - match pipes::select2(move ap, move bp) { + match pipes::select2(ap, bp) { either::Left(*) => { } either::Right(*) => { fail!() } } - stream::client::send(move bc, ~"abc"); + stream::client::send(bc, ~"abc"); error!("done with first select2"); let (ac, ap) = stream::init(); let (bc, bp) = stream::init(); - stream::client::send(move bc, ~"abc"); + stream::client::send(bc, ~"abc"); - match pipes::select2(move ap, move bp) { + match pipes::select2(ap, bp) { either::Left(*) => { fail!() } either::Right(*) => { } } - stream::client::send(move ac, 42); + stream::client::send(ac, 42); } diff --git a/src/test/run-pass/pipe-sleep.rs b/src/test/run-pass/pipe-sleep.rs index ac4829a9c19ad..57d72edd0a46a 100644 --- a/src/test/run-pass/pipe-sleep.rs +++ b/src/test/run-pass/pipe-sleep.rs @@ -10,12 +10,11 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#[legacy_records]; - extern mod std; use std::timer::sleep; use std::uv; -use pipes::recv; +use core::pipes; +use core::pipes::recv; proto! oneshot ( waiting:send { @@ -26,10 +25,10 @@ proto! oneshot ( pub fn main() { use oneshot::client::*; - let c = pipes::spawn_service(oneshot::init, |p| { recv(move p); }); + let c = pipes::spawn_service(oneshot::init, |p| { recv(p); }); let iotask = &uv::global_loop::get(); sleep(iotask, 500); - signal(move c); + signal(c); } diff --git a/src/test/run-pass/reflect-visit-data.rs b/src/test/run-pass/reflect-visit-data.rs index d6470ad72b04e..27afde631b2ab 100644 --- a/src/test/run-pass/reflect-visit-data.rs +++ b/src/test/run-pass/reflect-visit-data.rs @@ -9,7 +9,6 @@ // except according to those terms. // xfail-fast -#[legacy_modes]; use core::bool; use intrinsic::{TyDesc, get_tydesc, visit_tydesc, TyVisitor}; @@ -31,7 +30,7 @@ fn align(size: uint, align: uint) -> uint { enum ptr_visit_adaptor = Inner; -impl ptr_visit_adaptor { +impl ptr_visit_adaptor { #[inline(always)] fn bump(sz: uint) { @@ -59,7 +58,7 @@ impl ptr_visit_adaptor { } -impl TyVisitor for ptr_visit_adaptor { +impl TyVisitor for ptr_visit_adaptor { fn visit_bot(&self) -> bool { self.align_to::<()>(); @@ -471,12 +470,12 @@ impl TyVisitor for ptr_visit_adaptor { } } -enum my_visitor = @Stuff; +enum my_visitor = @mut Stuff; struct Stuff { - mut ptr1: *c_void, - mut ptr2: *c_void, - mut vals: ~[~str] + ptr1: *c_void, + ptr2: *c_void, + vals: ~[~str] } impl my_visitor { @@ -636,11 +635,11 @@ struct Triple { x: int, y: int, z: int } pub fn main() { unsafe { - let r = (1,2,3,true,false, Triple {x:5,y:4,z:3}); + let r = (1,2,3,true,false, Triple {x:5,y:4,z:3}, (12,)); let p = ptr::addr_of(&r) as *c_void; - let u = my_visitor(@Stuff {mut ptr1: p, - mut ptr2: p, - mut vals: ~[]}); + let u = my_visitor(@mut Stuff {ptr1: p, + ptr2: p, + vals: ~[]}); let v = ptr_visit_adaptor(Inner {inner: u}); let td = get_tydesc_for(r); unsafe { error!("tydesc sz: %u, align: %u", @@ -653,7 +652,7 @@ pub fn main() { } error!("%?", copy u.vals); assert u.vals == ~[ - ~"1", ~"2", ~"3", ~"true", ~"false", ~"5", ~"4", ~"3" + ~"1", ~"2", ~"3", ~"true", ~"false", ~"5", ~"4", ~"3", ~"12" ]; } } diff --git a/src/test/run-pass/reflect-visit-type.rs b/src/test/run-pass/reflect-visit-type.rs index 6b57c73d0f276..672e87e4f443d 100644 --- a/src/test/run-pass/reflect-visit-type.rs +++ b/src/test/run-pass/reflect-visit-type.rs @@ -10,7 +10,7 @@ // xfail-test use intrinsic::{TyDesc, get_tydesc, visit_tydesc, TyVisitor}; -enum my_visitor = @{ mut types: ~[str] }; +enum my_visitor = @mut { types: ~[str] }; impl TyVisitor for my_visitor { fn visit_bot() -> bool { @@ -141,7 +141,7 @@ fn visit_ty(v: TyVisitor) { } pub fn main() { - let v = my_visitor(@{mut types: ~[]}); + let v = my_visitor(@mut {types: ~[]}); let vv = v as TyVisitor; visit_ty::(vv); diff --git a/src/test/run-pass/regions-copy-closure.rs b/src/test/run-pass/regions-copy-closure.rs index bfb4ac5f60c99..ff3e115eda9b0 100644 --- a/src/test/run-pass/regions-copy-closure.rs +++ b/src/test/run-pass/regions-copy-closure.rs @@ -13,7 +13,7 @@ struct closure_box { } fn box_it(+x: &r/fn()) -> closure_box/&r { - closure_box {cl: move x} + closure_box {cl: x} } pub fn main() { diff --git a/src/test/run-pass/regions-params.rs b/src/test/run-pass/regions-params.rs index 0691f42bb7b27..ea981dc5fb70a 100644 --- a/src/test/run-pass/regions-params.rs +++ b/src/test/run-pass/regions-params.rs @@ -9,7 +9,6 @@ // except according to those terms. // xfail-fast -#[legacy_modes]; fn region_identity(x: &r/uint) -> &r/uint { x } diff --git a/src/test/run-pass/regions-self-impls.rs b/src/test/run-pass/regions-self-impls.rs index 7b07a8cf1af4d..22eec65b02a07 100644 --- a/src/test/run-pass/regions-self-impls.rs +++ b/src/test/run-pass/regions-self-impls.rs @@ -8,14 +8,16 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -struct Clam { chowder: &int } +struct Clam<'self> { + chowder: &'self int +} -trait get_chowder { - fn get_chowder() -> &self/int; +trait get_chowder<'self> { + fn get_chowder() -> &'self int; } -impl get_chowder for Clam { - fn get_chowder() -> &self/int { return self.chowder; } +impl<'self> get_chowder<'self> for Clam<'self> { + fn get_chowder() -> &'self int { return self.chowder; } } pub fn main() { diff --git a/src/test/run-pass/regions-static-closure.rs b/src/test/run-pass/regions-static-closure.rs index 8b7fbfd3758c0..00f5e695475a2 100644 --- a/src/test/run-pass/regions-static-closure.rs +++ b/src/test/run-pass/regions-static-closure.rs @@ -13,7 +13,7 @@ struct closure_box { } fn box_it(+x: &r/fn()) -> closure_box/&r { - closure_box {cl: move x} + closure_box {cl: x} } fn call_static_closure(cl: closure_box/&static) { @@ -22,5 +22,5 @@ fn call_static_closure(cl: closure_box/&static) { pub fn main() { let cl_box = box_it(|| debug!("Hello, world!")); - call_static_closure(move cl_box); + call_static_closure(cl_box); } 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 ee28c96defcad..af3c92db8f6a1 100644 --- a/src/test/run-pass/resource-assign-is-not-copy.rs +++ b/src/test/run-pass/resource-assign-is-not-copy.rs @@ -29,8 +29,8 @@ pub fn main() { // Even though these look like copies, they are guaranteed not to be { let a = r(i); - let b = (move a, 10); - let (c, _d) = move b; + let b = (a, 10); + let (c, _d) = b; log(debug, c); } assert *i == 1; diff --git a/src/test/run-pass/resource-cycle.rs b/src/test/run-pass/resource-cycle.rs index fb9a1e8117a5b..f5a959b2dbcab 100644 --- a/src/test/run-pass/resource-cycle.rs +++ b/src/test/run-pass/resource-cycle.rs @@ -37,7 +37,7 @@ fn r(v: *int) -> r { enum t = Node; struct Node { - mut next: Option<@t>, + next: Option<@mut t>, r: r } @@ -45,36 +45,36 @@ pub fn main() { unsafe { let i1 = ~0; let i1p = cast::reinterpret_cast(&i1); - cast::forget(move i1); + cast::forget(i1); let i2 = ~0; let i2p = cast::reinterpret_cast(&i2); - cast::forget(move i2); + cast::forget(i2); - let x1 = @t(Node{ - mut next: None, + let mut x1 = @mut t(Node{ + next: None, r: { let rs = r(i1p); debug!("r = %x", cast::reinterpret_cast::<*r, uint>(&ptr::addr_of(&rs))); - move rs } + rs } }); debug!("x1 = %x, x1.r = %x", - cast::reinterpret_cast::<@t, uint>(&x1), + cast::reinterpret_cast::<@mut t, uint>(&x1), cast::reinterpret_cast::<*r, uint>(&ptr::addr_of(&(x1.r)))); - let x2 = @t(Node{ - mut next: None, + let mut x2 = @mut t(Node{ + next: None, r: { let rs = r(i2p); debug!("r2 = %x", cast::reinterpret_cast::<*r, uint>(&ptr::addr_of(&rs))); - move rs + rs } }); debug!("x2 = %x, x2.r = %x", - cast::reinterpret_cast::<@t, uint>(&x2), + cast::reinterpret_cast::<@mut t, uint>(&x2), cast::reinterpret_cast::<*r, uint>(&ptr::addr_of(&(x2.r)))); x1.next = Some(x2); diff --git a/src/test/run-pass/resource-cycle2.rs b/src/test/run-pass/resource-cycle2.rs index eea5c43bb9955..cf5f36916a041 100644 --- a/src/test/run-pass/resource-cycle2.rs +++ b/src/test/run-pass/resource-cycle2.rs @@ -37,7 +37,7 @@ fn r(v: U) -> r { enum t = Node; struct Node { - mut next: Option<@t>, + next: Option<@mut t>, r: r } @@ -45,20 +45,20 @@ pub fn main() { unsafe { let i1 = ~0xA; let i1p = cast::reinterpret_cast(&i1); - cast::forget(move i1); + cast::forget(i1); let i2 = ~0xA; let i2p = cast::reinterpret_cast(&i2); - cast::forget(move i2); + cast::forget(i2); let u1 = U {a: 0xB, b: 0xC, c: i1p}; let u2 = U {a: 0xB, b: 0xC, c: i2p}; - let x1 = @t(Node { - mut next: None, + let x1 = @mut t(Node { + next: None, r: r(u1) }); - let x2 = @t(Node { - mut next: None, + let x2 = @mut t(Node { + next: None, r: r(u2) }); x1.next = Some(x2); diff --git a/src/test/run-pass/resource-cycle3.rs b/src/test/run-pass/resource-cycle3.rs index 544d82e799544..4cd3df0f87f90 100644 --- a/src/test/run-pass/resource-cycle3.rs +++ b/src/test/run-pass/resource-cycle3.rs @@ -46,7 +46,7 @@ fn r(v: U, w: int, _x: *int) -> R { enum t = Node; struct Node { - mut next: Option<@t>, + next: Option<@mut t>, r: R } @@ -54,20 +54,20 @@ pub fn main() { unsafe { let i1 = ~0xA; let i1p = cast::reinterpret_cast(&i1); - cast::forget(move i1); + cast::forget(i1); let i2 = ~0xA; let i2p = cast::reinterpret_cast(&i2); - cast::forget(move i2); + cast::forget(i2); let u1 = U {a: 0xB, b: 0xC, c: i1p}; let u2 = U {a: 0xB, b: 0xC, c: i2p}; - let x1 = @t(Node{ - mut next: None, + let x1 = @mut t(Node{ + next: None, r: r(u1, 42, i1p) }); - let x2 = @t(Node{ - mut next: None, + let x2 = @mut t(Node{ + next: None, r: r(u2, 42, i2p) }); x1.next = Some(x2); diff --git a/src/test/run-pass/resource-destruct.rs b/src/test/run-pass/resource-destruct.rs index 7b5456e21898c..3dc4ca7bd61dc 100644 --- a/src/test/run-pass/resource-destruct.rs +++ b/src/test/run-pass/resource-destruct.rs @@ -30,7 +30,7 @@ fn shrinky_pointer(i: @@mut int) -> shrinky_pointer { pub fn main() { let my_total = @@mut 10; - { let pt = move shrinky_pointer(my_total); assert (pt.look_at() == 10); } + { let pt = shrinky_pointer(my_total); assert (pt.look_at() == 10); } log(error, fmt!("my_total = %d", **my_total)); assert (**my_total == 9); } diff --git a/src/test/run-pass/resource-generic.rs b/src/test/run-pass/resource-generic.rs index 17ce27fa60ad1..d32a60ee4f84b 100644 --- a/src/test/run-pass/resource-generic.rs +++ b/src/test/run-pass/resource-generic.rs @@ -9,7 +9,6 @@ // except according to those terms. // xfail-fast -#[legacy_modes]; struct Arg {val: T, fin: extern fn(T)} @@ -17,13 +16,13 @@ struct finish { arg: Arg } -impl Drop for finish { +impl Drop for finish { fn finalize(&self) { (self.arg.fin)(self.arg.val); } } -fn finish(arg: Arg) -> finish { +fn finish(arg: Arg) -> finish { finish { arg: arg } @@ -31,8 +30,8 @@ fn finish(arg: Arg) -> finish { pub fn main() { let box = @mut 10; - fn dec_box(&&i: @mut int) { *i -= 1; } + fn dec_box(i: @mut int) { *i -= 1; } - { let _i = move finish(Arg{val: box, fin: dec_box}); } + { let _i = finish(Arg{val: box, fin: dec_box}); } assert (*box == 9); } diff --git a/src/test/run-pass/ret-break-cont-in-block.rs b/src/test/run-pass/ret-break-cont-in-block.rs index 97fa11bef1b2a..2f0f9e5ae6ad7 100644 --- a/src/test/run-pass/ret-break-cont-in-block.rs +++ b/src/test/run-pass/ret-break-cont-in-block.rs @@ -9,22 +9,21 @@ // except according to those terms. // xfail-fast -#[legacy_modes]; use cmp::Eq; -fn iter(v: ~[T], it: fn(T) -> bool) { +fn iter(v: ~[T], it: fn(&T) -> bool) { let mut i = 0u, l = v.len(); while i < l { - if !it(v[i]) { break; } + if !it(&v[i]) { break; } i += 1u; } } -fn find_pos(n: T, h: ~[T]) -> Option { +fn find_pos(n: T, h: ~[T]) -> Option { let mut i = 0u; for iter(copy h) |e| { - if e == n { return Some(i); } + if *e == n { return Some(i); } i += 1u; } None @@ -33,9 +32,9 @@ fn find_pos(n: T, h: ~[T]) -> Option { fn bail_deep(x: ~[~[bool]]) { let mut seen = false; for iter(copy x) |x| { - for iter(copy x) |x| { + for iter(copy *x) |x| { assert !seen; - if x { seen = true; return; } + if *x { seen = true; return; } } } assert !seen; @@ -44,7 +43,7 @@ fn bail_deep(x: ~[~[bool]]) { fn ret_deep() -> ~str { for iter(~[1, 2]) |e| { for iter(~[3, 4]) |x| { - if e + x > 4 { return ~"hi"; } + if *e + *x > 4 { return ~"hi"; } } } return ~"bye"; diff --git a/src/test/run-pass/ret-none.rs b/src/test/run-pass/ret-none.rs index 1df01a5e57933..d493f23ba8400 100644 --- a/src/test/run-pass/ret-none.rs +++ b/src/test/run-pass/ret-none.rs @@ -12,6 +12,6 @@ enum option { none, some(T), } -fn f() -> option { return none; } +fn f() -> option { return none; } pub fn main() { f::(); } diff --git a/src/test/run-pass/rt-sched-1.rs b/src/test/run-pass/rt-sched-1.rs index badd9632cc8a3..ca37a6663fd69 100644 --- a/src/test/run-pass/rt-sched-1.rs +++ b/src/test/run-pass/rt-sched-1.rs @@ -10,7 +10,7 @@ // Tests of the runtime's scheduler interface -use core::pipes::*; +use core::comm::*; type sched_id = int; type task_id = *libc::c_void; @@ -46,7 +46,7 @@ pub fn main() { }; let fptr = cast::reinterpret_cast(&ptr::addr_of(&f)); rustrt::start_task(new_task_id, fptr); - cast::forget(move f); + cast::forget(f); po.recv(); } } diff --git a/src/test/run-pass/select-macro.rs b/src/test/run-pass/select-macro.rs index 45df9cfa610c9..d576875be10d8 100644 --- a/src/test/run-pass/select-macro.rs +++ b/src/test/run-pass/select-macro.rs @@ -27,18 +27,18 @@ macro_rules! select_if ( $count:expr, $port:path => [ $(type_this $message:path$(($(x $x: ident),+))dont_type_this* - -> $next:ident => { move $e:expr }),+ + -> $next:ident => { $e:expr }),+ ] $(, $ports:path => [ $(type_this $messages:path$(($(x $xs: ident),+))dont_type_this* - -> $nexts:ident => { move $es:expr }),+ + -> $nexts:ident => { $es:expr }),+ ] )* } => { if $index == $count { - match move pipes::try_recv($port) { - $(Some($message($($(move $x,)+)* move next)) => { - let $next = move next; - move $e + match pipes::try_recv($port) { + $(Some($message($($($x,)+)* next)) => { + let $next = next; + $e })+ _ => fail!() } @@ -48,7 +48,7 @@ macro_rules! select_if ( $count + 1 $(, $ports => [ $(type_this $messages$(($(x $xs),+))dont_type_this* - -> $nexts => { move $es }),+ + -> $nexts => { $es }),+ ])* ) } @@ -64,7 +64,7 @@ macro_rules! select ( } => { let index = pipes::selecti([$(($port).header()),+]); select_if!(index, 0 $(, $port => [ - $(type_this $message$(($(x $x),+))dont_type_this* -> $next => { move $e }),+ + $(type_this $message$(($(x $x),+))dont_type_this* -> $next => { $e }),+ ])+) } ) diff --git a/src/test/run-pass/send-iloop.rs b/src/test/run-pass/send-iloop.rs index f1b9c85a0ff1a..18f4fd27858ba 100644 --- a/src/test/run-pass/send-iloop.rs +++ b/src/test/run-pass/send-iloop.rs @@ -17,7 +17,7 @@ fn die() { fn iloop() { task::spawn(|| die() ); - let (p, c) = core::pipes::stream::<()>(); + let (p, c) = comm::stream::<()>(); loop { // Sending and receiving here because these actions yield, // at which point our child can kill us. diff --git a/src/test/run-pass/send-resource.rs b/src/test/run-pass/send-resource.rs index ac910232c16bf..6bda62be621d6 100644 --- a/src/test/run-pass/send-resource.rs +++ b/src/test/run-pass/send-resource.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use core::pipes::*; +use core::comm::*; struct test { f: int, diff --git a/src/test/run-pass/send-type-inference.rs b/src/test/run-pass/send-type-inference.rs index bf1ab6e07d2e5..0f924df8dc006 100644 --- a/src/test/run-pass/send-type-inference.rs +++ b/src/test/run-pass/send-type-inference.rs @@ -8,12 +8,12 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use core::pipes::*; +use core::comm::*; // tests that ctrl's type gets inferred properly type command = {key: K, val: V}; -fn cache_server(c: Chan>>) { +fn cache_server(c: Chan>>) { let (ctrl_port, ctrl_chan) = stream(); c.send(ctrl_chan); } diff --git a/src/test/run-pass/sendable-class.rs b/src/test/run-pass/sendable-class.rs index 19169c168c2cf..8ef0173dbd327 100644 --- a/src/test/run-pass/sendable-class.rs +++ b/src/test/run-pass/sendable-class.rs @@ -23,6 +23,6 @@ fn foo(i:int, j: char) -> foo { } pub fn main() { - let (_po, ch) = pipes::stream(); + let (_po, ch) = comm::stream(); ch.send(foo(42, 'c')); } diff --git a/src/test/run-pass/sendfn-generic-fn.rs b/src/test/run-pass/sendfn-generic-fn.rs index be4b609afab10..8ae976ccadec2 100644 --- a/src/test/run-pass/sendfn-generic-fn.rs +++ b/src/test/run-pass/sendfn-generic-fn.rs @@ -9,33 +9,32 @@ // except according to those terms. // xfail-fast -#[legacy_modes]; pub fn main() { test05(); } struct Pair { a: A, b: B } -fn make_generic_record(a: A, b: B) -> Pair { +fn make_generic_record(a: A, b: B) -> Pair { return Pair {a: a, b: b}; } -fn test05_start(&&f: fn~(&&v: float, &&v: ~str) -> Pair) { - let p = f(22.22f, ~"Hi"); +fn test05_start(f: &~fn(v: float, v: ~str) -> Pair) { + let p = (*f)(22.22f, ~"Hi"); log(debug, copy p); assert p.a == 22.22f; assert p.b == ~"Hi"; - let q = f(44.44f, ~"Ho"); + let q = (*f)(44.44f, ~"Ho"); log(debug, copy q); assert q.a == 44.44f; assert q.b == ~"Ho"; } -fn spawn(f: extern fn(fn~(A,B)->Pair)) { +fn spawn(f: extern fn(&~fn(A,B)->Pair)) { let arg = fn~(a: A, b: B) -> Pair { return make_generic_record(a, b); }; - task::spawn(|| f(arg) ); + task::spawn(|| f(&arg) ); } fn test05() { diff --git a/src/test/run-pass/sendfn-is-a-block.rs b/src/test/run-pass/sendfn-is-a-block.rs index 2d995191785d2..099ba326300ee 100644 --- a/src/test/run-pass/sendfn-is-a-block.rs +++ b/src/test/run-pass/sendfn-is-a-block.rs @@ -9,7 +9,6 @@ // except according to those terms. // xfail-fast -#[legacy_modes]; fn test(f: fn(uint) -> uint) -> uint { return f(22u); diff --git a/src/test/run-pass/sendfn-spawn-with-fn-arg.rs b/src/test/run-pass/sendfn-spawn-with-fn-arg.rs index d86dc4d56d7dd..fce0889e0a9b8 100644 --- a/src/test/run-pass/sendfn-spawn-with-fn-arg.rs +++ b/src/test/run-pass/sendfn-spawn-with-fn-arg.rs @@ -20,7 +20,7 @@ fn test05() { log(error, *three + n); // will copy x into the closure assert(*three == 3); }; - task::spawn(fn~(move fn_to_send) { + task::spawn(fn~() { test05_start(fn_to_send); }); } diff --git a/src/test/run-pass/spawn-types.rs b/src/test/run-pass/spawn-types.rs index 6090f2eb71cd7..4111b50549055 100644 --- a/src/test/run-pass/spawn-types.rs +++ b/src/test/run-pass/spawn-types.rs @@ -14,7 +14,7 @@ Arnold. */ -use core::pipes::*; +use core::comm::*; type ctx = Chan; diff --git a/src/test/run-pass/static-impl.rs b/src/test/run-pass/static-impl.rs index 870059d1edc52..9d7c2fe446d32 100644 --- a/src/test/run-pass/static-impl.rs +++ b/src/test/run-pass/static-impl.rs @@ -9,7 +9,6 @@ // except according to those terms. // xfail-fast -#[legacy_modes]; pub trait plus { fn plus() -> int; @@ -17,12 +16,12 @@ pub trait plus { mod a { use plus; - pub impl uint: plus { fn plus() -> int { self as int + 20 } } + pub impl plus for uint { fn plus() -> int { self as int + 20 } } } mod b { use plus; - pub impl ~str: plus { fn plus() -> int { 200 } } + pub impl plus for ~str { fn plus() -> int { 200 } } } trait uint_utils { @@ -40,16 +39,16 @@ impl uint_utils for uint { trait vec_utils { fn length_() -> uint; - fn iter_(f: fn(T)); - fn map_(f: fn(T) -> U) -> ~[U]; + fn iter_(f: fn(&T)); + fn map_(f: fn(&T) -> U) -> ~[U]; } impl vec_utils for ~[T] { fn length_() -> uint { vec::len(self) } - fn iter_(f: fn(T)) { for self.each |x| { f(*x); } } - fn map_(f: fn(T) -> U) -> ~[U] { + fn iter_(f: fn(&T)) { for self.each |x| { f(x); } } + fn map_(f: fn(&T) -> U) -> ~[U] { let mut r = ~[]; - for self.each |elt| { r += ~[f(*elt)]; } + for self.each |elt| { r += ~[f(elt)]; } r } } @@ -59,8 +58,8 @@ pub fn main() { assert (~"hi").plus() == 200; assert (~[1]).length_().str() == ~"1"; - assert (~[3, 4]).map_(|a| a + 4 )[0] == 7; - assert (~[3, 4]).map_::(|a| a as uint + 4u )[0] == 7u; + assert (~[3, 4]).map_(|a| *a + 4 )[0] == 7; + assert (~[3, 4]).map_::(|a| *a as uint + 4u )[0] == 7u; let mut x = 0u; 10u.multi(|_n| x += 2u ); assert x == 20u; 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 328a937b441fe..9a9533d7c8a3b 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 @@ -12,11 +12,11 @@ trait Deserializer { fn read_int() -> int; } -trait Deserializable { +trait Deserializable { static fn deserialize(d: &D) -> Self; } -impl Deserializable for int { +impl Deserializable for int { static 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 3402da6c55c9d..d9461c48be8a8 100644 --- a/src/test/run-pass/static-method-test.rs +++ b/src/test/run-pass/static-method-test.rs @@ -17,19 +17,19 @@ trait bool_like { static fn select(b: Self, +x1: A, +x2: A) -> A; } -fn andand(x1: T, x2: T) -> T { +fn andand(x1: T, x2: T) -> T { bool_like::select(x1, x2, x1) } impl bool_like for bool { static fn select(&&b: bool, +x1: A, +x2: A) -> A { - if b { move x1 } else { move x2 } + if b { x1 } else { x2 } } } impl bool_like for int { static fn select(&&b: int, +x1: A, +x2: A) -> A { - if b != 0 { move x1 } else { move x2 } + if b != 0 { x1 } else { x2 } } } @@ -70,7 +70,7 @@ fn map, U, BU: buildable> } } -fn seq_range>(lo: uint, hi: uint) -> BT { +fn seq_range>(lo: uint, hi: uint) -> BT { do buildable::build_sized(hi-lo) |push| { for uint::range(lo, hi) |i| { push(i as int); diff --git a/src/test/run-pass/static-methods-in-traits2.rs b/src/test/run-pass/static-methods-in-traits2.rs index 8c61f60eaac2a..b4c28fd52a64c 100644 --- a/src/test/run-pass/static-methods-in-traits2.rs +++ b/src/test/run-pass/static-methods-in-traits2.rs @@ -2,7 +2,7 @@ pub trait Number: NumConv { static pure fn from(n: T) -> Self; } -pub impl float: Number { +pub impl Number for float { static pure fn from(n: T) -> float { n.to_float() } } @@ -10,7 +10,7 @@ pub trait NumConv { pure fn to_float(&self) -> float; } -pub impl float: NumConv { +pub impl NumConv for float { pure fn to_float(&self) -> float { *self } } diff --git a/src/test/run-pass/swap-overlapping.rs b/src/test/run-pass/swap-overlapping.rs new file mode 100644 index 0000000000000..90b2ceef71a76 --- /dev/null +++ b/src/test/run-pass/swap-overlapping.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. + +// Issue #5041 - avoid overlapping memcpy when src and dest of a swap are the same + +pub fn main() { + let mut test = TestDescAndFn { + desc: TestDesc { + name: DynTestName(~"test"), + should_fail: false + }, + testfn: DynTestFn(|| ()), + }; + do_swap(&mut test); +} + +fn do_swap(test: &mut TestDescAndFn) { + *test <-> *test; +} + +pub enum TestName { + DynTestName(~str) +} + +pub enum TestFn { + DynTestFn(~fn()), + DynBenchFn(~fn(&mut int)) +} + +pub struct TestDesc { + name: TestName, + should_fail: bool +} + +pub struct TestDescAndFn { + desc: TestDesc, + testfn: TestFn, +} diff --git a/src/test/run-pass/task-comm-0.rs b/src/test/run-pass/task-comm-0.rs index b66f295e1bad8..f260e571b42ac 100644 --- a/src/test/run-pass/task-comm-0.rs +++ b/src/test/run-pass/task-comm-0.rs @@ -13,8 +13,8 @@ extern mod std; -use pipes::Chan; -use pipes::Port; +use comm::Chan; +use comm::Port; pub fn main() { test05(); } @@ -28,8 +28,8 @@ fn test05_start(ch : Chan) { } fn test05() { - let (po, ch) = pipes::stream(); - task::spawn(|move ch| test05_start(ch) ); + let (po, ch) = comm::stream(); + task::spawn(|| test05_start(ch) ); let mut value = po.recv(); log(error, value); value = po.recv(); diff --git a/src/test/run-pass/task-comm-10.rs b/src/test/run-pass/task-comm-10.rs index a5d55fd823bcf..21c141d18a2d8 100644 --- a/src/test/run-pass/task-comm-10.rs +++ b/src/test/run-pass/task-comm-10.rs @@ -9,13 +9,12 @@ // except according to those terms. // xfail-fast -#[legacy_modes]; extern mod std; -fn start(c: pipes::Chan>) { - let (p, ch) = pipes::stream(); - c.send(move ch); +fn start(c: &comm::Chan>) { + let (p, ch) = comm::stream(); + c.send(ch); let mut a; let mut b; @@ -24,12 +23,12 @@ fn start(c: pipes::Chan>) { log(error, a); b = p.recv(); assert b == ~"B"; - log(error, move b); + log(error, b); } pub fn main() { - let (p, ch) = pipes::stream(); - let child = task::spawn(|move ch| start(ch) ); + let (p, ch) = comm::stream(); + let child = task::spawn(|| start(&ch) ); let c = p.recv(); c.send(~"A"); diff --git a/src/test/run-pass/task-comm-11.rs b/src/test/run-pass/task-comm-11.rs index 498b0b7423868..b2012fbd2dd5e 100644 --- a/src/test/run-pass/task-comm-11.rs +++ b/src/test/run-pass/task-comm-11.rs @@ -9,17 +9,16 @@ // except according to those terms. // xfail-fast -#[legacy_modes]; extern mod std; -fn start(c: pipes::Chan>) { - let (p, ch) = pipes::stream(); - c.send(move ch); +fn start(c: &comm::Chan>) { + let (p, ch) = comm::stream(); + c.send(ch); } pub fn main() { - let (p, ch) = pipes::stream(); - let child = task::spawn(|move ch| start(ch) ); + let (p, ch) = comm::stream(); + let child = task::spawn(|| start(&ch) ); let c = p.recv(); } diff --git a/src/test/run-pass/task-comm-12.rs b/src/test/run-pass/task-comm-12.rs index d32e9454f533b..9f23ab1c9dfa6 100644 --- a/src/test/run-pass/task-comm-12.rs +++ b/src/test/run-pass/task-comm-12.rs @@ -17,7 +17,7 @@ fn start(&&task_number: int) { debug!("Started / Finished task."); } fn test00() { let i: int = 0; let mut result = None; - do task::task().future_result(|+r| { result = Some(move r); }).spawn { + do task::task().future_result(|+r| { result = Some(r); }).spawn { start(i) } @@ -29,7 +29,7 @@ fn test00() { } // Try joining tasks that have already finished. - option::unwrap(move result).recv(); + option::unwrap(result).recv(); debug!("Joined task."); } diff --git a/src/test/run-pass/task-comm-13.rs b/src/test/run-pass/task-comm-13.rs index c52facf230be9..a246f1f4af2b1 100644 --- a/src/test/run-pass/task-comm-13.rs +++ b/src/test/run-pass/task-comm-13.rs @@ -12,16 +12,15 @@ #[legacy_modes]; extern mod std; -use pipes::send; -fn start(c: pipes::Chan, start: int, number_of_messages: int) { +fn start(c: comm::Chan, start: int, number_of_messages: int) { let mut i: int = 0; while i < number_of_messages { c.send(start + i); i += 1; } } pub fn main() { debug!("Check that we don't deadlock."); - let (p, ch) = pipes::stream(); - task::try(|move ch| start(ch, 0, 10) ); + let (p, ch) = comm::stream(); + task::try(|| start(ch, 0, 10) ); debug!("Joined task"); } diff --git a/src/test/run-pass/task-comm-14.rs b/src/test/run-pass/task-comm-14.rs index dbf8c03493550..053499ee5ed1f 100644 --- a/src/test/run-pass/task-comm-14.rs +++ b/src/test/run-pass/task-comm-14.rs @@ -9,18 +9,17 @@ // except according to those terms. // xfail-fast -#[legacy_modes]; pub fn main() { - let po = pipes::PortSet(); + let po = comm::PortSet(); // Spawn 10 tasks each sending us back one int. let mut i = 10; while (i > 0) { log(debug, i); - let (p, ch) = pipes::stream(); - po.add(move p); - task::spawn({let i = i; |move ch| child(i, ch)}); + let (p, ch) = comm::stream(); + po.add(p); + task::spawn({let i = i; || child(i, &ch)}); i = i - 1; } @@ -37,7 +36,7 @@ pub fn main() { debug!("main thread exiting"); } -fn child(x: int, ch: pipes::Chan) { +fn child(x: int, ch: &comm::Chan) { log(debug, x); ch.send(x); } diff --git a/src/test/run-pass/task-comm-15.rs b/src/test/run-pass/task-comm-15.rs index c65e10d36b7e6..308627720622c 100644 --- a/src/test/run-pass/task-comm-15.rs +++ b/src/test/run-pass/task-comm-15.rs @@ -10,11 +10,10 @@ // xfail-fast // xfail-win32 -#[legacy_modes]; extern mod std; -fn start(c: pipes::Chan, i0: int) { +fn start(c: &comm::Chan, i0: int) { let mut i = i0; while i > 0 { c.send(0); @@ -27,7 +26,7 @@ pub fn main() { // is likely to terminate before the child completes, so from // the child's point of view the receiver may die. We should // drop messages on the floor in this case, and not crash! - let (p, ch) = pipes::stream(); - task::spawn(|move ch| start(ch, 10)); + let (p, ch) = comm::stream(); + task::spawn(|| start(&ch, 10)); p.recv(); } diff --git a/src/test/run-pass/task-comm-16.rs b/src/test/run-pass/task-comm-16.rs index afc9290b62db7..e2ac5623db3d9 100644 --- a/src/test/run-pass/task-comm-16.rs +++ b/src/test/run-pass/task-comm-16.rs @@ -10,16 +10,11 @@ // except according to those terms. -use pipes::send; -use pipes::Port; -use pipes::recv; -use pipes::Chan; - // Tests of ports and channels on various types fn test_rec() { struct R {val0: int, val1: u8, val2: char} - let (po, ch) = pipes::stream(); + let (po, ch) = comm::stream(); let r0: R = R {val0: 0, val1: 1u8, val2: '2'}; ch.send(r0); let mut r1: R; @@ -30,7 +25,7 @@ fn test_rec() { } fn test_vec() { - let (po, ch) = pipes::stream(); + let (po, ch) = comm::stream(); let v0: ~[int] = ~[0, 1, 2]; ch.send(v0); let v1 = po.recv(); @@ -40,7 +35,7 @@ fn test_vec() { } fn test_str() { - let (po, ch) = pipes::stream(); + let (po, ch) = comm::stream(); let s0 = ~"test"; ch.send(s0); let s1 = po.recv(); @@ -84,7 +79,7 @@ impl cmp::Eq for t { } fn test_tag() { - let (po, ch) = pipes::stream(); + let (po, ch) = comm::stream(); ch.send(tag1); ch.send(tag2(10)); ch.send(tag3(10, 11u8, 'A')); @@ -98,9 +93,9 @@ fn test_tag() { } fn test_chan() { - let (po, ch) = pipes::stream(); - let (po0, ch0) = pipes::stream(); - ch.send(move ch0); + let (po, ch) = comm::stream(); + let (po0, ch0) = comm::stream(); + ch.send(ch0); let ch1 = po.recv(); // Does the transmitted channel still work? diff --git a/src/test/run-pass/task-comm-3.rs b/src/test/run-pass/task-comm-3.rs index 97280d37c6384..9ef76e06d7e83 100644 --- a/src/test/run-pass/task-comm-3.rs +++ b/src/test/run-pass/task-comm-3.rs @@ -9,16 +9,13 @@ // except according to those terms. // xfail-fast -#[legacy_modes]; extern mod std; -use pipes::Chan; -use pipes::send; -use pipes::recv; +use core::comm::Chan; pub fn main() { debug!("===== WITHOUT THREADS ====="); test00(); } -fn test00_start(ch: Chan, message: int, count: int) { +fn test00_start(ch: &Chan, message: int, count: int) { debug!("Starting test00_start"); let mut i: int = 0; while i < count { @@ -35,7 +32,7 @@ fn test00() { debug!("Creating tasks"); - let po = pipes::PortSet(); + let po = comm::PortSet(); let mut i: int = 0; @@ -44,10 +41,10 @@ fn test00() { while i < number_of_tasks { let ch = po.chan(); task::task().future_result(|+r| { - results.push(move r); + results.push(r); }).spawn({ let i = i; - |move ch| test00_start(ch, i, number_of_messages) + || test00_start(&ch, i, number_of_messages) }); i = i + 1; } diff --git a/src/test/run-pass/task-comm-4.rs b/src/test/run-pass/task-comm-4.rs index d7997d9324825..dc4dc27229c56 100644 --- a/src/test/run-pass/task-comm-4.rs +++ b/src/test/run-pass/task-comm-4.rs @@ -8,14 +8,12 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use pipes::send; - pub fn main() { test00(); } fn test00() { let mut r: int = 0; let mut sum: int = 0; - let (p, c) = pipes::stream(); + let (p, c) = comm::stream(); c.send(1); c.send(2); c.send(3); diff --git a/src/test/run-pass/task-comm-5.rs b/src/test/run-pass/task-comm-5.rs index f8f19d804c8ed..0256c1cbb8754 100644 --- a/src/test/run-pass/task-comm-5.rs +++ b/src/test/run-pass/task-comm-5.rs @@ -15,7 +15,7 @@ pub fn main() { test00(); } fn test00() { let r: int = 0; let mut sum: int = 0; - let (p, c) = pipes::stream(); + let (p, c) = comm::stream(); let number_of_messages: int = 1000; let mut i: int = 0; while i < number_of_messages { c.send(i + 0); i += 1; } diff --git a/src/test/run-pass/task-comm-6.rs b/src/test/run-pass/task-comm-6.rs index 5d19075a71ea0..c18090ea45f54 100644 --- a/src/test/run-pass/task-comm-6.rs +++ b/src/test/run-pass/task-comm-6.rs @@ -8,16 +8,14 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use pipes::send; -use pipes::Chan; -use pipes::recv; +use core::comm::Chan; pub fn main() { test00(); } fn test00() { let mut r: int = 0; let mut sum: int = 0; - let p = pipes::PortSet(); + let p = comm::PortSet(); let c0 = p.chan(); let c1 = p.chan(); let c2 = p.chan(); diff --git a/src/test/run-pass/task-comm-7.rs b/src/test/run-pass/task-comm-7.rs index 5ebd191944b61..21eb93e8d09b9 100644 --- a/src/test/run-pass/task-comm-7.rs +++ b/src/test/run-pass/task-comm-7.rs @@ -15,7 +15,7 @@ extern mod std; pub fn main() { test00(); } -fn test00_start(c: pipes::Chan, start: int, number_of_messages: int) { +fn test00_start(c: comm::Chan, start: int, number_of_messages: int) { let mut i: int = 0; while i < number_of_messages { c.send(start + i); i += 1; } } @@ -23,23 +23,23 @@ fn test00_start(c: pipes::Chan, start: int, number_of_messages: int) { fn test00() { let mut r: int = 0; let mut sum: int = 0; - let p = pipes::PortSet(); + let p = comm::PortSet(); let number_of_messages: int = 10; let c = p.chan(); - do task::spawn |move c| { + do task::spawn || { test00_start(c, number_of_messages * 0, number_of_messages); } let c = p.chan(); - do task::spawn |move c| { + do task::spawn || { test00_start(c, number_of_messages * 1, number_of_messages); } let c = p.chan(); - do task::spawn |move c| { + do task::spawn || { test00_start(c, number_of_messages * 2, number_of_messages); } let c = p.chan(); - do task::spawn |move c| { + do task::spawn || { test00_start(c, number_of_messages * 3, number_of_messages); } diff --git a/src/test/run-pass/task-comm-9.rs b/src/test/run-pass/task-comm-9.rs index ac259e7f7855b..4e54053865788 100644 --- a/src/test/run-pass/task-comm-9.rs +++ b/src/test/run-pass/task-comm-9.rs @@ -9,13 +9,12 @@ // except according to those terms. // xfail-fast -#[legacy_modes]; extern mod std; pub fn main() { test00(); } -fn test00_start(c: pipes::Chan, number_of_messages: int) { +fn test00_start(c: &comm::Chan, number_of_messages: int) { let mut i: int = 0; while i < number_of_messages { c.send(i + 0); i += 1; } } @@ -23,14 +22,14 @@ fn test00_start(c: pipes::Chan, number_of_messages: int) { fn test00() { let r: int = 0; let mut sum: int = 0; - let p = pipes::PortSet(); + let p = comm::PortSet(); let number_of_messages: int = 10; let ch = p.chan(); let mut result = None; - do task::task().future_result(|+r| { result = Some(move r); }).spawn - |move ch| { - test00_start(ch, number_of_messages); + do task::task().future_result(|+r| { result = Some(r); }).spawn + || { + test00_start(&ch, number_of_messages); } let mut i: int = 0; @@ -40,7 +39,7 @@ fn test00() { i += 1; } - option::unwrap(move result).recv(); + option::unwrap(result).recv(); assert (sum == number_of_messages * (number_of_messages - 1) / 2); } diff --git a/src/test/run-pass/task-comm-chan-nil.rs b/src/test/run-pass/task-comm-chan-nil.rs index cb62e2f87ee9a..db2ad2de61b95 100644 --- a/src/test/run-pass/task-comm-chan-nil.rs +++ b/src/test/run-pass/task-comm-chan-nil.rs @@ -16,7 +16,7 @@ extern mod std; // any size, but rustc currently can because they do have size. Whether // or not this is desirable I don't know, but here's a regression test. pub fn main() { - let (po, ch) = pipes::stream(); + let (po, ch) = comm::stream(); ch.send(()); let n: () = po.recv(); assert (n == ()); diff --git a/src/test/run-pass/task-killjoin-rsrc.rs b/src/test/run-pass/task-killjoin-rsrc.rs index ca60dfd3de009..b90c39ab34e50 100644 --- a/src/test/run-pass/task-killjoin-rsrc.rs +++ b/src/test/run-pass/task-killjoin-rsrc.rs @@ -13,7 +13,7 @@ // A port of task-killjoin to use a class with a dtor to manage // the join. -use core::pipes::*; +use core::comm::*; struct notify { ch: Chan, v: @mut bool, diff --git a/src/test/run-pass/task-spawn-move-and-copy.rs b/src/test/run-pass/task-spawn-move-and-copy.rs index d9b06627c80b7..805f8e8b1e24c 100644 --- a/src/test/run-pass/task-spawn-move-and-copy.rs +++ b/src/test/run-pass/task-spawn-move-and-copy.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use core::pipes::*; +use core::comm::*; pub fn main() { let (p, ch) = stream::(); diff --git a/src/test/run-pass/trait-bounds.rs b/src/test/run-pass/trait-bounds.rs index 2e093d6d63163..1775bba934c93 100644 --- a/src/test/run-pass/trait-bounds.rs +++ b/src/test/run-pass/trait-bounds.rs @@ -12,7 +12,7 @@ trait connection { fn read() -> int; } -trait connection_factory { +trait connection_factory { fn create() -> C; } diff --git a/src/test/run-pass/trait-cast.rs b/src/test/run-pass/trait-cast.rs index 62d1c00eea944..fb3756320f5c4 100644 --- a/src/test/run-pass/trait-cast.rs +++ b/src/test/run-pass/trait-cast.rs @@ -1,3 +1,6 @@ +// xfail-test +// Weird borrow check bug + // 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. @@ -10,20 +13,20 @@ // Test cyclic detector when using trait instances. -enum Tree = @TreeR; +enum Tree = @mut TreeR; struct TreeR { - mut left: Option, - mut right: Option, + left: Option, + right: Option, val: to_str } trait to_str { - fn to_str() -> ~str; + fn to_str(&self) -> ~str; } -impl to_str for Option { - fn to_str() -> ~str { - match self { +impl to_str for Option { + fn to_str(&self) -> ~str { + match *self { None => { ~"none" } Some(ref t) => { ~"some(" + t.to_str() + ~")" } } @@ -31,26 +34,26 @@ impl to_str for Option { } impl to_str for int { - fn to_str() -> ~str { int::str(self) } + fn to_str(&self) -> ~str { int::str(*self) } } impl to_str for Tree { - fn to_str() -> ~str { + fn to_str(&self) -> ~str { let l = self.left, r = self.right; - fmt!("[%s, %s, %s]", self.val.to_str(), - l.to_str(), r.to_str()) + let val = &self.val; + fmt!("[%s, %s, %s]", val.to_str(), l.to_str(), r.to_str()) } } -fn foo(x: T) -> ~str { x.to_str() } +fn foo(x: T) -> ~str { x.to_str() } pub fn main() { - let t1 = Tree(@TreeR{mut left: None, - mut right: None, - val: 1 as to_str }); - let t2 = Tree(@TreeR{mut left: Some(t1), - mut right: Some(t1), - val: 2 as to_str }); + let t1 = Tree(@mut TreeR{left: None, + right: None, + val: 1 as to_str }); + let t2 = Tree(@mut TreeR{left: Some(t1), + right: Some(t1), + val: 2 as to_str }); let expected = ~"[2, some([1, none, none]), some([1, none, none])]"; assert t2.to_str() == expected; assert foo(t2 as to_str) == expected; diff --git a/src/test/run-pass/trait-default-method-bound-subst.rs b/src/test/run-pass/trait-default-method-bound-subst.rs index 3f69a2e5d909b..19b6259860453 100644 --- a/src/test/run-pass/trait-default-method-bound-subst.rs +++ b/src/test/run-pass/trait-default-method-bound-subst.rs @@ -11,15 +11,15 @@ // xfail-test trait A { - fn g(x: T, y: U) -> (T, U) { (move x, move y) } + fn g(x: T, y: U) -> (T, U) { (x, y) } } impl A for int { } fn f>(i: V, j: T, k: U) -> (T, U) { - i.g(move j, move k) + i.g(j, k) } -fn main () { +pub fn main () { assert f(0, 1, 2) == (1, 2); } diff --git a/src/test/run-pass/trait-default-method-bound-subst2.rs b/src/test/run-pass/trait-default-method-bound-subst2.rs index fcb9f60d762c8..424ba02b6fb0a 100644 --- a/src/test/run-pass/trait-default-method-bound-subst2.rs +++ b/src/test/run-pass/trait-default-method-bound-subst2.rs @@ -11,15 +11,15 @@ // xfail-test trait A { - fn g(x: T) -> T { move x } + fn g(x: T) -> T { x } } impl A for int { } fn f>(i: V, j: T) -> T { - i.g(move j) + i.g(j) } -fn main () { +pub fn main () { assert f(0, 2) == 2; } diff --git a/src/test/run-pass/trait-default-method-bound-subst3.rs b/src/test/run-pass/trait-default-method-bound-subst3.rs index c89d4abe3dae7..f8f51312b188c 100644 --- a/src/test/run-pass/trait-default-method-bound-subst3.rs +++ b/src/test/run-pass/trait-default-method-bound-subst3.rs @@ -11,16 +11,16 @@ #[allow(default_methods)]; trait A { - fn g(x: T, y: T) -> (T, T) { (move x, move y) } + fn g(x: T, y: T) -> (T, T) { (x, y) } } impl A for int { } fn f(i: V, j: T, k: T) -> (T, T) { - i.g(move j, move k) + i.g(j, k) } -fn main () { +pub fn main () { assert f(0, 1, 2) == (1, 2); assert f(0, 1u8, 2u8) == (1u8, 2u8); } diff --git a/src/test/run-pass/trait-default-method-bound-subst4.rs b/src/test/run-pass/trait-default-method-bound-subst4.rs index 7a6dfa33a1ac4..0f994ca9402b0 100644 --- a/src/test/run-pass/trait-default-method-bound-subst4.rs +++ b/src/test/run-pass/trait-default-method-bound-subst4.rs @@ -11,16 +11,16 @@ #[allow(default_methods)]; trait A { - fn g(x: uint) -> uint { move x } + fn g(x: uint) -> uint { x } } impl A for int { } fn f>(i: V, j: uint) -> uint { - i.g(move j) + i.g(j) } -fn main () { +pub fn main () { assert f::(0, 2u) == 2u; assert f::(0, 2u) == 2u; } diff --git a/src/test/run-pass/trait-default-method-bound.rs b/src/test/run-pass/trait-default-method-bound.rs index b28884e5fbc7e..be50b4340553c 100644 --- a/src/test/run-pass/trait-default-method-bound.rs +++ b/src/test/run-pass/trait-default-method-bound.rs @@ -16,10 +16,10 @@ trait A { impl A for int { } -fn f(i: T) { +fn f(i: T) { assert i.g() == 10; } -fn main () { +pub fn main () { f(0); } diff --git a/src/test/run-pass/trait-generic.rs b/src/test/run-pass/trait-generic.rs index 80b1b1eba39ef..1f32cc94de97d 100644 --- a/src/test/run-pass/trait-generic.rs +++ b/src/test/run-pass/trait-generic.rs @@ -9,7 +9,6 @@ // except according to those terms. // xfail-fast -#[legacy_modes]; trait to_str { fn to_str() -> ~str; @@ -25,12 +24,12 @@ impl to_str for () { } trait map { - fn map(f: fn(T) -> U) -> ~[U]; + fn map(f: fn(&T) -> U) -> ~[U]; } impl map for ~[T] { - fn map(f: fn(T) -> U) -> ~[U] { + fn map(f: fn(&T) -> U) -> ~[U] { let mut r = ~[]; - for self.each |x| { r += ~[f(*x)]; } + for self.each |x| { r += ~[f(x)]; } r } } @@ -38,7 +37,7 @@ impl map for ~[T] { fn foo>(x: T) -> ~[~str] { x.map(|_e| ~"hi" ) } -fn bar>(x: T) -> ~[~str] { +fn bar>(x: T) -> ~[~str] { x.map(|_e| _e.to_str() ) } diff --git a/src/test/run-pass/trait-inheritance-auto-xc-2.rs b/src/test/run-pass/trait-inheritance-auto-xc-2.rs index b8e060ee91431..c3333fa10ab17 100644 --- a/src/test/run-pass/trait-inheritance-auto-xc-2.rs +++ b/src/test/run-pass/trait-inheritance-auto-xc-2.rs @@ -18,9 +18,9 @@ use aux::{Foo, Bar, Baz, A}; // We want to extend all Foo, Bar, Bazes to Quuxes pub trait Quux: Foo Bar Baz { } -impl Quux for T { } +impl Quux for T { } -fn f(a: &T) { +fn f(a: &T) { assert a.f() == 10; assert a.g() == 20; assert a.h() == 30; diff --git a/src/test/run-pass/trait-inheritance-auto-xc.rs b/src/test/run-pass/trait-inheritance-auto-xc.rs index f0fa291f00c15..302076da7a221 100644 --- a/src/test/run-pass/trait-inheritance-auto-xc.rs +++ b/src/test/run-pass/trait-inheritance-auto-xc.rs @@ -21,7 +21,7 @@ impl Foo for A { fn f() -> int { 10 } } impl Bar for A { fn g() -> int { 20 } } impl Baz for A { fn h() -> int { 30 } } -fn f(a: &T) { +fn f(a: &T) { assert a.f() == 10; assert a.g() == 20; assert a.h() == 30; diff --git a/src/test/run-pass/trait-inheritance-auto.rs b/src/test/run-pass/trait-inheritance-auto.rs index 84e498c8ffd11..5d576193880e5 100644 --- a/src/test/run-pass/trait-inheritance-auto.rs +++ b/src/test/run-pass/trait-inheritance-auto.rs @@ -10,7 +10,7 @@ // Testing that this impl turns A into a Quux, because // A is already a Foo Bar Baz -impl Quux for T { } +impl Quux for T { } trait Foo { fn f() -> int; } trait Bar { fn g() -> int; } @@ -24,7 +24,7 @@ impl Foo for A { fn f() -> int { 10 } } impl Bar for A { fn g() -> int { 20 } } impl Baz for A { fn h() -> int { 30 } } -fn f(a: &T) { +fn f(a: &T) { assert a.f() == 10; assert a.g() == 20; assert a.h() == 30; diff --git a/src/test/run-pass/trait-inheritance-call-bound-inherited2.rs b/src/test/run-pass/trait-inheritance-call-bound-inherited2.rs index 45498996ba552..11a0918ba78c0 100644 --- a/src/test/run-pass/trait-inheritance-call-bound-inherited2.rs +++ b/src/test/run-pass/trait-inheritance-call-bound-inherited2.rs @@ -20,7 +20,7 @@ impl Baz for A { fn h() -> int { 30 } } // Call a function on Foo, given a T: Baz, // which is inherited via Bar -fn gg(a: &T) -> int { +fn gg(a: &T) -> int { a.f() } diff --git a/src/test/run-pass/trait-inheritance-diamond.rs b/src/test/run-pass/trait-inheritance-diamond.rs index 1c914ebabc0a2..1d6e482309178 100644 --- a/src/test/run-pass/trait-inheritance-diamond.rs +++ b/src/test/run-pass/trait-inheritance-diamond.rs @@ -22,7 +22,7 @@ impl B for S { fn b(&self) -> int { 20 } } impl C for S { fn c(&self) -> int { 30 } } impl D for S { fn d(&self) -> int { 40 } } -fn f(x: &T) { +fn f(x: &T) { assert x.a() == 10; assert x.b() == 20; assert x.c() == 30; diff --git a/src/test/run-pass/trait-inheritance-multiple-inheritors.rs b/src/test/run-pass/trait-inheritance-multiple-inheritors.rs index afcf5c87832ac..ad4d3ebc0b577 100644 --- a/src/test/run-pass/trait-inheritance-multiple-inheritors.rs +++ b/src/test/run-pass/trait-inheritance-multiple-inheritors.rs @@ -19,7 +19,7 @@ impl B for S { fn b(&self) -> int { 20 } } impl C for S { fn c(&self) -> int { 30 } } // Both B and C inherit from A -fn f(x: &T) { +fn f(x: &T) { assert x.a() == 10; assert x.b() == 20; assert x.c() == 30; diff --git a/src/test/run-pass/trait-inheritance-multiple-params.rs b/src/test/run-pass/trait-inheritance-multiple-params.rs index a91a40ce2212a..5b6a754488efb 100644 --- a/src/test/run-pass/trait-inheritance-multiple-params.rs +++ b/src/test/run-pass/trait-inheritance-multiple-params.rs @@ -19,7 +19,7 @@ impl B for S { fn b(&self) -> int { 20 } } impl C for S { fn c(&self) -> int { 30 } } // Multiple type params, multiple levels of inheritance -fn f(x: &X, y: &Y, z: &Z) { +fn f(x: &X, y: &Y, z: &Z) { assert x.a() == 10; assert y.a() == 10; assert y.b() == 20; diff --git a/src/test/run-pass/trait-inheritance-num2.rs b/src/test/run-pass/trait-inheritance-num2.rs index fb2969a839824..64b30d71e1dff 100644 --- a/src/test/run-pass/trait-inheritance-num2.rs +++ b/src/test/run-pass/trait-inheritance-num2.rs @@ -21,84 +21,84 @@ use std::cmp::FuzzyEq; pub trait TypeExt {} -pub impl u8: TypeExt {} -pub impl u16: TypeExt {} -pub impl u32: TypeExt {} -pub impl u64: TypeExt {} -pub impl uint: TypeExt {} +pub impl TypeExt for u8 {} +pub impl TypeExt for u16 {} +pub impl TypeExt for u32 {} +pub impl TypeExt for u64 {} +pub impl TypeExt for uint {} -pub impl i8: TypeExt {} -pub impl i16: TypeExt {} -pub impl i32: TypeExt {} -pub impl i64: TypeExt {} -pub impl int: TypeExt {} +pub impl TypeExt for i8 {} +pub impl TypeExt for i16 {} +pub impl TypeExt for i32 {} +pub impl TypeExt for i64 {} +pub impl TypeExt for int {} -pub impl f32: TypeExt {} -pub impl f64: TypeExt {} -pub impl float: TypeExt {} +pub impl TypeExt for f32 {} +pub impl TypeExt for f64 {} +pub impl TypeExt for float {} pub trait NumExt: TypeExt Eq Ord NumCast {} -pub impl u8: NumExt {} -pub impl u16: NumExt {} -pub impl u32: NumExt {} -pub impl u64: NumExt {} -pub impl uint: NumExt {} +pub impl NumExt for u8 {} +pub impl NumExt for u16 {} +pub impl NumExt for u32 {} +pub impl NumExt for u64 {} +pub impl NumExt for uint {} -pub impl i8: NumExt {} -pub impl i16: NumExt {} -pub impl i32: NumExt {} -pub impl i64: NumExt {} -pub impl int: NumExt {} +pub impl NumExt for i8 {} +pub impl NumExt for i16 {} +pub impl NumExt for i32 {} +pub impl NumExt for i64 {} +pub impl NumExt for int {} -pub impl f32: NumExt {} -pub impl f64: NumExt {} -pub impl float: NumExt {} +pub impl NumExt for f32 {} +pub impl NumExt for f64 {} +pub impl NumExt for float {} pub trait UnSignedExt: NumExt {} -pub impl u8: UnSignedExt {} -pub impl u16: UnSignedExt {} -pub impl u32: UnSignedExt {} -pub impl u64: UnSignedExt {} -pub impl uint: UnSignedExt {} +pub impl UnSignedExt for u8 {} +pub impl UnSignedExt for u16 {} +pub impl UnSignedExt for u32 {} +pub impl UnSignedExt for u64 {} +pub impl UnSignedExt for uint {} pub trait SignedExt: NumExt {} -pub impl i8: SignedExt {} -pub impl i16: SignedExt {} -pub impl i32: SignedExt {} -pub impl i64: SignedExt {} -pub impl int: SignedExt {} +pub impl SignedExt for i8 {} +pub impl SignedExt for i16 {} +pub impl SignedExt for i32 {} +pub impl SignedExt for i64 {} +pub impl SignedExt for int {} -pub impl f32: SignedExt {} -pub impl f64: SignedExt {} -pub impl float: SignedExt {} +pub impl SignedExt for f32 {} +pub impl SignedExt for f64 {} +pub impl SignedExt for float {} pub trait IntegerExt: NumExt {} -pub impl u8: IntegerExt {} -pub impl u16: IntegerExt {} -pub impl u32: IntegerExt {} -pub impl u64: IntegerExt {} -pub impl uint: IntegerExt {} +pub impl IntegerExt for u8 {} +pub impl IntegerExt for u16 {} +pub impl IntegerExt for u32 {} +pub impl IntegerExt for u64 {} +pub impl IntegerExt for uint {} -pub impl i8: IntegerExt {} -pub impl i16: IntegerExt {} -pub impl i32: IntegerExt {} -pub impl i64: IntegerExt {} -pub impl int: IntegerExt {} +pub impl IntegerExt for i8 {} +pub impl IntegerExt for i16 {} +pub impl IntegerExt for i32 {} +pub impl IntegerExt for i64 {} +pub impl IntegerExt for int {} pub trait FloatExt: NumExt FuzzyEq {} -pub impl f32: FloatExt {} -pub impl f64: FloatExt {} -pub impl float: FloatExt {} +pub impl FloatExt for f32 {} +pub impl FloatExt for f64 {} +pub impl FloatExt for float {} fn test_float_ext(n: T) { io::println(fmt!("%?", n < n)) } diff --git a/src/test/run-pass/trait-inheritance-num3.rs b/src/test/run-pass/trait-inheritance-num3.rs index 30cc54230223f..f184ab2741a1d 100644 --- a/src/test/run-pass/trait-inheritance-num3.rs +++ b/src/test/run-pass/trait-inheritance-num3.rs @@ -13,7 +13,7 @@ use num::NumCast::from; pub trait NumExt: Eq Ord NumCast {} -pub impl f32: NumExt {} +pub impl NumExt for f32 {} fn num_eq_one(n: T) { io::println(fmt!("%?", n == from(1))) } diff --git a/src/test/run-pass/trait-inheritance-num5.rs b/src/test/run-pass/trait-inheritance-num5.rs index c2b88c59f874f..692d50e541a97 100644 --- a/src/test/run-pass/trait-inheritance-num5.rs +++ b/src/test/run-pass/trait-inheritance-num5.rs @@ -13,8 +13,8 @@ use num::NumCast::from; pub trait NumExt: Eq NumCast {} -pub impl f32: NumExt {} -pub impl int: NumExt {} +pub impl NumExt for f32 {} +pub impl NumExt for int {} fn num_eq_one() -> T { from(1) diff --git a/src/test/run-pass/trait-inheritance-overloading-simple.rs b/src/test/run-pass/trait-inheritance-overloading-simple.rs index c41579e360374..b068d109ccfdb 100644 --- a/src/test/run-pass/trait-inheritance-overloading-simple.rs +++ b/src/test/run-pass/trait-inheritance-overloading-simple.rs @@ -19,7 +19,7 @@ impl Eq for MyInt { pure fn ne(&self, other: &MyInt) -> bool { !self.eq(other) } } -impl MyInt : MyNum; +impl MyNum for MyInt; fn f(x: T, y: T) -> bool { return x == y; 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 f779850787160..1d59f1fc19e13 100644 --- a/src/test/run-pass/trait-inheritance-overloading-xc-exe.rs +++ b/src/test/run-pass/trait-inheritance-overloading-xc-exe.rs @@ -14,7 +14,7 @@ extern mod trait_inheritance_overloading_xc; use trait_inheritance_overloading_xc::{MyNum, MyInt}; -fn f(x: T, y: T) -> (T, T, T) { +fn f(x: T, y: T) -> (T, T, T) { return (x + y, x - y, x * y); } diff --git a/src/test/run-pass/trait-inheritance-overloading.rs b/src/test/run-pass/trait-inheritance-overloading.rs index 56cdb5d31188d..08f3d41ddad9b 100644 --- a/src/test/run-pass/trait-inheritance-overloading.rs +++ b/src/test/run-pass/trait-inheritance-overloading.rs @@ -31,9 +31,9 @@ impl Eq for MyInt { pure fn ne(&self, other: &MyInt) -> bool { !self.eq(other) } } -impl MyInt : MyNum; +impl MyNum for MyInt; -fn f(x: T, y: T) -> (T, T, T) { +fn f(x: T, y: T) -> (T, T, T) { return (x + y, x - y, x * y); } diff --git a/src/test/run-pass/trait-inheritance-subst.rs b/src/test/run-pass/trait-inheritance-subst.rs index 03b7e37a7ad13..ea3e75f355185 100644 --- a/src/test/run-pass/trait-inheritance-subst.rs +++ b/src/test/run-pass/trait-inheritance-subst.rs @@ -20,7 +20,7 @@ impl Add for MyInt { pure fn add(other: &MyInt) -> MyInt { mi(self.val + other.val) } } -impl MyInt : MyNum; +impl MyNum for MyInt; fn f(x: T, y: T) -> T { return x.add(&y); diff --git a/src/test/run-pass/trait-inheritance-subst2.rs b/src/test/run-pass/trait-inheritance-subst2.rs index 378c78cfd921f..ab755da709969 100644 --- a/src/test/run-pass/trait-inheritance-subst2.rs +++ b/src/test/run-pass/trait-inheritance-subst2.rs @@ -30,7 +30,7 @@ impl Add for MyInt { fn add(other: &MyInt) -> MyInt { self.chomp(other) } } -impl MyInt : MyNum; +impl MyNum for MyInt; fn f(x: T, y: T) -> T { return x.add(&y).chomp(&y); diff --git a/src/test/run-pass/trait-inheritance-visibility.rs b/src/test/run-pass/trait-inheritance-visibility.rs index 6015eff8abe24..8518137bbb829 100644 --- a/src/test/run-pass/trait-inheritance-visibility.rs +++ b/src/test/run-pass/trait-inheritance-visibility.rs @@ -15,11 +15,11 @@ mod traits { } trait Quux: traits::Foo { } -impl Quux for T { } +impl Quux for T { } // Foo is not in scope but because Quux is we can still access // Foo's methods on a Quux bound typaram -fn f(x: &T) { +fn f(x: &T) { assert x.f() == 10; } diff --git a/src/test/run-pass/trait-inheritance2.rs b/src/test/run-pass/trait-inheritance2.rs index 3dee07194dd51..55a63e9099a93 100644 --- a/src/test/run-pass/trait-inheritance2.rs +++ b/src/test/run-pass/trait-inheritance2.rs @@ -19,9 +19,9 @@ struct A { x: int } impl Foo for A { fn f() -> int { 10 } } impl Bar for A { fn g() -> int { 20 } } impl Baz for A { fn h() -> int { 30 } } -impl A : Quux; +impl Quux for A; -fn f(a: &T) { +fn f(a: &T) { assert a.f() == 10; assert a.g() == 20; assert a.h() == 30; diff --git a/src/test/run-pass/trait-static-method-overwriting.rs b/src/test/run-pass/trait-static-method-overwriting.rs index 9538ea497ec9f..d416f3f6c910e 100644 --- a/src/test/run-pass/trait-static-method-overwriting.rs +++ b/src/test/run-pass/trait-static-method-overwriting.rs @@ -19,7 +19,7 @@ mod base { dummy: (), } - pub impl Foo : ::base::HasNew { + pub impl ::base::HasNew for Foo { static pure fn new() -> Foo { unsafe { io::println("Foo"); } Foo { dummy: () } @@ -30,7 +30,7 @@ mod base { dummy: (), } - pub impl Bar : ::base::HasNew { + pub impl ::base::HasNew for Bar { static pure fn new() -> Bar { unsafe { io::println("Bar"); } Bar { dummy: () } diff --git a/src/test/run-pass/trait-to-str.rs b/src/test/run-pass/trait-to-str.rs index 62f4ef89d693d..20e23c0fc58e7 100644 --- a/src/test/run-pass/trait-to-str.rs +++ b/src/test/run-pass/trait-to-str.rs @@ -24,7 +24,7 @@ impl to_str for int { fn to_str() -> ~str { int::str(self) } } -impl to_str for ~[T] { +impl to_str for ~[T] { fn to_str() -> ~str { ~"[" + str::connect(vec::map(self, |e| e.to_str() ), ~", ") + ~"]" } @@ -34,13 +34,13 @@ pub fn main() { assert 1.to_str() == ~"1"; assert (~[2, 3, 4]).to_str() == ~"[2, 3, 4]"; - fn indirect(x: T) -> ~str { + fn indirect(x: T) -> ~str { x.to_str() + ~"!" } assert indirect(~[10, 20]) == ~"[10, 20]!"; - fn indirect2(x: T) -> ~str { - indirect(move x) + fn indirect2(x: T) -> ~str { + indirect(x) } assert indirect2(~[1]) == ~"[1]!"; } diff --git a/src/test/run-pass/trivial-message.rs b/src/test/run-pass/trivial-message.rs index 21524d3fc5414..7800ebd7310ca 100644 --- a/src/test/run-pass/trivial-message.rs +++ b/src/test/run-pass/trivial-message.rs @@ -8,14 +8,12 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use pipes::{Port, Chan}; - /* This is about the simplest program that can successfully send a message. */ pub fn main() { - let (po, ch) = pipes::stream(); + let (po, ch) = comm::stream(); ch.send(42); let r = po.recv(); log(error, r); diff --git a/src/test/run-pass/type-param-constraints.rs b/src/test/run-pass/type-param-constraints.rs index 95920bcc967d3..bd6165806c273 100644 --- a/src/test/run-pass/type-param-constraints.rs +++ b/src/test/run-pass/type-param-constraints.rs @@ -9,11 +9,10 @@ // except according to those terms. // xfail-fast -#[legacy_modes]; fn p_foo(pinned: T) { } -fn s_foo(shared: T) { } -fn u_foo(unique: T) { } +fn s_foo(shared: T) { } +fn u_foo(unique: T) { } struct r { i: int, diff --git a/src/test/run-pass/type-use-i1-versus-i8.rs b/src/test/run-pass/type-use-i1-versus-i8.rs index 5f0414cdb7891..d16b2e3e996ce 100644 --- a/src/test/run-pass/type-use-i1-versus-i8.rs +++ b/src/test/run-pass/type-use-i1-versus-i8.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. // @@ -8,14 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use io::ReaderUtil; pub fn main() { let mut x: bool = false; // this line breaks it - vec::rusti::move_val_init(&mut x, false); - - let input = io::stdin(); - let line = input.read_line(); // use core's io again - - io::println(fmt!("got %?", line)); + private::intrinsics::move_val_init(&mut x, false); } diff --git a/src/test/run-pass/uniq-cc-generic.rs b/src/test/run-pass/uniq-cc-generic.rs index 8de91acd18542..dd86150b93bf9 100644 --- a/src/test/run-pass/uniq-cc-generic.rs +++ b/src/test/run-pass/uniq-cc-generic.rs @@ -18,7 +18,7 @@ struct Pointy { d : fn~() -> uint, } -fn make_uniq_closure(a: A) -> fn~() -> uint { +fn make_uniq_closure(a: A) -> fn~() -> uint { fn~() -> uint { ptr::addr_of(&a) as uint } } diff --git a/src/test/run-pass/unique-assign-generic.rs b/src/test/run-pass/unique-assign-generic.rs index 9ad5575be9dad..d6992e4623fd0 100644 --- a/src/test/run-pass/unique-assign-generic.rs +++ b/src/test/run-pass/unique-assign-generic.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -fn f(t: T) -> T { +fn f(t: T) -> T { let t1 = t; t1 } diff --git a/src/test/run-pass/unique-decl-move-temp.rs b/src/test/run-pass/unique-decl-move-temp.rs index fd4f428bd9d7a..96e91093d37a2 100644 --- a/src/test/run-pass/unique-decl-move-temp.rs +++ b/src/test/run-pass/unique-decl-move-temp.rs @@ -9,6 +9,6 @@ // except according to those terms. pub fn main() { - let i = move ~100; + let i = ~100; assert *i == 100; } diff --git a/src/test/run-pass/unique-decl-move.rs b/src/test/run-pass/unique-decl-move.rs index 27600c04e22f9..7723eafc035ee 100644 --- a/src/test/run-pass/unique-decl-move.rs +++ b/src/test/run-pass/unique-decl-move.rs @@ -10,6 +10,6 @@ pub fn main() { let i = ~100; - let j = move i; + let j = i; assert *j == 100; } diff --git a/src/test/run-pass/unique-fn-arg-move.rs b/src/test/run-pass/unique-fn-arg-move.rs index 61cee457b0cf0..12e9820361d77 100644 --- a/src/test/run-pass/unique-fn-arg-move.rs +++ b/src/test/run-pass/unique-fn-arg-move.rs @@ -14,5 +14,5 @@ fn f(-i: ~int) { pub fn main() { let i = ~100; - f(move i); + f(i); } diff --git a/src/test/run-pass/unique-generic-assign.rs b/src/test/run-pass/unique-generic-assign.rs index 5d3b550c4304a..ab92b10a3320b 100644 --- a/src/test/run-pass/unique-generic-assign.rs +++ b/src/test/run-pass/unique-generic-assign.rs @@ -10,7 +10,7 @@ // Issue #976 -fn f(x: ~T) { +fn f(x: ~T) { let _x2 = x; } pub fn main() { } diff --git a/src/test/run-pass/unique-kinds.rs b/src/test/run-pass/unique-kinds.rs index 0cffa14fb70e5..180ce716dcc9d 100644 --- a/src/test/run-pass/unique-kinds.rs +++ b/src/test/run-pass/unique-kinds.rs @@ -12,11 +12,11 @@ use cmp::Eq; fn sendable() { - fn f(i: T, j: T) { + fn f(i: T, j: T) { assert i == j; } - fn g(i: T, j: T) { + fn g(i: T, j: T) { assert i != j; } @@ -30,11 +30,11 @@ fn sendable() { fn copyable() { - fn f(i: T, j: T) { + fn f(i: T, j: T) { assert i == j; } - fn g(i: T, j: T) { + fn g(i: T, j: T) { assert i != j; } @@ -48,11 +48,11 @@ fn copyable() { fn noncopyable() { - fn f(i: T, j: T) { + fn f(i: T, j: T) { assert i == j; } - fn g(i: T, j: T) { + fn g(i: T, j: T) { assert i != j; } diff --git a/src/test/run-pass/unique-move-drop.rs b/src/test/run-pass/unique-move-drop.rs index fd86d5aa6fefa..5988a3e8658dc 100644 --- a/src/test/run-pass/unique-move-drop.rs +++ b/src/test/run-pass/unique-move-drop.rs @@ -11,6 +11,6 @@ pub fn main() { let i = ~100; let j = ~200; - let j = move i; + let j = i; assert *j == 100; } diff --git a/src/test/run-pass/unique-move-temp.rs b/src/test/run-pass/unique-move-temp.rs index eaa8a1cf7bd40..08a496987c0a6 100644 --- a/src/test/run-pass/unique-move-temp.rs +++ b/src/test/run-pass/unique-move-temp.rs @@ -10,6 +10,6 @@ pub fn main() { let mut i; - i = move ~100; + i = ~100; assert *i == 100; } diff --git a/src/test/run-pass/unique-move.rs b/src/test/run-pass/unique-move.rs index be0426edbe2e4..5e778d581d340 100644 --- a/src/test/run-pass/unique-move.rs +++ b/src/test/run-pass/unique-move.rs @@ -11,6 +11,6 @@ pub fn main() { let i = ~100; let mut j; - j = move i; + j = i; assert *j == 100; } diff --git a/src/test/run-pass/unique-send-2.rs b/src/test/run-pass/unique-send-2.rs index a5398e7407b37..7be6907a0c730 100644 --- a/src/test/run-pass/unique-send-2.rs +++ b/src/test/run-pass/unique-send-2.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use core::pipes::*; +use core::comm::*; fn child(c: &SharedChan<~uint>, i: uint) { c.send(~i); diff --git a/src/test/run-pass/unique-send.rs b/src/test/run-pass/unique-send.rs index 57b345c2d25ea..75fc71441f8f3 100644 --- a/src/test/run-pass/unique-send.rs +++ b/src/test/run-pass/unique-send.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use core::pipes::*; +use core::comm::*; pub fn main() { let (p, c) = stream(); diff --git a/src/test/run-pass/unreachable-code-1.rs b/src/test/run-pass/unreachable-code-1.rs index 8e900aa7ff3c4..9c658fdc25276 100644 --- a/src/test/run-pass/unreachable-code-1.rs +++ b/src/test/run-pass/unreachable-code-1.rs @@ -12,7 +12,7 @@ fn id(x: bool) -> bool { x } fn call_id() { - let c = move fail!(); + let c = fail!(); id(c); //~ WARNING unreachable statement } diff --git a/src/test/run-pass/unreachable-code.rs b/src/test/run-pass/unreachable-code.rs index 75b2bf090ba65..fa93dfd0fe135 100644 --- a/src/test/run-pass/unreachable-code.rs +++ b/src/test/run-pass/unreachable-code.rs @@ -12,7 +12,7 @@ fn id(x: bool) -> bool { x } fn call_id() { - let c = move fail!(); + let c = fail!(); id(c); } diff --git a/src/test/run-pass/unused-move-capture.rs b/src/test/run-pass/unused-move-capture.rs index 8f3a6f91d173f..665abe23ee893 100644 --- a/src/test/run-pass/unused-move-capture.rs +++ b/src/test/run-pass/unused-move-capture.rs @@ -10,6 +10,6 @@ pub fn main() { let x = ~1; - let lam_move = fn@(move x) { }; + let lam_move = fn@() { }; lam_move(); } diff --git a/src/test/run-pass/unused-move.rs b/src/test/run-pass/unused-move.rs index 785eb691459d6..69ce791c1a35a 100644 --- a/src/test/run-pass/unused-move.rs +++ b/src/test/run-pass/unused-move.rs @@ -15,5 +15,5 @@ pub fn main() { let y = ~1; - move y; + y; } diff --git a/src/test/run-pass/unwind-resource.rs b/src/test/run-pass/unwind-resource.rs index 62673fc134d19..2693a8d39423e 100644 --- a/src/test/run-pass/unwind-resource.rs +++ b/src/test/run-pass/unwind-resource.rs @@ -11,7 +11,7 @@ // xfail-win32 extern mod std; -use core::pipes::*; +use core::comm::*; struct complainer { c: SharedChan, @@ -33,7 +33,7 @@ fn complainer(c: SharedChan) -> complainer { } fn f(c: SharedChan) { - let _c = move complainer(c); + let _c = complainer(c); fail!(); } diff --git a/src/test/run-pass/unwind-resource2.rs b/src/test/run-pass/unwind-resource2.rs index 967ed727aa535..75ce797cfc842 100644 --- a/src/test/run-pass/unwind-resource2.rs +++ b/src/test/run-pass/unwind-resource2.rs @@ -26,7 +26,7 @@ fn complainer(c: @int) -> complainer { } fn f() { - let c = move complainer(@0); + let c = complainer(@0); fail!(); } diff --git a/src/test/run-pass/vec-position.rs b/src/test/run-pass/vec-position.rs new file mode 100644 index 0000000000000..fe186a78ed706 --- /dev/null +++ b/src/test/run-pass/vec-position.rs @@ -0,0 +1,16 @@ +// 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. + +pub fn main() { + let mut v = ~[1, 2, 3]; + assert v.position(|x| *x == 1) == Some(0); + assert v.position(|x| *x == 3) == Some(2); + assert v.position(|x| *x == 17) == None; +} diff --git a/src/test/run-pass/weird-exprs.rs b/src/test/run-pass/weird-exprs.rs index 28a5a5ca47b55..5b515ae543476 100644 --- a/src/test/run-pass/weird-exprs.rs +++ b/src/test/run-pass/weird-exprs.rs @@ -50,7 +50,7 @@ fn zombiejesus() { fn notsure() { let mut _x; let mut _y = (_x = 0) == (_x = 0); - let mut _z = (_x = move 0) < (_x = 0); + let mut _z = (_x = 0) < (_x = 0); let _a = (_x += 0) == (_x = 0); let _b = (_y <-> _z) == (_y <-> _z); } @@ -73,7 +73,7 @@ fn angrydome() { break; } } -fn evil_lincoln() { let evil = move debug!("lincoln"); } +fn evil_lincoln() { let evil = debug!("lincoln"); } pub fn main() { strange(); diff --git a/src/test/run-pass/while-loop-constraints-2.rs b/src/test/run-pass/while-loop-constraints-2.rs index 3d44cf2669b27..df5f5904793da 100644 --- a/src/test/run-pass/while-loop-constraints-2.rs +++ b/src/test/run-pass/while-loop-constraints-2.rs @@ -15,7 +15,7 @@ pub fn main() { let mut x: int; while z < 50 { z += 1; - while false { x = move y; y = z; } + while false { x = y; y = z; } log(debug, y); } assert (y == 42 && z == 50); diff --git a/src/test/run-pass/writealias.rs b/src/test/run-pass/writealias.rs index 2aa3bc30d07b8..c9c5ce0c928fd 100644 --- a/src/test/run-pass/writealias.rs +++ b/src/test/run-pass/writealias.rs @@ -12,12 +12,12 @@ // -*- rust -*- -struct Point {x: int, y: int, mut z: int} +struct Point {x: int, y: int, z: int} fn f(p: &mut Point) { p.z = 13; } pub fn main() { - let mut x: Point = Point {x: 10, y: 11, mut z: 12}; + let mut x: Point = Point {x: 10, y: 11, z: 12}; f(&mut x); assert (x.z == 13); } diff --git a/src/test/run-pass/yield.rs b/src/test/run-pass/yield.rs index d5c58bbd0fabf..16f43016b8e67 100644 --- a/src/test/run-pass/yield.rs +++ b/src/test/run-pass/yield.rs @@ -11,13 +11,13 @@ pub fn main() { let mut result = None; - task::task().future_result(|+r| { result = Some(move r); }).spawn(child); + task::task().future_result(|+r| { result = Some(r); }).spawn(child); error!("1"); task::yield(); error!("2"); task::yield(); error!("3"); - option::unwrap(move result).recv(); + option::unwrap(result).recv(); } fn child() { diff --git a/src/test/run-pass/yield1.rs b/src/test/run-pass/yield1.rs index 1f6170624346b..ae1271f64e4dc 100644 --- a/src/test/run-pass/yield1.rs +++ b/src/test/run-pass/yield1.rs @@ -11,10 +11,10 @@ pub fn main() { let mut result = None; - task::task().future_result(|+r| { result = Some(move r); }).spawn(child); + task::task().future_result(|+r| { result = Some(r); }).spawn(child); error!("1"); task::yield(); - option::unwrap(move result).recv(); + option::unwrap(result).recv(); } fn child() { error!("2"); }