]> git.lizzy.rs Git - rust.git/commitdiff
auto merge of #15727 : fhahn/rust/remove-some-unwraps, r=alexcrichton
authorbors <bors@rust-lang.org>
Fri, 18 Jul 2014 07:51:22 +0000 (07:51 +0000)
committerbors <bors@rust-lang.org>
Fri, 18 Jul 2014 07:51:22 +0000 (07:51 +0000)
When looking through the `btree` code, I stumbled over a couple of `unwraps` that could be avoided.

154 files changed:
man/rustc.1
mk/main.mk
src/compiletest/compiletest.rs
src/compiletest/runtest.rs
src/doc/complement-lang-faq.md
src/doc/guide-lifetimes.md
src/doc/guide-pointers.md
src/doc/guide-strings.md [new file with mode: 0644]
src/doc/intro.md
src/doc/rust.md
src/doc/tutorial.md
src/liballoc/boxed.rs
src/libcollections/slice.rs
src/libcollections/str.rs
src/libcollections/treemap.rs
src/libcollections/vec.rs
src/libdebug/repr.rs
src/libgetopts/lib.rs
src/libglob/lib.rs
src/libgraphviz/lib.rs
src/libgraphviz/maybe_owned_vec.rs
src/libnum/bigint.rs
src/libnum/integer.rs
src/libregex/parse.rs
src/libregex/re.rs
src/libregex/vm.rs
src/libregex_macros/lib.rs
src/librustc/back/link.rs
src/librustc/driver/config.rs
src/librustc/driver/driver.rs
src/librustc/driver/mod.rs
src/librustc/lint/builtin.rs
src/librustc/metadata/csearch.rs
src/librustc/metadata/decoder.rs
src/librustc/metadata/encoder.rs
src/librustc/metadata/filesearch.rs
src/librustc/metadata/tyencode.rs
src/librustc/middle/astencode.rs
src/librustc/middle/borrowck/mod.rs
src/librustc/middle/check_match.rs
src/librustc/middle/dataflow.rs
src/librustc/middle/dead.rs
src/librustc/middle/reachable.rs
src/librustc/middle/region.rs
src/librustc/middle/resolve.rs
src/librustc/middle/save/mod.rs
src/librustc/middle/save/recorder.rs
src/librustc/middle/trans/_match.rs
src/librustc/middle/trans/base.rs
src/librustc/middle/trans/debuginfo.rs
src/librustc/middle/trans/meth.rs
src/librustc/middle/ty.rs
src/librustc/middle/typeck/astconv.rs
src/librustc/middle/typeck/check/method.rs
src/librustc/middle/typeck/check/mod.rs
src/librustc/middle/typeck/collect.rs
src/librustc/middle/typeck/infer/coercion.rs
src/librustc/middle/typeck/infer/combine.rs
src/librustc/middle/typeck/infer/mod.rs
src/librustc/middle/typeck/infer/region_inference/mod.rs
src/librustc/middle/typeck/infer/test.rs
src/librustc/middle/typeck/variance.rs
src/librustc/util/ppaux.rs
src/librustdoc/clean/mod.rs
src/librustdoc/html/format.rs
src/librustdoc/html/render.rs
src/librustdoc/lib.rs
src/librustdoc/markdown.rs
src/librustdoc/passes.rs
src/librustrt/c_str.rs
src/libserialize/json.rs
src/libsync/mpmc_bounded_queue.rs
src/libsync/raw.rs
src/libsyntax/ast.rs
src/libsyntax/ext/deriving/generic/mod.rs
src/libsyntax/ext/deriving/generic/ty.rs
src/libsyntax/ext/expand.rs
src/libsyntax/fold.rs
src/libsyntax/parse/obsolete.rs
src/libsyntax/parse/parser.rs
src/libsyntax/print/pprust.rs
src/libsyntax/visit.rs
src/libterm/terminfo/parm.rs
src/libterm/terminfo/searcher.rs
src/libtest/lib.rs
src/libtest/stats.rs
src/libuuid/lib.rs
src/test/auxiliary/lint_stability.rs
src/test/bench/shootout-k-nucleotide-pipes.rs
src/test/bench/shootout-regex-dna.rs
src/test/compile-fail/borrowck-bad-nested-calls-free.rs
src/test/compile-fail/borrowck-bad-nested-calls-move.rs
src/test/compile-fail/borrowck-closures-use-after-free.rs
src/test/compile-fail/borrowck-lend-flow-loop.rs
src/test/compile-fail/borrowck-loan-blocks-mut-uniq.rs
src/test/compile-fail/borrowck-preserve-box-in-field.rs
src/test/compile-fail/borrowck-preserve-box-in-uniq.rs
src/test/compile-fail/borrowck-preserve-box.rs
src/test/compile-fail/borrowck-preserve-expl-deref.rs
src/test/compile-fail/borrowck-uniq-via-lend.rs
src/test/compile-fail/explicit-self-lifetime-mismatch.rs [new file with mode: 0644]
src/test/compile-fail/issue-11192.rs
src/test/compile-fail/issue-5153.rs
src/test/compile-fail/isuue-12470.rs
src/test/compile-fail/lint-allocation.rs [deleted file]
src/test/compile-fail/lint-stability.rs
src/test/compile-fail/lint-unused-mut-self.rs
src/test/compile-fail/object-pointer-types.rs
src/test/compile-fail/regions-infer-borrow-scope-too-big.rs
src/test/compile-fail/regions-infer-borrow-scope-within-loop.rs
src/test/compile-fail/regions-trait-variance.rs
src/test/compile-fail/struct-field-assignability.rs
src/test/compile-fail/ufcs-explicit-self-bad.rs [new file with mode: 0644]
src/test/debuginfo/borrowed-managed-basic.rs
src/test/debuginfo/borrowed-struct.rs
src/test/debuginfo/borrowed-tuple.rs
src/test/debuginfo/borrowed-unique-basic.rs
src/test/debuginfo/generic-method-on-generic-struct.rs
src/test/debuginfo/method-on-enum.rs
src/test/debuginfo/method-on-generic-struct.rs
src/test/debuginfo/method-on-struct.rs
src/test/debuginfo/method-on-trait.rs
src/test/debuginfo/method-on-tuple-struct.rs
src/test/debuginfo/self-in-default-method.rs
src/test/debuginfo/self-in-generic-default-method.rs
src/test/debuginfo/var-captured-in-sendable-closure.rs
src/test/run-pass/autoderef-method-on-trait.rs
src/test/run-pass/autoderef-method-twice-but-not-thrice.rs
src/test/run-pass/autoderef-method-twice.rs
src/test/run-pass/autoderef-method.rs
src/test/run-pass/bitv-perf-test.rs
src/test/run-pass/borrowck-lend-args.rs
src/test/run-pass/borrowck-mut-uniq.rs
src/test/run-pass/borrowck-root-while-cond.rs
src/test/run-pass/borrowck-uniq-via-ref.rs
src/test/run-pass/cci_borrow.rs
src/test/run-pass/explicit-self-objects-uniq.rs
src/test/run-pass/explicit-self.rs
src/test/run-pass/issue-1696.rs
src/test/run-pass/issue-3794.rs
src/test/run-pass/issue-4241.rs
src/test/run-pass/issue-5884.rs
src/test/run-pass/issue-7320.rs
src/test/run-pass/let-assignability.rs
src/test/run-pass/new-box.rs
src/test/run-pass/objects-owned-object-owned-method.rs
src/test/run-pass/regions-borrow-at.rs
src/test/run-pass/regions-borrow-uniq.rs
src/test/run-pass/regions-escape-into-other-fn.rs
src/test/run-pass/regions-infer-borrow-scope-within-loop-ok.rs
src/test/run-pass/regions-infer-borrow-scope.rs
src/test/run-pass/self-in-mut-slot-default-method.rs
src/test/run-pass/ufcs-explicit-self.rs [new file with mode: 0644]
src/test/run-pass/uniq-self-in-mut-slot.rs

index f49faf2ec6e3a8d68fa76631158f4a06fb0bd7a0..00d698e611e34eb3d7651e1ed818f691d8e589e7 100644 (file)
@@ -68,7 +68,7 @@ AST nodes and blocks with IDs), or flowgraph=<nodeid> (graphviz
 formatted flowgraph for node)
 .TP
 \fB\-\-dep-info\fR [FILENAME]
-Output dependency info to <filename> after compiling, in o format suitable
+Output dependency info to <filename> after compiling, in a format suitable
 for use by Makefiles.
 .TP
 \fB\-\-sysroot\fR PATH
index 8f54b2735a575d03ef455bff94b913e4285f342b..15e9897d47dbde634b43a1a2d7b42d2dd10487da 100644 (file)
@@ -377,7 +377,7 @@ define SREQ_CMDS
 ifeq ($$(OSTYPE_$(3)),apple-darwin)
   LD_LIBRARY_PATH_ENV_NAME$(1)_T_$(2)_H_$(3) := DYLD_LIBRARY_PATH
 else
-ifeq ($$(CFG_WINDOWSY_$(2)),1)
+ifeq ($$(CFG_WINDOWSY_$(3)),1)
   LD_LIBRARY_PATH_ENV_NAME$(1)_T_$(2)_H_$(3) := PATH
 else
   LD_LIBRARY_PATH_ENV_NAME$(1)_T_$(2)_H_$(3) := LD_LIBRARY_PATH
index 07e331c2a39639a72123dee67ad4298cac9134dc..583d9249b35476a72f59346dac2e8f544e94f1e5 100644 (file)
@@ -89,9 +89,9 @@ pub fn parse_config(args: Vec<String> ) -> Config {
           optflag("h", "help", "show this message"));
 
     assert!(!args.is_empty());
-    let argv0 = (*args.get(0)).clone();
+    let argv0 = args[0].clone();
     let args_ = args.tail();
-    if args.get(1).as_slice() == "-h" || args.get(1).as_slice() == "--help" {
+    if args[1].as_slice() == "-h" || args[1].as_slice() == "--help" {
         let message = format!("Usage: {} [OPTIONS] [TESTNAME...]", argv0);
         println!("{}", getopts::usage(message.as_slice(), groups.as_slice()));
         println!("");
@@ -116,7 +116,7 @@ fn opt_path(m: &getopts::Matches, nm: &str) -> Path {
     }
 
     let filter = if !matches.free.is_empty() {
-        let s = matches.free.get(0).as_slice();
+        let s = matches.free[0].as_slice();
         match regex::Regex::new(s) {
             Ok(re) => Some(re),
             Err(e) => {
index 44763f2cf4b3353b9af5164ba0715fc928b13c1c..c3ac40e8f08d41d03238ec3ad3e0017203460e37 100644 (file)
@@ -167,7 +167,7 @@ fn run_pretty_test(config: &Config, props: &TestProps, testfile: &Path) {
         let proc_res = print_source(config,
                                     props,
                                     testfile,
-                                    (*srcs.get(round)).to_string(),
+                                    srcs[round].to_string(),
                                     "normal");
 
         if !proc_res.status.success() {
@@ -187,9 +187,9 @@ fn run_pretty_test(config: &Config, props: &TestProps, testfile: &Path) {
             let s = File::open(&filepath).read_to_end().unwrap();
             String::from_utf8(s).unwrap()
         }
-        None => { (*srcs.get(srcs.len() - 2u)).clone() }
+        None => { srcs[srcs.len() - 2u].clone() }
     };
-    let mut actual = (*srcs.get(srcs.len() - 1u)).clone();
+    let mut actual = srcs[srcs.len() - 1u].clone();
 
     if props.pp_exact.is_some() {
         // Now we have to care about line endings
@@ -209,7 +209,7 @@ fn run_pretty_test(config: &Config, props: &TestProps, testfile: &Path) {
     if props.no_pretty_expanded { return }
 
     // additionally, run `--pretty expanded` and try to build it.
-    let proc_res = print_source(config, props, testfile, (*srcs.get(round)).clone(), "expanded");
+    let proc_res = print_source(config, props, testfile, srcs[round].clone(), "expanded");
     if !proc_res.status.success() {
         fatal_proc_rec("pretty-printing (expanded) failed", &proc_res);
     }
@@ -702,7 +702,7 @@ fn check_debugger_output(debugger_run_result: &ProcRes, check_lines: &[String])
             let mut rest = line.trim();
             let mut first = true;
             let mut failed = false;
-            for frag in check_fragments.get(i).iter() {
+            for frag in check_fragments[i].iter() {
                 let found = if first {
                     if rest.starts_with(frag.as_slice()) {
                         Some(0)
@@ -752,7 +752,7 @@ fn check_error_patterns(props: &TestProps,
     }
 
     let mut next_err_idx = 0u;
-    let mut next_err_pat = props.error_patterns.get(next_err_idx);
+    let mut next_err_pat = &props.error_patterns[next_err_idx];
     let mut done = false;
     let output_to_check = if props.check_stdout {
         format!("{}{}", proc_res.stdout, proc_res.stderr)
@@ -761,14 +761,14 @@ fn check_error_patterns(props: &TestProps,
     };
     for line in output_to_check.as_slice().lines() {
         if line.contains(next_err_pat.as_slice()) {
-            debug!("found error pattern {}", *next_err_pat);
+            debug!("found error pattern {}", next_err_pat);
             next_err_idx += 1u;
             if next_err_idx == props.error_patterns.len() {
                 debug!("found all error patterns");
                 done = true;
                 break;
             }
-            next_err_pat = props.error_patterns.get(next_err_idx);
+            next_err_pat = &props.error_patterns[next_err_idx];
         }
     }
     if done { return; }
@@ -847,13 +847,13 @@ fn prefix_matches( line : &str, prefix : &str ) -> bool {
     for line in proc_res.stderr.as_slice().lines() {
         let mut was_expected = false;
         for (i, ee) in expected_errors.iter().enumerate() {
-            if !*found_flags.get(i) {
+            if !found_flags[i] {
                 debug!("prefix={} ee.kind={} ee.msg={} line={}",
-                       prefixes.get(i).as_slice(),
+                       prefixes[i].as_slice(),
                        ee.kind,
                        ee.msg,
                        line);
-                if prefix_matches(line, prefixes.get(i).as_slice()) &&
+                if prefix_matches(line, prefixes[i].as_slice()) &&
                     line.contains(ee.kind.as_slice()) &&
                     line.contains(ee.msg.as_slice()) {
                     *found_flags.get_mut(i) = true;
@@ -877,7 +877,7 @@ fn prefix_matches( line : &str, prefix : &str ) -> bool {
 
     for (i, &flag) in found_flags.iter().enumerate() {
         if !flag {
-            let ee = expected_errors.get(i);
+            let ee = &expected_errors[i];
             fatal_proc_rec(format!("expected {} on line {} not found: {}",
                                   ee.kind, ee.line, ee.msg).as_slice(),
                           proc_res);
index ae58db9077cabd418abd9d673333244aefd06e24..ce037251e46b44940fa754d5c8f6185647cfff9d 100644 (file)
@@ -31,7 +31,7 @@ You may also be interested in browsing [GitHub's Rust][github-rust] page.
 
 ## Does it run on Windows?
 
-Yes. All development happens in lock-step on all 3 target platforms. Using MinGW, not Cygwin. Note that the windows implementation currently has some limitations: in particular 64-bit build is [not fully supported yet][win64], and all executables created by rustc [depends on libgcc DLL at runtime][libgcc].
+Yes. All development happens in lock-step on all 3 target platforms. Using MinGW, not Cygwin. Note that the windows implementation currently has some limitations: in particular 64-bit build is [not fully supported yet][win64], and all executables created by rustc [depend on libgcc DLL at runtime][libgcc].
 
 [win64]: https://github.com/rust-lang/rust/issues/1237
 [libgcc]: https://github.com/rust-lang/rust/issues/11782
@@ -68,7 +68,7 @@ Cleanup through RAII-style destructors is more likely to work than in catch bloc
 
 ## Why aren't modules type-parametric?
 
-We want to maintain the option to parametrize at runtime. We may make eventually change this limitation, but initially this is how type parameters were implemented.
+We want to maintain the option to parametrize at runtime. We may eventually change this limitation, but initially this is how type parameters were implemented.
 
 ## Why aren't values type-parametric? Why only items?
 
index 1f44b77d56abb1d47203c79527e4d06dcae22e1c..a6cc9cd0bc281f9a9b6950ca7bdc62349b2f59d2 100644 (file)
@@ -67,7 +67,7 @@ Now we can call `compute_distance()`:
 # let on_the_stack :     Point  =     Point{x: 3.0, y: 4.0};
 # let on_the_heap  : Box<Point> = box Point{x: 7.0, y: 9.0};
 # fn compute_distance(p1: &Point, p2: &Point) -> f64 { 0.0 }
-compute_distance(&on_the_stack, on_the_heap);
+compute_distance(&on_the_stack, &*on_the_heap);
 ~~~
 
 Here, the `&` operator takes the address of the variable
@@ -77,10 +77,9 @@ value. We also call this _borrowing_ the local variable
 `on_the_stack`, because we have created an alias: that is, another
 name for the same data.
 
-In the case of `on_the_heap`, however, no explicit action is necessary. 
-The compiler will automatically convert a box point to a reference like &point. 
-This is another form of borrowing; in this case, the contents of the owned box 
-are being lent out.
+Likewise, in the case of `owned_box`,
+the `&` operator is used in conjunction with the `*` operator
+to take a reference to the contents of the box.
 
 Whenever a caller lends data to a callee, there are some limitations on what
 the caller can do with the original. For example, if the contents of a
index 0865282209773d3423a5510d3c6ca81e60024615..17a1114be55f6e0b777baa0398197f6dd436208a 100644 (file)
@@ -279,7 +279,7 @@ fn main() {
     let origin =    &Point { x: 0.0, y: 0.0 };
     let p1     = box Point { x: 5.0, y: 3.0 };
 
-    println!("{}", compute_distance(origin, p1));
+    println!("{}", compute_distance(origin, &*p1));
 }
 ~~~
 
diff --git a/src/doc/guide-strings.md b/src/doc/guide-strings.md
new file mode 100644 (file)
index 0000000..6f301af
--- /dev/null
@@ -0,0 +1,129 @@
+% The Strings Guide
+
+# Strings
+
+Strings are an important concept to master in any programming language. If you
+come from a managed language background, you may be surprised at the complexity
+of string handling in a systems programming language. Efficient access and
+allocation of memory for a dynamically sized structure involves a lot of
+details. Luckily, Rust has lots of tools to help us here.
+
+A **string** is a sequence of unicode scalar values encoded as a stream of
+UTF-8 bytes. All strings are guaranteed to be validly-encoded UTF-8 sequences.
+Additionally, strings are not null-terminated and can contain null bytes.
+
+Rust has two main types of strings: `&str` and `String`.
+
+## &str
+
+The first kind is a `&str`. This is pronounced a 'string slice.' String literals
+are of the type `&str`:
+
+```{rust}
+let string = "Hello there.";
+```
+
+Like any Rust type, string slices have an associated lifetime. A string literal
+is a `&'static str`.  A string slice can be written without an explicit
+lifetime in many cases, such as in function arguments. In these cases the
+lifetime will be inferred:
+
+```{rust}
+fn takes_slice(slice: &str) {
+    println!("Got: {}", slice);
+}
+```
+
+Like vector slices, string slices are simply a pointer plus a length. This
+means that they're a 'view' into an already-allocated string, such as a
+`&'static str` or a `String`.
+
+## String
+
+A `String` is a heap-allocated string. This string is growable, and is also
+guaranteed to be UTF-8.
+
+```{rust}
+let mut s = "Hello".to_string();
+println!("{}", s);
+
+s.push_str(", world.");
+println!("{}", s);
+```
+
+You can coerce a `String` into a `&str` with the `as_slice()` method:
+
+```{rust}
+fn takes_slice(slice: &str) {
+    println!("Got: {}", slice);
+}
+
+fn main() {
+    let s = "Hello".to_string();
+    takes_slice(s.as_slice());
+}
+```
+
+You can also get a `&str` from a stack-allocated array of bytes:
+
+```{rust}
+use std::str;
+
+let x: &[u8] = &[b'a', b'b'];
+let stack_str: &str = str::from_utf8(x).unwrap();
+```
+
+## Best Practices
+
+### `String` vs. `&str`
+
+In general, you should prefer `String` when you need ownership, and `&str` when
+you just need to borrow a string. This is very similar to using `Vec<T>` vs. `&[T]`,
+and `T` vs `&T` in general.
+
+This means starting off with this:
+
+```{rust,ignore}
+fn foo(s: &str) {
+```
+
+and only moving to this:
+
+```{rust,ignore}
+fn foo(s: String) {
+```
+
+If you have good reason. It's not polite to hold on to ownership you don't
+need, and it can make your lifetimes more complex. Furthermore, you can pass
+either kind of string into `foo` by using `.as_slice()` on any `String` you
+need to pass in, so the `&str` version is more flexible.
+
+### Comparisons
+
+To compare a String to a constant string, prefer `as_slice()`...
+
+```{rust}
+fn compare(string: String) {
+    if string.as_slice() == "Hello" {
+        println!("yes");
+    }
+}
+```
+
+... over `to_string()`:
+
+```{rust}
+fn compare(string: String) {
+    if string == "Hello".to_string() {
+        println!("yes");
+    }
+}
+```
+
+Converting a `String` to a `&str` is cheap, but converting the `&str` to a
+`String` involves an allocation.
+
+## Other Documentation
+
+* [the `&str` API documentation](/std/str/index.html)
+* [the `String` API documentation](std/string/index.html)
index e8928cb55056c519d65faa4d65d8c220eba5fd46..7dcf8486181ed2bf064136e0e5e3b5614b70ffa1 100644 (file)
@@ -205,7 +205,7 @@ fn main() {
 
     spawn(proc() {
         let numbers = rx.recv();
-        println!("{}", *numbers.get(0));
+        println!("{}", numbers[0]);
     })
 }
 ```
@@ -244,11 +244,11 @@ fn main() {
 
     spawn(proc() {
         let numbers = rx.recv();
-        println!("{}", numbers.get(0));
+        println!("{}", numbers[0]);
     });
 
     // Try to print a number from the original task
-    println!("{}", *numbers.get(0));
+    println!("{}", numbers[0]);
 }
 ```
 
@@ -256,7 +256,7 @@ The compiler will produce an error indicating that the value is no longer in sco
 
 ```text
 concurrency.rs:12:20: 12:27 error: use of moved value: 'numbers'
-concurrency.rs:12     println!("{}", numbers.get(0));
+concurrency.rs:12     println!("{}", numbers[0]);
                                      ^~~~~~~
 ```
 
@@ -276,7 +276,7 @@ fn main() {
 
         spawn(proc() {
             let numbers = rx.recv();
-            println!("{:d}", *numbers.get(num as uint));
+            println!("{:d}", numbers[num as uint]);
         })
     }
 }
@@ -309,7 +309,7 @@ fn main() {
 
         spawn(proc() {
             let numbers = rx.recv();
-            println!("{:d}", *numbers.get(num as uint));
+            println!("{:d}", (*numbers)[num as uint]);
         })
     }
 }
@@ -364,7 +364,7 @@ fn main() {
             // See: https://github.com/rust-lang/rust/issues/6515
             *numbers.get_mut(num as uint) = *numbers.get_mut(num as uint) + 1;
 
-            println!("{}", *numbers.get(num as uint));
+            println!("{}", (*numbers)[num as uint]);
 
             // When `numbers` goes out of scope the lock is dropped
         })
index 9d5a6fa42a830239fb21695527511b85fc6abe1f..9fe61eb3fe3b0da14db5f78cb30d4ae48d5cfeef 100644 (file)
@@ -3243,7 +3243,7 @@ enum List { Nil, Cons(uint, Box<List>) }
 fn is_sorted(list: &List) -> bool {
     match *list {
         Nil | Cons(_, box Nil) => true,
-        Cons(x, ref r @ box Cons(y, _)) => (x <= y) && is_sorted(*r)
+        Cons(x, ref r @ box Cons(y, _)) => (x <= y) && is_sorted(&**r)
     }
 }
 
index 10f67876e508fc34137c20bbce97cf67fa9a17d3..4c90e564b584ec127883df86d0141c8b44effff3 100644 (file)
@@ -1470,7 +1470,7 @@ Now we can call `compute_distance()` in various ways:
 # let on_the_stack :     Point  =     Point { x: 3.0, y: 4.0 };
 # let on_the_heap  : Box<Point> = box Point { x: 7.0, y: 9.0 };
 # fn compute_distance(p1: &Point, p2: &Point) -> f64 { 0.0 }
-compute_distance(&on_the_stack, on_the_heap);
+compute_distance(&on_the_stack, &*on_the_heap);
 ~~~
 
 Here the `&` operator is used to take the address of the variable
@@ -1480,11 +1480,9 @@ reference. We also call this _borrowing_ the local variable
 `on_the_stack`, because we are creating an alias: that is, another
 route to the same data.
 
-In the case of `owned_box`, however, no
-explicit action is necessary. The compiler will automatically convert
-a box `box point` to a reference like
-`&point`. This is another form of borrowing; in this case, the
-contents of the owned box are being lent out.
+Likewise, in the case of `owned_box`,
+the `&` operator is used in conjunction with the `*` operator
+to take a reference to the contents of the box.
 
 Whenever a value is borrowed, there are some limitations on what you
 can do with the original. For example, if the contents of a variable
@@ -2427,7 +2425,7 @@ as in this version of `print_all` that copies elements.
 fn print_all<T: Printable + Clone>(printable_things: Vec<T>) {
     let mut i = 0;
     while i < printable_things.len() {
-        let copy_of_thing = printable_things.get(i).clone();
+        let copy_of_thing = printable_things[i].clone();
         copy_of_thing.print();
         i += 1;
     }
index 56506d798d9df3335f70ad6abe8f56bf8b9e76db..89f6e934ad2597e78e6e1ce79da9e4d4965d954c 100644 (file)
@@ -67,7 +67,7 @@ fn ne(&self, other: &Box<T>) -> bool { *(*self) != *(*other) }
 impl<T:PartialOrd> PartialOrd for Box<T> {
     #[inline]
     fn partial_cmp(&self, other: &Box<T>) -> Option<Ordering> {
-        (**self).partial_cmp(*other)
+        (**self).partial_cmp(&**other)
     }
     #[inline]
     fn lt(&self, other: &Box<T>) -> bool { *(*self) < *(*other) }
@@ -80,7 +80,9 @@ fn gt(&self, other: &Box<T>) -> bool { *(*self) > *(*other) }
 }
 impl<T: Ord> Ord for Box<T> {
     #[inline]
-    fn cmp(&self, other: &Box<T>) -> Ordering { (**self).cmp(*other) }
+    fn cmp(&self, other: &Box<T>) -> Ordering {
+        (**self).cmp(&**other)
+    }
 }
 impl<T: Eq> Eq for Box<T> {}
 
index 40cf8495a40593996e7f259d13f9fda43ef91ed8..1c5aa8a323bab8cdaca429e08dfb3d35cd7766d1 100644 (file)
@@ -277,21 +277,33 @@ fn size_hint(&self) -> (uint, Option<uint>) {
 
 /// Extension methods for vector slices with cloneable elements
 pub trait CloneableVector<T> {
-    /// Copy `self` into a new owned vector
-    fn to_owned(&self) -> Vec<T>;
+    /// Copy `self` into a new vector
+    fn to_vec(&self) -> Vec<T>;
+
+    /// Deprecated. Use `to_vec`
+    #[deprecated = "Replaced by `to_vec`"]
+    fn to_owned(&self) -> Vec<T> {
+        self.to_vec()
+    }
 
     /// Convert `self` into an owned vector, not making a copy if possible.
-    fn into_owned(self) -> Vec<T>;
+    fn into_vec(self) -> Vec<T>;
+
+    /// Deprecated. Use `into_vec`
+    #[deprecated = "Replaced by `into_vec`"]
+    fn into_owned(self) -> Vec<T> {
+        self.into_vec()
+    }
 }
 
 /// Extension methods for vector slices
 impl<'a, T: Clone> CloneableVector<T> for &'a [T] {
     /// Returns a copy of `v`.
     #[inline]
-    fn to_owned(&self) -> Vec<T> { Vec::from_slice(*self) }
+    fn to_vec(&self) -> Vec<T> { Vec::from_slice(*self) }
 
     #[inline(always)]
-    fn into_owned(self) -> Vec<T> { self.to_owned() }
+    fn into_vec(self) -> Vec<T> { self.to_vec() }
 }
 
 /// Extension methods for vectors containing `Clone` elements.
@@ -325,7 +337,7 @@ fn partitioned(&self, f: |&T| -> bool) -> (Vec<T>, Vec<T>) {
     fn permutations(self) -> Permutations<T> {
         Permutations{
             swaps: ElementSwaps::new(self.len()),
-            v: self.to_owned(),
+            v: self.to_vec(),
         }
     }
 
@@ -888,7 +900,7 @@ fn test_last() {
     fn test_slice() {
         // Test fixed length vector.
         let vec_fixed = [1i, 2, 3, 4];
-        let v_a = vec_fixed.slice(1u, vec_fixed.len()).to_owned();
+        let v_a = vec_fixed.slice(1u, vec_fixed.len()).to_vec();
         assert_eq!(v_a.len(), 3u);
         let v_a = v_a.as_slice();
         assert_eq!(v_a[0], 2);
@@ -897,7 +909,7 @@ fn test_slice() {
 
         // Test on stack.
         let vec_stack = &[1i, 2, 3];
-        let v_b = vec_stack.slice(1u, 3u).to_owned();
+        let v_b = vec_stack.slice(1u, 3u).to_vec();
         assert_eq!(v_b.len(), 2u);
         let v_b = v_b.as_slice();
         assert_eq!(v_b[0], 2);
@@ -905,7 +917,7 @@ fn test_slice() {
 
         // Test `Box<[T]>`
         let vec_unique = vec![1i, 2, 3, 4, 5, 6];
-        let v_d = vec_unique.slice(1u, 6u).to_owned();
+        let v_d = vec_unique.slice(1u, 6u).to_vec();
         assert_eq!(v_d.len(), 5u);
         let v_d = v_d.as_slice();
         assert_eq!(v_d[0], 2);
@@ -1132,7 +1144,7 @@ fn test_permutations() {
             let (min_size, max_opt) = it.size_hint();
             assert_eq!(min_size, 1);
             assert_eq!(max_opt.unwrap(), 1);
-            assert_eq!(it.next(), Some(v.as_slice().to_owned()));
+            assert_eq!(it.next(), Some(v.as_slice().to_vec()));
             assert_eq!(it.next(), None);
         }
         {
@@ -1141,7 +1153,7 @@ fn test_permutations() {
             let (min_size, max_opt) = it.size_hint();
             assert_eq!(min_size, 1);
             assert_eq!(max_opt.unwrap(), 1);
-            assert_eq!(it.next(), Some(v.as_slice().to_owned()));
+            assert_eq!(it.next(), Some(v.as_slice().to_vec()));
             assert_eq!(it.next(), None);
         }
         {
index 85921f1176a3ae58ea4a6a67bd0944c3eebbe68b..bd6a13ae2e3ed7c28c273d7c16f6c6d4df1bc030 100644 (file)
@@ -55,10 +55,10 @@ fn main() {
 
 # Representation
 
-Rust's string type, `str`, is a sequence of unicode codepoints encoded as a
-stream of UTF-8 bytes. All safely-created strings are guaranteed to be validly
-encoded UTF-8 sequences. Additionally, strings are not null-terminated
-and can contain null codepoints.
+Rust's string type, `str`, is a sequence of unicode scalar values encoded as a
+stream of UTF-8 bytes. All strings are guaranteed to be validly encoded UTF-8
+sequences. Additionally, strings are not null-terminated and can contain null
+bytes.
 
 The actual representation of strings have direct mappings to vectors: `&str`
 is the same as `&[u8]`.
index 3d4973373e26763fbfa756bd6b85ce7f5833f086..ad5ad13167c0e4c50d1d2d529aa52fa269114d95 100644 (file)
 //! An ordered map and set implemented as self-balancing binary search
 //! trees. The only requirement for the types is that the key implements
 //! `Ord`.
+//!
+//! ## Example
+//!
+//! ```{rust}
+//! use std::collections::TreeSet;
+//!
+//! let mut tree_set = TreeSet::new();
+//!
+//! tree_set.insert(2i);
+//! tree_set.insert(1i);
+//! tree_set.insert(3i);
+//!
+//! for i in tree_set.iter() {
+//!    println!("{}", i) // prints 1, then 2, then 3
+//! }
+//! ```
 
 use core::prelude::*;
 
@@ -500,7 +516,7 @@ fn size_hint(&self) -> (uint, Option<uint>) {
 fn deref<'a, K, V>(node: &'a Option<Box<TreeNode<K, V>>>) -> *const TreeNode<K, V> {
     match *node {
         Some(ref n) => {
-            let n: &TreeNode<K, V> = *n;
+            let n: &TreeNode<K, V> = &**n;
             n as *const TreeNode<K, V>
         }
         None => ptr::null()
@@ -587,6 +603,22 @@ fn next(&mut self) -> Option<&'a T> {
 /// A implementation of the `Set` trait on top of the `TreeMap` container. The
 /// only requirement is that the type of the elements contained ascribes to the
 /// `Ord` trait.
+///
+/// ## Example
+///
+/// ```{rust}
+/// use std::collections::TreeSet;
+///
+/// let mut tree_set = TreeSet::new();
+///
+/// tree_set.insert(2i);
+/// tree_set.insert(1i);
+/// tree_set.insert(3i);
+///
+/// for i in tree_set.iter() {
+///    println!("{}", i) // prints 1, then 2, then 3
+/// }
+/// ```
 #[deriving(Clone)]
 pub struct TreeSet<T> {
     map: TreeMap<T, ()>
index 1e96588dac5f896a9217b791228cac9533f0a52d..96228531ae54f05446cb5777b4dc6536d98f8200 100644 (file)
@@ -42,7 +42,7 @@
 /// vec.push(2i);
 ///
 /// assert_eq!(vec.len(), 2);
-/// assert_eq!(vec.get(0), &1);
+/// assert_eq!(vec[0], 1);
 ///
 /// assert_eq!(vec.pop(), Some(2));
 /// assert_eq!(vec.len(), 1);
@@ -363,6 +363,21 @@ fn clone_from(&mut self, other: &Vec<T>) {
     }
 }
 
+impl<T> Index<uint,T> for Vec<T> {
+    #[inline]
+    fn index<'a>(&'a self, index: &uint) -> &'a T {
+        self.get(*index)
+    }
+}
+
+// FIXME(#12825) Indexing will always try IndexMut first and that causes issues.
+/*impl<T> IndexMut<uint,T> for Vec<T> {
+    #[inline]
+    fn index_mut<'a>(&'a mut self, index: &uint) -> &'a mut T {
+        self.get_mut(*index)
+    }
+}*/
+
 impl<T> FromIterator<T> for Vec<T> {
     #[inline]
     fn from_iter<I:Iterator<T>>(mut iterator: I) -> Vec<T> {
@@ -422,8 +437,8 @@ fn len(&self) -> uint {
 }
 
 impl<T: Clone> CloneableVector<T> for Vec<T> {
-    fn to_owned(&self) -> Vec<T> { self.clone() }
-    fn into_owned(self) -> Vec<T> { self }
+    fn to_vec(&self) -> Vec<T> { self.clone() }
+    fn into_vec(self) -> Vec<T> { self }
 }
 
 // FIXME: #13996: need a way to mark the return value as `noalias`
@@ -731,9 +746,12 @@ pub unsafe fn set_len(&mut self, len: uint) {
     /// # Example
     ///
     /// ```rust
+    /// #![allow(deprecated)]
+    ///
     /// let vec = vec!(1i, 2, 3);
     /// assert!(vec.get(1) == &2);
     /// ```
+    #[deprecated="prefer using indexing, e.g., vec[0]"]
     #[inline]
     pub fn get<'a>(&'a self, index: uint) -> &'a T {
         &self.as_slice()[index]
@@ -1847,6 +1865,19 @@ fn drop(&mut self) {
         v.truncate(0);
     }
 
+    #[test]
+    fn test_index() {
+        let vec = vec!(1i, 2, 3);
+        assert!(vec[1] == 2);
+    }
+
+    #[test]
+    #[should_fail]
+    fn test_index_out_of_bounds() {
+        let vec = vec!(1i, 2, 3);
+        let _ = vec[3];
+    }
+
     #[bench]
     fn bench_new(b: &mut Bencher) {
         b.iter(|| {
index 9755d54a1320591f506118285c8d8b288a1489ef..b72cc43b28c60c3485684c5875a64a1c9eac6184 100644 (file)
@@ -466,7 +466,7 @@ fn visit_enum_variant_field(&mut self,
                                 _offset: uint,
                                 inner: *const TyDesc)
                                 -> bool {
-        match *self.var_stk.get(self.var_stk.len() - 1) {
+        match self.var_stk[self.var_stk.len() - 1] {
             Matched => {
                 if i != 0 {
                     try!(self, self.writer.write(", ".as_bytes()));
@@ -484,7 +484,7 @@ fn visit_leave_enum_variant(&mut self, _variant: uint,
                                 _disr_val: Disr,
                                 n_fields: uint,
                                 _name: &str) -> bool {
-        match *self.var_stk.get(self.var_stk.len() - 1) {
+        match self.var_stk[self.var_stk.len() - 1] {
             Matched => {
                 if n_fields > 0 {
                     try!(self, self.writer.write([')' as u8]));
index eaec31a45f42180fab1f4cb3ae95ac19a0d00bcd..bf39fd566e52d200ea2ff367ca4796e7312f1575 100644 (file)
@@ -51,7 +51,7 @@
 //! fn main() {
 //!     let args: Vec<String> = os::args();
 //!
-//!     let program = args.get(0).clone();
+//!     let program = args[0].clone();
 //!
 //!     let opts = [
 //!         optopt("o", "", "set output file name", "NAME"),
@@ -67,7 +67,7 @@
 //!     }
 //!     let output = matches.opt_str("o");
 //!     let input = if !matches.free.is_empty() {
-//!         (*matches.free.get(0)).clone()
+//!         matches.free[0].clone()
 //!     } else {
 //!         print_usage(program.as_slice(), opts);
 //!         return;
@@ -275,7 +275,7 @@ pub fn long_to_short(&self) -> Opt {
 impl Matches {
     fn opt_vals(&self, nm: &str) -> Vec<Optval> {
         match find_opt(self.opts.as_slice(), Name::from_str(nm)) {
-            Some(id) => (*self.vals.get(id)).clone(),
+            Some(id) => self.vals[id].clone(),
             None => fail!("No option '{}' defined", nm)
         }
     }
@@ -285,7 +285,7 @@ fn opt_val(&self, nm: &str) -> Option<Optval> {
         if vals.is_empty() {
             None
         } else {
-            Some((*vals.get(0)).clone())
+            Some(vals[0].clone())
         }
     }
 
@@ -304,7 +304,7 @@ pub fn opts_present(&self, names: &[String]) -> bool {
         for nm in names.iter() {
             match find_opt(self.opts.as_slice(),
                            Name::from_str(nm.as_slice())) {
-                Some(id) if !self.vals.get(id).is_empty() => return true,
+                Some(id) if !self.vals[id].is_empty() => return true,
                 _ => (),
             };
         }
@@ -344,8 +344,8 @@ pub fn opt_str(&self, nm: &str) -> Option<String> {
         if vals.is_empty() {
             return None::<String>;
         }
-        match vals.get(0) {
-            &Val(ref s) => Some((*s).clone()),
+        match vals[0] {
+            Val(ref s) => Some((*s).clone()),
             _ => None
         }
     }
@@ -361,8 +361,8 @@ pub fn opt_default(&self, nm: &str, def: &str) -> Option<String> {
         if vals.is_empty() {
             return None;
         }
-        match vals.get(0) {
-            &Val(ref s) => Some((*s).clone()),
+        match vals[0] {
+            Val(ref s) => Some((*s).clone()),
             _ => Some(def.to_string())
         }
     }
@@ -560,8 +560,8 @@ pub fn getopts(args: &[String], optgrps: &[OptGroup]) -> Result {
                     names = vec!(Long(tail.to_string()));
                 } else {
                     names =
-                        vec!(Long((*tail_eq.get(0)).to_string()));
-                    i_arg = Some((*tail_eq.get(1)).to_string());
+                        vec!(Long(tail_eq[0].to_string()));
+                    i_arg = Some(tail_eq[1].to_string());
                 }
             } else {
                 let mut j = 1;
@@ -583,7 +583,7 @@ pub fn getopts(args: &[String], optgrps: &[OptGroup]) -> Result {
                       None => {
                         let arg_follows =
                             last_valid_opt_id.is_some() &&
-                            match opts.get(last_valid_opt_id.unwrap())
+                            match opts[last_valid_opt_id.unwrap()]
                               .hasarg {
 
                               Yes | Maybe => true,
@@ -609,7 +609,7 @@ pub fn getopts(args: &[String], optgrps: &[OptGroup]) -> Result {
                   Some(id) => id,
                   None => return Err(UnrecognizedOption(nm.to_string()))
                 };
-                match opts.get(optid).hasarg {
+                match opts[optid].hasarg {
                   No => {
                     if !i_arg.is_none() {
                         return Err(UnexpectedArgument(nm.to_string()));
@@ -646,16 +646,16 @@ pub fn getopts(args: &[String], optgrps: &[OptGroup]) -> Result {
     }
     i = 0u;
     while i < n_opts {
-        let n = vals.get(i).len();
-        let occ = opts.get(i).occur;
+        let n = vals[i].len();
+        let occ = opts[i].occur;
         if occ == Req {
             if n == 0 {
-                return Err(OptionMissing(opts.get(i).name.to_string()));
+                return Err(OptionMissing(opts[i].name.to_string()));
             }
         }
         if occ != Multi {
             if n > 1 {
-                return Err(OptionDuplicated(opts.get(i).name.to_string()));
+                return Err(OptionDuplicated(opts[i].name.to_string()));
             }
         }
         i += 1;
index c28eb51d59d442d42acfa5962886e50a5fd0bf7c..d539283f0a717a8b544d562bead76c06f636603f 100644 (file)
@@ -154,7 +154,7 @@ fn next(&mut self) -> Option<Path> {
                 if self.require_dir && !path.is_dir() { continue; }
                 return Some(path);
             }
-            let ref pattern = *self.dir_patterns.get(idx);
+            let ref pattern = self.dir_patterns[idx];
 
             if pattern.matches_with(match path.filename_str() {
                 // this ugly match needs to go here to avoid a borrowck error
@@ -250,21 +250,21 @@ pub fn new(pattern: &str) -> Pattern {
         let mut i = 0;
 
         while i < chars.len() {
-            match *chars.get(i) {
+            match chars[i] {
                 '?' => {
                     tokens.push(AnyChar);
                     i += 1;
                 }
                 '*' => {
                     // *, **, ***, ****, ... are all equivalent
-                    while i < chars.len() && *chars.get(i) == '*' {
+                    while i < chars.len() && chars[i] == '*' {
                         i += 1;
                     }
                     tokens.push(AnySequence);
                 }
                 '[' => {
 
-                    if i <= chars.len() - 4 && *chars.get(i + 1) == '!' {
+                    if i <= chars.len() - 4 && chars[i + 1] == '!' {
                         match chars.slice_from(i + 3).position_elem(&']') {
                             None => (),
                             Some(j) => {
@@ -276,7 +276,7 @@ pub fn new(pattern: &str) -> Pattern {
                             }
                         }
                     }
-                    else if i <= chars.len() - 3 && *chars.get(i + 1) != '!' {
+                    else if i <= chars.len() - 3 && chars[i + 1] != '!' {
                         match chars.slice_from(i + 2).position_elem(&']') {
                             None => (),
                             Some(j) => {
@@ -507,7 +507,7 @@ fn pattern_as_str(pattern: &Pattern) -> Option<String> {
                     // the current and parent directory respectively requires that
                     // the pattern has a leading dot, even if the `MatchOptions` field
                     // `require_literal_leading_dot` is not set.
-                    if pattern.tokens.len() > 0 && pattern.tokens.get(0) == &Char('.') {
+                    if pattern.tokens.len() > 0 && pattern.tokens[0] == Char('.') {
                         for &special in [".", ".."].iter() {
                             if pattern.matches_with(special, options) {
                                 add(todo, path.join(special));
index a3653fa9735901353a3cf331b895fc614e296e0f..24698d09f56e53d782556aa343b0fd0f7e823d11 100644 (file)
@@ -168,7 +168,7 @@ fn node_id(&'a self, n: &Nd) -> dot::Id<'a> {
         dot::Id::new(format!("N{}", n))
     }
     fn node_label<'a>(&'a self, n: &Nd) -> dot::LabelText<'a> {
-        dot::LabelStr(str::Slice(self.nodes.get(*n).as_slice()))
+        dot::LabelStr(str::Slice(self.nodes[*n].as_slice()))
     }
     fn edge_label<'a>(&'a self, _: &Ed) -> dot::LabelText<'a> {
         dot::LabelStr(str::Slice("&sube;"))
@@ -225,7 +225,7 @@ fn node_id(&'a self, n: &Nd<'a>) -> dot::Id<'a> {
     }
     fn node_label<'a>(&'a self, n: &Nd<'a>) -> dot::LabelText<'a> {
         let &(i, _) = n;
-        dot::LabelStr(str::Slice(self.nodes.get(i).as_slice()))
+        dot::LabelStr(str::Slice(self.nodes[i].as_slice()))
     }
     fn edge_label<'a>(&'a self, _: &Ed<'a>) -> dot::LabelText<'a> {
         dot::LabelStr(str::Slice("&sube;"))
@@ -238,8 +238,8 @@ fn nodes(&'a self) -> dot::Nodes<'a,Nd<'a>> {
     }
     fn edges(&'a self) -> dot::Edges<'a,Ed<'a>> {
         self.edges.iter()
-            .map(|&(i,j)|((i, self.nodes.get(i).as_slice()),
-                          (j, self.nodes.get(j).as_slice())))
+            .map(|&(i,j)|((i, self.nodes[i].as_slice()),
+                          (j, self.nodes[j].as_slice())))
             .collect()
     }
     fn source(&self, e: &Ed<'a>) -> Nd<'a> { let &(s,_) = e; s }
index bd19f19cec6b2f86a9a1beee94f87b60c3720eab..ec60be195158ad67714689040f24a4a8e230c5c4 100644 (file)
@@ -124,15 +124,15 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
 
 impl<'a,T:Clone> CloneableVector<T> for MaybeOwnedVector<'a,T> {
     /// Returns a copy of `self`.
-    fn to_owned(&self) -> Vec<T> {
-        self.as_slice().to_owned()
+    fn to_vec(&self) -> Vec<T> {
+        self.as_slice().to_vec()
     }
 
     /// Convert `self` into an owned slice, not making a copy if possible.
-    fn into_owned(self) -> Vec<T> {
+    fn into_vec(self) -> Vec<T> {
         match self {
-            Growable(v) => v.as_slice().to_owned(),
-            Borrowed(v) => v.to_owned(),
+            Growable(v) => v.as_slice().to_vec(),
+            Borrowed(v) => v.to_vec(),
         }
     }
 }
@@ -140,7 +140,7 @@ fn into_owned(self) -> Vec<T> {
 impl<'a, T: Clone> Clone for MaybeOwnedVector<'a, T> {
     fn clone(&self) -> MaybeOwnedVector<'a, T> {
         match *self {
-            Growable(ref v) => Growable(v.to_owned()),
+            Growable(ref v) => Growable(v.to_vec()),
             Borrowed(v) => Borrowed(v)
         }
     }
index 046ba96f45a38185e28770381c58094ca4713e77..acba750aaf4ac0d745f2c0b8014188050f1932b5 100644 (file)
@@ -8,13 +8,53 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-/*!
-
-A Big integer (signed version: `BigInt`, unsigned version: `BigUint`).
-
-A `BigUint` is represented as an array of `BigDigit`s.
-A `BigInt` is a combination of `BigUint` and `Sign`.
-*/
+//! A Big integer (signed version: `BigInt`, unsigned version: `BigUint`).
+//!
+//! A `BigUint` is represented as an array of `BigDigit`s.
+//! A `BigInt` is a combination of `BigUint` and `Sign`.
+//!
+//! Common numerical operations are overloaded, so we can treat them
+//! the same way we treat other numbers.
+//!
+//! ## Example
+//!
+//! ```rust
+//! use num::bigint::BigUint;
+//! use std::num::{Zero, One};
+//! use std::mem::replace;
+//!
+//! // Calculate large fibonacci numbers.
+//! fn fib(n: uint) -> BigUint {
+//!     let mut f0: BigUint = Zero::zero();
+//!     let mut f1: BigUint = One::one();
+//!     for _ in range(0, n) {
+//!         let f2 = f0 + f1;
+//!         // This is a low cost way of swapping f0 with f1 and f1 with f2.
+//!         f0 = replace(&mut f1, f2);
+//!     }
+//!     f0
+//! }
+//!
+//! // This is a very large number.
+//! println!("fib(1000) = {}", fib(1000));
+//! ```
+//!
+//! It's easy to generate large random numbers:
+//!
+//! ```rust
+//! use num::bigint::{ToBigInt, RandBigInt};
+//! use std::rand;
+//!
+//! let mut rng = rand::task_rng();
+//! let a = rng.gen_bigint(1000u);
+//!
+//! let low = -10000i.to_bigint().unwrap();
+//! let high = 10000i.to_bigint().unwrap();
+//! let b = rng.gen_bigint_range(&low, &high);
+//!
+//! // Probably an even larger number.
+//! println!("{}", a * b);
+//! ```
 
 use Integer;
 use rand::Rng;
 use std::string::String;
 use std::{uint, i64, u64};
 
-/**
-A `BigDigit` is a `BigUint`'s composing element.
-*/
+/// A `BigDigit` is a `BigUint`'s composing element.
 pub type BigDigit = u32;
 
-/**
-A `DoubleBigDigit` is the internal type used to do the computations.  Its
-size is the double of the size of `BigDigit`.
-*/
+/// A `DoubleBigDigit` is the internal type used to do the computations.  Its
+/// size is the double of the size of `BigDigit`.
 pub type DoubleBigDigit = u64;
 
 pub static ZERO_BIG_DIGIT: BigDigit = 0;
@@ -70,12 +106,10 @@ pub fn to_doublebigdigit(hi: BigDigit, lo: BigDigit) -> DoubleBigDigit {
     }
 }
 
-/**
-A big unsigned integer type.
-
-A `BigUint`-typed value `BigUint { data: vec!(a, b, c) }` represents a number
-`(a + b * BigDigit::base + c * BigDigit::base^2)`.
-*/
+/// A big unsigned integer type.
+///
+/// A `BigUint`-typed value `BigUint { data: vec!(a, b, c) }` represents a number
+/// `(a + b * BigDigit::base + c * BigDigit::base^2)`.
 #[deriving(Clone)]
 pub struct BigUint {
     data: Vec<BigDigit>
@@ -460,11 +494,9 @@ fn div_estimate(a: &BigUint, b: &BigUint, n: uint)
         }
     }
 
-    /**
-     * Calculates the Greatest Common Divisor (GCD) of the number and `other`
-     *
-     * The result is always positive
-     */
+    /// Calculates the Greatest Common Divisor (GCD) of the number and `other`.
+    ///
+    /// The result is always positive.
     #[inline]
     fn gcd(&self, other: &BigUint) -> BigUint {
         // Use Euclid's algorithm
@@ -478,17 +510,15 @@ fn gcd(&self, other: &BigUint) -> BigUint {
         return n;
     }
 
-    /**
-     * Calculates the Lowest Common Multiple (LCM) of the number and `other`
-     */
+    /// Calculates the Lowest Common Multiple (LCM) of the number and `other`.
     #[inline]
     fn lcm(&self, other: &BigUint) -> BigUint { ((*self * *other) / self.gcd(other)) }
 
-    /// Returns `true` if the number can be divided by `other` without leaving a remainder
+    /// Returns `true` if the number can be divided by `other` without leaving a remainder.
     #[inline]
     fn divides(&self, other: &BigUint) -> bool { (*self % *other).is_zero() }
 
-    /// Returns `true` if the number is divisible by `2`
+    /// Returns `true` if the number is divisible by `2`.
     #[inline]
     fn is_even(&self) -> bool {
         // Considering only the last digit.
@@ -498,7 +528,7 @@ fn is_even(&self) -> bool {
         }
     }
 
-    /// Returns `true` if the number is not divisible by `2`
+    /// Returns `true` if the number is not divisible by `2`.
     #[inline]
     fn is_odd(&self) -> bool { !self.is_even() }
 }
@@ -1068,33 +1098,29 @@ fn div_mod_floor(&self, other: &BigInt) -> (BigInt, BigInt) {
         }
     }
 
-    /**
-     * Calculates the Greatest Common Divisor (GCD) of the number and `other`
-     *
-     * The result is always positive
-     */
+    /// Calculates the Greatest Common Divisor (GCD) of the number and `other`.
+    ///
+    /// The result is always positive.
     #[inline]
     fn gcd(&self, other: &BigInt) -> BigInt {
         BigInt::from_biguint(Plus, self.data.gcd(&other.data))
     }
 
-    /**
-     * Calculates the Lowest Common Multiple (LCM) of the number and `other`
-     */
+    /// Calculates the Lowest Common Multiple (LCM) of the number and `other`.
     #[inline]
     fn lcm(&self, other: &BigInt) -> BigInt {
         BigInt::from_biguint(Plus, self.data.lcm(&other.data))
     }
 
-    /// Returns `true` if the number can be divided by `other` without leaving a remainder
+    /// Returns `true` if the number can be divided by `other` without leaving a remainder.
     #[inline]
     fn divides(&self, other: &BigInt) -> bool { self.data.divides(&other.data) }
 
-    /// Returns `true` if the number is divisible by `2`
+    /// Returns `true` if the number is divisible by `2`.
     #[inline]
     fn is_even(&self) -> bool { self.data.is_even() }
 
-    /// Returns `true` if the number is not divisible by `2`
+    /// Returns `true` if the number is not divisible by `2`.
     #[inline]
     fn is_odd(&self) -> bool { self.data.is_odd() }
 }
index d958d40d3d114c435179bb67e25741367bbe5d89..bcaebbd136809e36368fc6fa95b8280b89cecf42 100644 (file)
@@ -8,18 +8,12 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-//! Integer trait and functions
+//! Integer trait and functions.
 
 pub trait Integer: Num + PartialOrd
                  + Div<Self, Self>
                  + Rem<Self, Self> {
-    /// Simultaneous truncated integer division and modulus
-    #[inline]
-    fn div_rem(&self, other: &Self) -> (Self, Self) {
-        (*self / *other, *self % *other)
-    }
-
-    /// Floored integer division
+    /// Floored integer division.
     ///
     /// # Examples
     ///
@@ -61,25 +55,103 @@ fn div_rem(&self, other: &Self) -> (Self, Self) {
     /// ~~~
     fn mod_floor(&self, other: &Self) -> Self;
 
-    /// Simultaneous floored integer division and modulus
-    fn div_mod_floor(&self, other: &Self) -> (Self, Self) {
-        (self.div_floor(other), self.mod_floor(other))
-    }
-
-    /// Greatest Common Divisor (GCD)
+    /// Greatest Common Divisor (GCD).
+    ///
+    /// # Examples
+    ///
+    /// ~~~
+    /// # use num::Integer;
+    /// assert_eq!(6i.gcd(&8), 2);
+    /// assert_eq!(7i.gcd(&3), 1);
+    /// ~~~
     fn gcd(&self, other: &Self) -> Self;
 
-    /// Lowest Common Multiple (LCM)
+    /// Lowest Common Multiple (LCM).
+    ///
+    /// # Examples
+    ///
+    /// ~~~
+    /// # use num::Integer;
+    /// assert_eq!(7i.lcm(&3), 21);
+    /// assert_eq!(2i.lcm(&4), 4);
+    /// ~~~
     fn lcm(&self, other: &Self) -> Self;
 
-    /// Returns `true` if `other` divides evenly into `self`
+    /// Returns `true` if `other` divides evenly into `self`.
+    ///
+    /// # Examples
+    ///
+    /// ~~~
+    /// # use num::Integer;
+    /// assert_eq!(9i.divides(&3), true);
+    /// assert_eq!(3i.divides(&9), false);
+    /// ~~~
     fn divides(&self, other: &Self) -> bool;
 
-    /// Returns `true` if the number is even
+    /// Returns `true` if the number is even.
+    ///
+    /// # Examples
+    ///
+    /// ~~~
+    /// # use num::Integer;
+    /// assert_eq!(3i.is_even(), false);
+    /// assert_eq!(4i.is_even(), true);
+    /// ~~~
     fn is_even(&self) -> bool;
 
-    /// Returns `true` if the number is odd
+    /// Returns `true` if the number is odd.
+    ///
+    /// # Examples
+    ///
+    /// ~~~
+    /// # use num::Integer;
+    /// assert_eq!(3i.is_odd(), true);
+    /// assert_eq!(4i.is_odd(), false);
+    /// ~~~
     fn is_odd(&self) -> bool;
+
+    /// Simultaneous truncated integer division and modulus.
+    /// Returns `(quotient, remainder)`.
+    ///
+    /// # Examples
+    ///
+    /// ~~~
+    /// # use num::Integer;
+    /// assert_eq!(( 8i).div_rem( &3), ( 2,  2));
+    /// assert_eq!(( 8i).div_rem(&-3), (-2,  2));
+    /// assert_eq!((-8i).div_rem( &3), (-2, -2));
+    /// assert_eq!((-8i).div_rem(&-3), ( 2, -2));
+    ///
+    /// assert_eq!(( 1i).div_rem( &2), ( 0,  1));
+    /// assert_eq!(( 1i).div_rem(&-2), ( 0,  1));
+    /// assert_eq!((-1i).div_rem( &2), ( 0, -1));
+    /// assert_eq!((-1i).div_rem(&-2), ( 0, -1));
+    /// ~~~
+    #[inline]
+    fn div_rem(&self, other: &Self) -> (Self, Self) {
+        (*self / *other, *self % *other)
+    }
+
+    /// Simultaneous floored integer division and modulus.
+    /// Returns `(quotient, remainder)`.
+    ///
+    /// # Examples
+    ///
+    /// ~~~
+    /// # use num::Integer;
+    /// assert_eq!(( 8i).div_mod_floor( &3), ( 2,  2));
+    /// assert_eq!(( 8i).div_mod_floor(&-3), (-3, -1));
+    /// assert_eq!((-8i).div_mod_floor( &3), (-3,  1));
+    /// assert_eq!((-8i).div_mod_floor(&-3), ( 2, -2));
+    ///
+    /// assert_eq!(( 1i).div_mod_floor( &2), ( 0,  1));
+    /// assert_eq!(( 1i).div_mod_floor(&-2), (-1, -1));
+    /// assert_eq!((-1i).div_mod_floor( &2), (-1,  1));
+    /// assert_eq!((-1i).div_mod_floor(&-2), ( 0, -1));
+    /// ~~~
+    fn div_mod_floor(&self, other: &Self) -> (Self, Self) {
+        (self.div_floor(other), self.mod_floor(other))
+    }
 }
 
 /// Simultaneous integer division and modulus
index 109d32f69b9678342caf8ea463325f0ad6d2b413..d53fed7aa80fc897ab39f9ab64c58d45b2ae5fe2 100644 (file)
@@ -235,7 +235,7 @@ fn parse(&mut self) -> Result<Ast, Error> {
                     // left paren, let's grab the old flags and see if we
                     // need a capture.
                     let (cap, cap_name, oldflags) = {
-                        let paren = self.stack.get(altfrom-1);
+                        let paren = &self.stack[altfrom-1];
                         (paren.capture(), paren.capture_name(), paren.flags())
                     };
                     try!(self.alternate(altfrom));
@@ -464,7 +464,7 @@ fn try_parse_ascii(&mut self) -> Option<Ast> {
                 Some(i) => i,
                 None => return None,
             };
-        if *self.chars.get(closer-1) != ':' {
+        if self.chars[closer-1] != ':' {
             return None
         }
         if closer - self.chari <= 3 {
@@ -519,7 +519,7 @@ fn parse_counted(&mut self) -> Result<(), Error> {
             max = Some(min);
         } else {
             let pieces: Vec<&str> = inner.as_slice().splitn(',', 1).collect();
-            let (smin, smax) = (*pieces.get(0), *pieces.get(1));
+            let (smin, smax) = (pieces[0], pieces[1]);
             if smin.len() == 0 {
                 return self.err("Max repetitions cannot be specified \
                                     without min repetitions.")
@@ -931,7 +931,7 @@ fn peek(&self, offset: uint) -> Option<char> {
         if self.chari + offset >= self.chars.len() {
             return None
         }
-        Some(*self.chars.get(self.chari + offset))
+        Some(self.chars[self.chari + offset])
     }
 
     fn peek_is(&self, offset: uint, is: char) -> bool {
@@ -939,7 +939,7 @@ fn peek_is(&self, offset: uint, is: char) -> bool {
     }
 
     fn cur(&self) -> char {
-        *self.chars.get(self.chari)
+        self.chars[self.chari]
     }
 
     fn slice(&self, start: uint, end: uint) -> String {
index 054cbb0fcd63dfa2c518f793bdeb3fd80f4599aa..8e4145b2a3198973b69ade6d83e8f6067323a78f 100644 (file)
@@ -207,7 +207,7 @@ pub fn is_match(&self, text: &str) -> bool {
     pub fn find(&self, text: &str) -> Option<(uint, uint)> {
         let caps = exec(self, Location, text);
         if has_match(&caps) {
-            Some((caps.get(0).unwrap(), caps.get(1).unwrap()))
+            Some((caps[0].unwrap(), caps[1].unwrap()))
         } else {
             None
         }
@@ -699,11 +699,11 @@ fn new(re: &Regex, search: &'t str, locs: CaptureLocs)
     /// original string matched.
     pub fn pos(&self, i: uint) -> Option<(uint, uint)> {
         let (s, e) = (i * 2, i * 2 + 1);
-        if e >= self.locs.len() || self.locs.get(s).is_none() {
+        if e >= self.locs.len() || self.locs[s].is_none() {
             // VM guarantees that each pair of locations are both Some or None.
             return None
         }
-        Some((self.locs.get(s).unwrap(), self.locs.get(e).unwrap()))
+        Some((self.locs[s].unwrap(), self.locs[e].unwrap()))
     }
 
     /// Returns the matched string for the capture group `i`.
@@ -851,7 +851,7 @@ fn next(&mut self) -> Option<Captures<'t>> {
             if !has_match(&caps) {
                 return None
             } else {
-                (caps.get(0).unwrap(), caps.get(1).unwrap())
+                (caps[0].unwrap(), caps[1].unwrap())
             };
 
         // Don't accept empty matches immediately following a match.
@@ -893,7 +893,7 @@ fn next(&mut self) -> Option<(uint, uint)> {
             if !has_match(&caps) {
                 return None
             } else {
-                (caps.get(0).unwrap(), caps.get(1).unwrap())
+                (caps[0].unwrap(), caps[1].unwrap())
             };
 
         // Don't accept empty matches immediately following a match.
@@ -922,5 +922,5 @@ fn exec_slice(re: &Regex, which: MatchKind,
 
 #[inline]
 fn has_match(caps: &CaptureLocs) -> bool {
-    caps.len() >= 2 && caps.get(0).is_some() && caps.get(1).is_some()
+    caps.len() >= 2 && caps[0].is_some() && caps[1].is_some()
 }
index 782078ced497b9d09cf139416bc9e226848d5619..b37000df02dbec436e2c862fbb26c711efbbca28 100644 (file)
@@ -123,7 +123,7 @@ fn run(&mut self) -> CaptureLocs {
         // Make sure multi-line mode isn't enabled for it, otherwise we can't
         // drop the initial .*?
         let prefix_anchor =
-            match *self.prog.insts.get(1) {
+            match self.prog.insts[1] {
                 EmptyBegin(flags) if flags & FLAG_MULTI == 0 => true,
                 _ => false,
             };
@@ -192,7 +192,7 @@ fn run(&mut self) -> CaptureLocs {
     fn step(&self, groups: &mut [Option<uint>], nlist: &mut Threads,
             caps: &mut [Option<uint>], pc: uint)
            -> StepState {
-        match *self.prog.insts.get(pc) {
+        match self.prog.insts[pc] {
             Match => {
                 match self.which {
                     Exists => {
@@ -259,7 +259,7 @@ fn add(&self, nlist: &mut Threads, pc: uint, groups: &mut [Option<uint>]) {
         //
         // We make a minor optimization by indicating that the state is "empty"
         // so that its capture groups are not filled in.
-        match *self.prog.insts.get(pc) {
+        match self.prog.insts[pc] {
             EmptyBegin(flags) => {
                 let multi = flags & FLAG_MULTI > 0;
                 nlist.add(pc, groups, true);
@@ -481,8 +481,8 @@ fn add(&mut self, pc: uint, groups: &[Option<uint>], empty: bool) {
 
     #[inline]
     fn contains(&self, pc: uint) -> bool {
-        let s = *self.sparse.get(pc);
-        s < self.size && self.queue.get(s).pc == pc
+        let s = self.sparse[pc];
+        s < self.size && self.queue[s].pc == pc
     }
 
     #[inline]
@@ -492,7 +492,7 @@ fn empty(&mut self) {
 
     #[inline]
     fn pc(&self, i: uint) -> uint {
-        self.queue.get(i).pc
+        self.queue[i].pc
     }
 
     #[inline]
index 6545163fdbb68199ccb5a98ce581631c0a3cd8aa..7163dfa3b16abf6b27035913d63e1eebf60b941c 100644 (file)
@@ -623,7 +623,7 @@ fn parse(cx: &mut ExtCtxt, tts: &[ast::TokenTree]) -> Option<String> {
                 _ => {
                     cx.span_err(entry.span, format!(
                         "expected string literal but got `{}`",
-                        pprust::lit_to_string(lit)).as_slice());
+                        pprust::lit_to_string(&*lit)).as_slice());
                     return None
                 }
             }
@@ -631,7 +631,7 @@ fn parse(cx: &mut ExtCtxt, tts: &[ast::TokenTree]) -> Option<String> {
         _ => {
             cx.span_err(entry.span, format!(
                 "expected string literal but got `{}`",
-                pprust::expr_to_string(entry)).as_slice());
+                pprust::expr_to_string(&*entry)).as_slice());
             return None
         }
     };
index 6fa8a1530234e15b4f4f8392deb327be96b0c89e..88b42dba8e99d1adf18473c70afbc7eb1f83e973 100644 (file)
@@ -186,6 +186,22 @@ pub fn run_passes(sess: &Session,
                 }
             };
 
+            let code_model = match sess.opts.cg.code_model.as_slice() {
+                "default" => llvm::CodeModelDefault,
+                "small" => llvm::CodeModelSmall,
+                "kernel" => llvm::CodeModelKernel,
+                "medium" => llvm::CodeModelMedium,
+                "large" => llvm::CodeModelLarge,
+                _ => {
+                    sess.err(format!("{} is not a valid code model",
+                                     sess.opts
+                                         .cg
+                                         .code_model).as_slice());
+                    sess.abort_if_errors();
+                    return;
+                }
+            };
+
             let tm = sess.targ_cfg
                          .target_strs
                          .target_triple
@@ -195,7 +211,7 @@ pub fn run_passes(sess: &Session,
                     target_feature(sess).with_c_str(|features| {
                         llvm::LLVMRustCreateTargetMachine(
                             t, cpu, features,
-                            llvm::CodeModelDefault,
+                            code_model,
                             reloc_model,
                             opt_level,
                             true /* EnableSegstk */,
@@ -1238,7 +1254,7 @@ fn link_args(cmd: &mut Command,
         abi::OsMacos | abi::OsiOS => {
             let morestack = lib_path.join("libmorestack.a");
 
-            let mut v = "-Wl,-force_load,".as_bytes().to_owned();
+            let mut v = b"-Wl,-force_load,".to_vec();
             v.push_all(morestack.as_vec());
             cmd.arg(v.as_slice());
         }
index 345877d9ab6c47beea8f81694eeccb00af7c462b..ee611293475f9011702f7196c5482d244e3b962a 100644 (file)
@@ -332,8 +332,12 @@ fn parse_list(slot: &mut Vec<String>, v: Option<&str>)
         "prefer dynamic linking to static linking"),
     no_integrated_as: bool = (false, parse_bool,
         "use an external assembler rather than LLVM's integrated one"),
+    no_redzone: bool = (false, parse_bool,
+        "disable the use of the redzone"),
     relocation_model: String = ("pic".to_string(), parse_string,
          "choose the relocation model to use (llc -relocation-model for details)"),
+    code_model: String = ("default".to_string(), parse_string,
+         "choose the code model to use (llc -code-model for details)"),
     metadata: Vec<String> = (Vec::new(), parse_list,
          "metadata to mangle symbol names with"),
     extra_filename: String = ("".to_string(), parse_string,
index 87693658afd03d05b41715f279b9224f29fe3faa..43aa3f9041fd97d146bbbad40a8a22fe1a6bd835 100644 (file)
@@ -799,7 +799,7 @@ fn print_flowgraph<W:io::Writer>(variants: Vec<borrowck_dot::Variant>,
     let ty_cx = &analysis.ty_cx;
     let cfg = match code {
         blocks::BlockCode(block) => cfg::CFG::new(ty_cx, &*block),
-        blocks::FnLikeCode(fn_like) => cfg::CFG::new(ty_cx, fn_like.body()),
+        blocks::FnLikeCode(fn_like) => cfg::CFG::new(ty_cx, &*fn_like.body()),
     };
     debug!("cfg: {:?}", cfg);
 
index 3fd402c90fdd87a7d8e116c4e38ef585191fbaa7..e433c3df8644c2713e179d200c17d90960ca48ac 100644 (file)
@@ -36,7 +36,7 @@
 
 
 pub fn main_args(args: &[String]) -> int {
-    let owned_args = args.to_owned();
+    let owned_args = args.to_vec();
     monitor(proc() run_compiler(owned_args.as_slice()));
     0
 }
index 62236d753ad26e8dc80ad4b8ac08fae63ce3710b..fbe4b211f975264a90578b888a30046153b2b888 100644 (file)
@@ -1433,6 +1433,9 @@ fn get_lints(&self) -> LintArray {
     }
 
     fn check_expr(&mut self, cx: &Context, e: &ast::Expr) {
+        // if the expression was produced by a macro expansion,
+        if e.span.expn_info.is_some() { return }
+
         let id = match e.node {
             ast::ExprPath(..) | ast::ExprStruct(..) => {
                 match cx.tcx.def_map.borrow().find(&e.id) {
index 5ab8eeeb36055c7242e3d192f66eb6cd4ccf6038..0adc8e915c679e2050e5f22f487ff27ad14ae549 100644 (file)
@@ -132,7 +132,8 @@ pub fn get_method(tcx: &ty::ctxt, def: ast::DefId) -> ty::Method {
 
 pub fn get_method_name_and_explicit_self(cstore: &cstore::CStore,
                                          def: ast::DefId)
-                                     -> (ast::Ident, ast::ExplicitSelf_)
+                                         -> (ast::Ident,
+                                             ty::ExplicitSelfCategory)
 {
     let cdata = cstore.get_crate_data(def.krate);
     decoder::get_method_name_and_explicit_self(cstore.intr.clone(), &*cdata, def.node)
index cc41223688ee0b9eab8f8ff7f3c6caaff54d262d..094e83d2a4770af150046c2aa7102df4ca28c3ad 100644 (file)
@@ -724,7 +724,7 @@ pub fn get_enum_variants(intr: Rc<IdentInterner>, cdata: Cmd, id: ast::NodeId,
     }).collect()
 }
 
-fn get_explicit_self(item: ebml::Doc) -> ast::ExplicitSelf_ {
+fn get_explicit_self(item: ebml::Doc) -> ty::ExplicitSelfCategory {
     fn get_mutability(ch: u8) -> ast::Mutability {
         match ch as char {
             'i' => ast::MutImmutable,
@@ -738,12 +738,15 @@ fn get_mutability(ch: u8) -> ast::Mutability {
 
     let explicit_self_kind = string.as_bytes()[0];
     match explicit_self_kind as char {
-        's' => ast::SelfStatic,
-        'v' => ast::SelfValue(special_idents::self_),
-        '~' => ast::SelfUniq(special_idents::self_),
+        's' => ty::StaticExplicitSelfCategory,
+        'v' => ty::ByValueExplicitSelfCategory,
+        '~' => ty::ByBoxExplicitSelfCategory,
         // FIXME(#4846) expl. region
-        '&' => ast::SelfRegion(None, get_mutability(string.as_bytes()[1]),
-                               special_idents::self_),
+        '&' => {
+            ty::ByReferenceExplicitSelfCategory(
+                ty::ReEmpty,
+                get_mutability(string.as_bytes()[1]))
+        }
         _ => fail!("unknown self type code: `{}`", explicit_self_kind as char)
     }
 }
@@ -761,11 +764,11 @@ pub fn get_impl_methods(cdata: Cmd, impl_id: ast::NodeId) -> Vec<ast::DefId> {
     methods
 }
 
-pub fn get_method_name_and_explicit_self(
-    intr: Rc<IdentInterner>,
-    cdata: Cmd,
-    id: ast::NodeId) -> (ast::Ident, ast::ExplicitSelf_)
-{
+pub fn get_method_name_and_explicit_self(intr: Rc<IdentInterner>,
+                                         cdata: Cmd,
+                                         id: ast::NodeId)
+                                         -> (ast::Ident,
+                                             ty::ExplicitSelfCategory) {
     let method_doc = lookup_item(id, cdata.data());
     let name = item_name(&*intr, method_doc);
     let explicit_self = get_explicit_self(method_doc);
index 0a050850fe907f9cb091541d51a3d234b5e159bb..a3389ef86e551e8b03962757bd9da3b637e1fcdb 100644 (file)
@@ -402,7 +402,7 @@ fn encode_reexported_static_base_methods(ecx: &EncodeContext,
             for base_impl_did in implementations.borrow().iter() {
                 for &method_did in impl_methods.get(base_impl_did).iter() {
                     let m = ty::method(ecx.tcx, method_did);
-                    if m.explicit_self == ast::SelfStatic {
+                    if m.explicit_self == ty::StaticExplicitSelfCategory {
                         encode_reexported_static_method(ebml_w, exp, m.def_id, m.ident);
                     }
                 }
@@ -421,7 +421,7 @@ fn encode_reexported_static_trait_methods(ecx: &EncodeContext,
     match ecx.tcx.trait_methods_cache.borrow().find(&exp.def_id) {
         Some(methods) => {
             for m in methods.iter() {
-                if m.explicit_self == ast::SelfStatic {
+                if m.explicit_self == ty::StaticExplicitSelfCategory {
                     encode_reexported_static_method(ebml_w, exp, m.def_id, m.ident);
                 }
             }
@@ -623,15 +623,22 @@ fn encode_visibility(ebml_w: &mut Encoder, visibility: Visibility) {
     ebml_w.end_tag();
 }
 
-fn encode_explicit_self(ebml_w: &mut Encoder, explicit_self: ast::ExplicitSelf_) {
+fn encode_explicit_self(ebml_w: &mut Encoder,
+                        explicit_self: &ty::ExplicitSelfCategory) {
     ebml_w.start_tag(tag_item_trait_method_explicit_self);
 
     // Encode the base self type.
-    match explicit_self {
-        SelfStatic   => { ebml_w.writer.write(&[ 's' as u8 ]); }
-        SelfValue(_) => { ebml_w.writer.write(&[ 'v' as u8 ]); }
-        SelfUniq(_)  => { ebml_w.writer.write(&[ '~' as u8 ]); }
-        SelfRegion(_, m, _) => {
+    match *explicit_self {
+        ty::StaticExplicitSelfCategory => {
+            ebml_w.writer.write(&[ 's' as u8 ]);
+        }
+        ty::ByValueExplicitSelfCategory => {
+            ebml_w.writer.write(&[ 'v' as u8 ]);
+        }
+        ty::ByBoxExplicitSelfCategory => {
+            ebml_w.writer.write(&[ '~' as u8 ]);
+        }
+        ty::ByReferenceExplicitSelfCategory(_, m) => {
             // FIXME(#4846) encode custom lifetime
             ebml_w.writer.write(&['&' as u8]);
             encode_mutability(ebml_w, m);
@@ -748,10 +755,10 @@ fn encode_method_ty_fields(ecx: &EncodeContext,
                               tag_item_method_tps);
     encode_method_fty(ecx, ebml_w, &method_ty.fty);
     encode_visibility(ebml_w, method_ty.vis);
-    encode_explicit_self(ebml_w, method_ty.explicit_self);
+    encode_explicit_self(ebml_w, &method_ty.explicit_self);
     let fn_style = method_ty.fty.fn_style;
     match method_ty.explicit_self {
-        ast::SelfStatic => {
+        ty::StaticExplicitSelfCategory => {
             encode_family(ebml_w, fn_style_static_method_family(fn_style));
         }
         _ => encode_family(ebml_w, style_fn_family(fn_style))
@@ -1206,7 +1213,7 @@ fn add_to_index(item: &Item, ebml_w: &Encoder,
             encode_path(ebml_w, path.clone().chain(Some(elem).move_iter()));
 
             match method_ty.explicit_self {
-                SelfStatic => {
+                ty::StaticExplicitSelfCategory => {
                     encode_family(ebml_w,
                                   fn_style_static_method_family(
                                       method_ty.fty.fn_style));
@@ -1233,7 +1240,7 @@ fn add_to_index(item: &Item, ebml_w: &Encoder,
                     encode_attributes(ebml_w, m.attrs.as_slice());
                     // If this is a static method, we've already encoded
                     // this.
-                    if method_ty.explicit_self != SelfStatic {
+                    if method_ty.explicit_self != ty::StaticExplicitSelfCategory {
                         // FIXME: I feel like there is something funny going on.
                         let pty = ty::lookup_item_type(tcx, method_def_id);
                         encode_bounds_and_type(ebml_w, ecx, &pty);
@@ -1241,7 +1248,7 @@ fn add_to_index(item: &Item, ebml_w: &Encoder,
                     encode_method_sort(ebml_w, 'p');
                     encode_inlined_item(ecx, ebml_w,
                                         IIMethodRef(def_id, true, &*m));
-                    encode_method_argument_names(ebml_w, m.pe_fn_decl());
+                    encode_method_argument_names(ebml_w, &*m.pe_fn_decl());
                 }
             }
 
index c15148f75df2242b9c5915ac113f1ac5d14ec811..99b98b690fa667faf2e6f55c82ebd6e8182fbf96 100644 (file)
@@ -46,7 +46,7 @@ pub fn for_each_lib_search_path(&self, f: |&Path| -> FileMatch) {
                 FileMatches => found = true,
                 FileDoesntMatch => ()
             }
-            visited_dirs.insert(path.as_vec().to_owned());
+            visited_dirs.insert(path.as_vec().to_vec());
         }
 
         debug!("filesearch: searching lib path");
@@ -59,7 +59,7 @@ pub fn for_each_lib_search_path(&self, f: |&Path| -> FileMatch) {
             }
         }
 
-        visited_dirs.insert(tlib_path.as_vec().to_owned());
+        visited_dirs.insert(tlib_path.as_vec().to_vec());
         // Try RUST_PATH
         if !found {
             let rustpath = rust_path();
@@ -67,10 +67,10 @@ pub fn for_each_lib_search_path(&self, f: |&Path| -> FileMatch) {
                 let tlib_path = make_rustpkg_lib_path(
                     self.sysroot, path, self.triple);
                 debug!("is {} in visited_dirs? {:?}", tlib_path.display(),
-                        visited_dirs.contains_equiv(&tlib_path.as_vec().to_owned()));
+                        visited_dirs.contains_equiv(&tlib_path.as_vec().to_vec()));
 
                 if !visited_dirs.contains_equiv(&tlib_path.as_vec()) {
-                    visited_dirs.insert(tlib_path.as_vec().to_owned());
+                    visited_dirs.insert(tlib_path.as_vec().to_vec());
                     // Don't keep searching the RUST_PATH if one match turns up --
                     // if we did, we'd get a "multiple matching crates" error
                     match f(&tlib_path) {
index b207543398aaa2ec6b18df2ffbb1c74a754f39a1..bcd6f3ac91abc8ed64984806e1f2a723538570f6 100644 (file)
@@ -267,7 +267,7 @@ fn enc_sty(w: &mut MemWriter, cx: &ctxt, st: &ty::sty) {
         }
         ty::ty_closure(ref f) => {
             mywrite!(w, "f");
-            enc_closure_ty(w, cx, *f);
+            enc_closure_ty(w, cx, &**f);
         }
         ty::ty_bare_fn(ref f) => {
             mywrite!(w, "F");
index 9240547874fd83291e82a6c50ce90b4ae9318300..fd10fd3c35aae4f5fa7f48f51b451bc8ff8e8b89 100644 (file)
@@ -1557,7 +1557,7 @@ fn eq_int(a: int, b: int) -> bool { a == b }
             return alist {eq_fn: eq_int, data: Vec::new()};
         }
     ).unwrap();
-    let item_in = e::IIItemRef(item);
+    let item_in = e::IIItemRef(&*item);
     let item_out = simplify_ast(item_in);
     let item_exp = ast::IIItem(quote_item!(cx,
         fn new_int_alist<B>() -> alist<int, B> {
@@ -1566,7 +1566,8 @@ fn new_int_alist<B>() -> alist<int, B> {
     ).unwrap());
     match (item_out, item_exp) {
       (ast::IIItem(item_out), ast::IIItem(item_exp)) => {
-        assert!(pprust::item_to_string(item_out) == pprust::item_to_string(item_exp));
+        assert!(pprust::item_to_string(&*item_out) ==
+                pprust::item_to_string(&*item_exp));
       }
       _ => fail!()
     }
index 77b3cfafa63afaa26d6f05fabd7052f212259d82..5604d33496d9dfc0e6f37d9831abc8b4eaa732b5 100644 (file)
@@ -216,8 +216,13 @@ pub fn build_borrowck_dataflow_data_for_fn<'a>(
 
     let p = input.fn_parts;
 
-    let dataflow_data = build_borrowck_dataflow_data(
-        &mut bccx, &p.kind, p.decl, input.cfg, p.body, p.span, p.id);
+    let dataflow_data = build_borrowck_dataflow_data(&mut bccx,
+                                                     &p.kind,
+                                                     &*p.decl,
+                                                     input.cfg,
+                                                     &*p.body,
+                                                     p.span,
+                                                     p.id);
 
     (bccx, dataflow_data)
 }
index 832b222ef1641200c1e38618a25bf1156ddb415c..066837afac94a008f1b56aadb3f8ddcc2ecdbb36 100644 (file)
@@ -47,7 +47,9 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
 
         let &Matrix(ref m) = self;
         let pretty_printed_matrix: Vec<Vec<String>> = m.iter().map(|row| {
-            row.iter().map(|&pat| pat_to_string(pat)).collect::<Vec<String>>()
+            row.iter()
+               .map(|&pat| pat_to_string(&*pat))
+               .collect::<Vec<String>>()
         }).collect();
 
         let column_count = m.iter().map(|row| row.len()).max().unwrap_or(0u);
index b28c0158584e6c96a06c054a5115ce14fa429d19..e9c7a1cccb3e0060fe4c06d219afe8c5375facf6 100644 (file)
@@ -369,7 +369,7 @@ pub fn each_bit_for_node(&self,
         let slice = match e {
             Entry => on_entry,
             Exit => {
-                let mut t = on_entry.to_owned();
+                let mut t = on_entry.to_vec();
                 self.apply_gen_kill_frozen(cfgidx, t.as_mut_slice());
                 temp_bits = t;
                 temp_bits.as_slice()
@@ -445,7 +445,7 @@ pub fn add_kills_from_flow_exits(&mut self, cfg: &cfg::CFG) {
         cfg.graph.each_edge(|_edge_index, edge| {
             let flow_exit = edge.source();
             let (start, end) = self.compute_id_range(flow_exit);
-            let mut orig_kills = self.kills.slice(start, end).to_owned();
+            let mut orig_kills = self.kills.slice(start, end).to_vec();
 
             let mut changed = false;
             for &node_id in edge.data.exiting_scopes.iter() {
index 8f01ee0564d19635e218d920b1d63486a1fe0910..33e7554084ac64fb361884a10259e3f6931b1416 100644 (file)
@@ -212,7 +212,7 @@ fn visit_node(&mut self, node: &ast_map::Node) {
                 visit::walk_trait_method(self, &*trait_method, ctxt);
             }
             ast_map::NodeMethod(method) => {
-                visit::walk_block(self, method.pe_body(), ctxt);
+                visit::walk_block(self, &*method.pe_body(), ctxt);
             }
             ast_map::NodeForeignItem(foreign_item) => {
                 visit::walk_foreign_item(self, &*foreign_item, ctxt);
@@ -520,7 +520,9 @@ fn visit_struct_field(&mut self, field: &ast::StructField, _: ()) {
     // Overwrite so that we don't warn the trait method itself.
     fn visit_trait_method(&mut self, trait_method: &ast::TraitMethod, _: ()) {
         match *trait_method {
-            ast::Provided(ref method) => visit::walk_block(self, method.pe_body(), ()),
+            ast::Provided(ref method) => {
+                visit::walk_block(self, &*method.pe_body(), ())
+            }
             ast::Required(_) => ()
         }
     }
index b228a82bdf7b1bf7fd39ded7367dc2bf9ce0989d..e404ce85663757beddd3c7115039788b0e1affc6 100644 (file)
@@ -316,14 +316,14 @@ fn propagate_node(&mut self, node: &ast_map::Node,
                         // Keep going, nothing to get exported
                     }
                     ast::Provided(ref method) => {
-                        visit::walk_block(self, method.pe_body(), ())
+                        visit::walk_block(self, &*method.pe_body(), ())
                     }
                 }
             }
             ast_map::NodeMethod(method) => {
                 let did = self.tcx.map.get_parent_did(search_item);
                 if method_might_be_inlined(self.tcx, &*method, did) {
-                    visit::walk_block(self, method.pe_body(), ())
+                    visit::walk_block(self, &*method.pe_body(), ())
                 }
             }
             // Nothing to recurse on for these
index df4d3b7efe432ea6ffada1db2c3bac9569f4bc8e..822a43f2619dc4496ff7d0fa68b4d3b1d519e553 100644 (file)
@@ -314,6 +314,16 @@ pub fn is_subregion_of(&self,
                     self.sub_free_region(sub_fr, super_fr)
                 }
 
+                (ty::ReEarlyBound(param_id_a, param_space_a, index_a, _),
+                 ty::ReEarlyBound(param_id_b, param_space_b, index_b, _)) => {
+                    // This case is used only to make sure that explicitly-
+                    // specified `Self` types match the real self type in
+                    // implementations.
+                    param_id_a == param_id_b &&
+                        param_space_a == param_space_b &&
+                        index_a == index_b
+                }
+
                 _ => {
                     false
                 }
index 40237e7984f6c6bf4a741cfd1a241f3149e17db0..5bea24dfa90f6d53385099d5dbdbb7f2c7349822 100644 (file)
 #![allow(non_camel_case_types)]
 
 use driver::session::Session;
+use lint;
 use metadata::csearch;
 use metadata::decoder::{DefLike, DlDef, DlField, DlImpl};
 use middle::def::*;
 use middle::lang_items::LanguageItems;
 use middle::pat_util::pat_bindings;
 use middle::subst::{ParamSpace, FnSpace, TypeSpace};
-use lint;
+use middle::ty::{ExplicitSelfCategory, StaticExplicitSelfCategory};
 use util::nodemap::{NodeMap, DefIdSet, FnvHashMap};
 
 use syntax::ast::*;
@@ -287,6 +288,24 @@ enum ModulePrefixResult {
     PrefixFound(Rc<Module>, uint)
 }
 
+#[deriving(Clone, Eq, PartialEq)]
+enum MethodIsStaticFlag {
+    MethodIsNotStatic,
+    MethodIsStatic,
+}
+
+impl MethodIsStaticFlag {
+    fn from_explicit_self_category(explicit_self_category:
+                                   ExplicitSelfCategory)
+                                   -> MethodIsStaticFlag {
+        if explicit_self_category == StaticExplicitSelfCategory {
+            MethodIsStatic
+        } else {
+            MethodIsNotStatic
+        }
+    }
+}
+
 #[deriving(PartialEq)]
 enum NameSearchType {
     /// We're doing a name search in order to resolve a `use` directive.
@@ -805,7 +824,8 @@ struct Resolver<'a> {
 
     graph_root: NameBindings,
 
-    method_map: RefCell<FnvHashMap<(Name, DefId), ast::ExplicitSelf_>>,
+    method_map: RefCell<FnvHashMap<(Name, DefId), MethodIsStaticFlag>>,
+
     structs: FnvHashMap<DefId, Vec<Name>>,
 
     // The number of imports that are currently unresolved.
@@ -1361,17 +1381,19 @@ fn build_reduced_graph_for_item(&mut self,
                     let ident = ty_m.ident;
 
                     // Add it as a name in the trait module.
-                    let def = match ty_m.explicit_self.node {
+                    let (def, static_flag) = match ty_m.explicit_self.node {
                         SelfStatic => {
                             // Static methods become `def_static_method`s.
-                            DefStaticMethod(local_def(ty_m.id),
+                            (DefStaticMethod(local_def(ty_m.id),
                                               FromTrait(local_def(item.id)),
-                                              ty_m.fn_style)
+                                              ty_m.fn_style),
+                             MethodIsStatic)
                         }
                         _ => {
                             // Non-static methods become `def_method`s.
-                            DefMethod(local_def(ty_m.id),
-                                       Some(local_def(item.id)))
+                            (DefMethod(local_def(ty_m.id),
+                                       Some(local_def(item.id))),
+                             MethodIsNotStatic)
                         }
                     };
 
@@ -1382,8 +1404,9 @@ fn build_reduced_graph_for_item(&mut self,
                                        ty_m.span);
                     method_name_bindings.define_value(def, ty_m.span, true);
 
-                    self.method_map.borrow_mut().insert((ident.name, def_id),
-                                                        ty_m.explicit_self.node);
+                    self.method_map
+                        .borrow_mut()
+                        .insert((ident.name, def_id), static_flag);
                 }
 
                 name_bindings.define_type(DefTrait(def_id), sp, is_public);
@@ -1670,7 +1693,11 @@ fn handle_external_def(&mut self,
                           trait method '{}'",
                          token::get_ident(method_name));
 
-                  self.method_map.borrow_mut().insert((method_name.name, def_id), explicit_self);
+                  self.method_map
+                      .borrow_mut()
+                      .insert((method_name.name, def_id),
+                              MethodIsStaticFlag::from_explicit_self_category(
+                                  explicit_self));
 
                   if is_exported {
                       self.external_exports.insert(method_def_id);
@@ -3678,6 +3705,13 @@ fn resolve_item(&mut self, item: &Item) {
                                     this.resolve_type(&*argument.ty);
                                 }
 
+                                match ty_m.explicit_self.node {
+                                    SelfExplicit(ref typ, _) => {
+                                        this.resolve_type(&**typ)
+                                    }
+                                    _ => {}
+                                }
+
                                 this.resolve_type(&*ty_m.decl.output);
                             });
                           }
@@ -4009,7 +4043,14 @@ fn resolve_method(&mut self,
                                                 method.id,
                                                 rib_kind);
 
-        self.resolve_function(rib_kind, Some(method.pe_fn_decl()), type_parameters,
+        match method.pe_explicit_self().node {
+            SelfExplicit(ref typ, _) => self.resolve_type(&**typ),
+            _ => {}
+        }
+
+        self.resolve_function(rib_kind,
+                              Some(method.pe_fn_decl()),
+                              type_parameters,
                               method.pe_body());
     }
 
@@ -4765,7 +4806,7 @@ fn resolve_module_relative_path(&mut self,
                 match containing_module.def_id.get() {
                     Some(def_id) => {
                         match self.method_map.borrow().find(&(ident.name, def_id)) {
-                            Some(x) if *x == SelfStatic => (),
+                            Some(&MethodIsStatic) => (),
                             None => (),
                             _ => {
                                 debug!("containing module was a trait or impl \
@@ -5037,7 +5078,7 @@ fn get_module(this: &mut Resolver, span: Span, ident_path: &[ast::Ident])
                 let path_str = self.path_idents_to_string(&trait_ref.path);
 
                 match method_map.find(&(name, did)) {
-                    Some(&SelfStatic) => return StaticTraitMethod(path_str),
+                    Some(&MethodIsStatic) => return StaticTraitMethod(path_str),
                     Some(_) => return TraitMethod,
                     None => {}
                 }
index 9ae2a4c62cd546b022ec93109f49e83bda55fceb..2778764d6fada0b2cb52d7f3ae918750cd0e0b79 100644 (file)
@@ -356,9 +356,10 @@ fn process_method(&mut self, method: &ast::Method, e:DxrVisitorEnv) {
         for arg in method.pe_fn_decl().inputs.iter() {
             self.visit_ty(&*arg.ty, e);
         }
-        self.visit_ty(method.pe_fn_decl().output, e);
+        self.visit_ty(&*method.pe_fn_decl().output, e);
         // walk the fn body
-        self.visit_block(method.pe_body(), DxrVisitorEnv::new_nested(method.id));
+        self.visit_block(&*method.pe_body(),
+                         DxrVisitorEnv::new_nested(method.id));
 
         self.process_generic_params(method.pe_generics(),
                                     method.span,
@@ -1136,10 +1137,11 @@ fn visit_view_item(&mut self, i:&ast::ViewItem, e:DxrVisitorEnv) {
                 }
             },
             ast::ViewItemExternCrate(ident, ref s, id) => {
-                let name = get_ident(ident).get().to_owned();
+                let name = get_ident(ident);
+                let name = name.get();
                 let s = match *s {
-                    Some((ref s, _)) => s.get().to_owned(),
-                    None => name.to_owned(),
+                    Some((ref s, _)) => s.get().to_string(),
+                    None => name.to_string(),
                 };
                 let sub_span = self.span.sub_span_after_keyword(i.span, keywords::Crate);
                 let cnum = match self.sess.cstore.find_extern_mod_stmt_cnum(id) {
@@ -1150,7 +1152,7 @@ fn visit_view_item(&mut self, i:&ast::ViewItem, e:DxrVisitorEnv) {
                                           sub_span,
                                           id,
                                           cnum,
-                                          name.as_slice(),
+                                          name,
                                           s.as_slice(),
                                           e.cur_scope);
             },
@@ -1273,9 +1275,9 @@ fn visit_arm(&mut self, arm: &ast::Arm, e: DxrVisitorEnv) {
         // process collected paths
         for &(id, ref p, ref immut, ref_kind) in self.collected_paths.iter() {
             let value = if *immut {
-                self.span.snippet(p.span).into_owned()
+                self.span.snippet(p.span).into_string()
             } else {
-                "<mutable>".to_owned()
+                "<mutable>".to_string()
             };
             let sub_span = self.span.span_for_first_ident(p.span);
             let def_map = self.analysis.ty_cx.def_map.borrow();
@@ -1330,7 +1332,7 @@ fn visit_local(&mut self, l:&ast::Local, e: DxrVisitorEnv) {
         let value = self.span.snippet(l.span);
 
         for &(id, ref p, ref immut, _) in self.collected_paths.iter() {
-            let value = if *immut { value.to_owned() } else { "<mutable>".to_owned() };
+            let value = if *immut { value.to_string() } else { "<mutable>".to_string() };
             let types = self.analysis.ty_cx.node_types.borrow();
             let typ = ppaux::ty_to_string(&self.analysis.ty_cx, *types.get(&(id as uint)));
             // Get the span only for the name of the variable (I hope the path
index 7869aec1683c20c115814223a1e706ecb478b516..1af6fde02afa4e69a09cdf91514fa0318e22c262 100644 (file)
@@ -170,7 +170,7 @@ pub fn make_values_str(&self,
                 String::from_str(v)
             }
         )));
-        Some(strs.fold(String::new(), |s, ss| s.append(ss.as_slice()))).map(|s| s.into_owned())
+        Some(strs.fold(String::new(), |s, ss| s.append(ss.as_slice())))
     }
 
     pub fn record_without_span(&mut self,
@@ -503,7 +503,7 @@ pub fn meth_call_str(&mut self,
         };
         let (dcn, dck) = match declid {
             Some(declid) => (s!(declid.node), s!(declid.krate)),
-            None => ("".to_owned(), "".to_owned())
+            None => ("".to_string(), "".to_string())
         };
         self.check_and_record(MethodCall,
                               span,
index 958d2cd3774315fa4da1a53a44b2e2e7c00a6e86..75224883cf37f1b312a89fc05a1a0e180573c78c 100644 (file)
@@ -491,7 +491,7 @@ fn enter_default<'a, 'b>(
 
     // Collect all of the matches that can match against anything.
     enter_match(bcx, dm, m, col, val, |pats| {
-        if pat_is_binding_or_wild(dm, pats[col]) {
+        if pat_is_binding_or_wild(dm, &*pats[col]) {
             Some(Vec::from_slice(pats.slice_to(col)).append(pats.slice_from(col + 1)))
         } else {
             None
@@ -546,8 +546,10 @@ fn enter_opt<'a, 'b>(
     let _indenter = indenter();
 
     let ctor = match opt {
-        &lit(x) => check_match::ConstantValue(const_eval::eval_const_expr(
-            bcx.tcx(), lit_to_expr(bcx.tcx(), &x))),
+        &lit(x) => {
+            check_match::ConstantValue(const_eval::eval_const_expr(
+                bcx.tcx(), &*lit_to_expr(bcx.tcx(), &x)))
+        }
         &range(ref lo, ref hi) => check_match::ConstantRange(
             const_eval::eval_const_expr(bcx.tcx(), &**lo),
             const_eval::eval_const_expr(bcx.tcx(), &**hi)
index 6bcc9b9b745b7f5e438842de8b7bbcb9774c4a6e..3ca188cf2813afbdcae39d8e35cda3dd7aa235a7 100644 (file)
@@ -193,6 +193,14 @@ fn decl_fn(ccx: &CrateContext, name: &str, cc: llvm::CallConv,
         _ => {}
     }
 
+    if ccx.tcx.sess.opts.cg.no_redzone {
+        unsafe {
+            llvm::LLVMAddFunctionAttribute(llfn,
+                                           llvm::FunctionIndex as c_uint,
+                                           llvm::NoRedZoneAttribute as uint64_t)
+        }
+    }
+
     llvm::SetFunctionCallConv(llfn, cc);
     // Function addresses in Rust are never significant, allowing functions to be merged.
     llvm::SetUnnamedAddr(llfn, true);
index 49b6f02356091ce2acafcb286008b60d4a0198e4..8ecdf907fc465b14e7238ac0e884f25c4a4a2b48 100644 (file)
@@ -799,15 +799,16 @@ pub fn create_global_var_metadata(cx: &CrateContext,
                                    var_item).as_slice())
     };
 
-    let filename = span_start(cx, span).file.name.clone();
-    let file_metadata = file_metadata(cx, filename.as_slice());
+    let (file_metadata, line_number) = if span != codemap::DUMMY_SP {
+        let loc = span_start(cx, span);
+        (file_metadata(cx, loc.file.name.as_slice()), loc.line as c_uint)
+    } else {
+        (UNKNOWN_FILE_METADATA, UNKNOWN_LINE_NUMBER)
+    };
 
     let is_local_to_unit = is_node_local_to_unit(cx, node_id);
-    let loc = span_start(cx, span);
-
     let variable_type = ty::node_id_to_type(cx.tcx(), node_id);
     let type_metadata = type_metadata(cx, variable_type, span);
-
     let namespace_node = namespace_for_item(cx, ast_util::local_def(node_id));
     let var_name = token::get_ident(ident).get().to_string();
     let linkage_name =
@@ -822,7 +823,7 @@ pub fn create_global_var_metadata(cx: &CrateContext,
                                                         var_name,
                                                         linkage_name,
                                                         file_metadata,
-                                                        loc.line as c_uint,
+                                                        line_number,
                                                         type_metadata,
                                                         is_local_to_unit,
                                                         global,
index f9c5f82fb29ac2ff42d86c520cd13625f0f10c38..ba44314d962acd6e3d00bcf50aa69e7713894b3c 100644 (file)
@@ -68,8 +68,13 @@ pub fn trans_impl(ccx: &CrateContext,
     for method in methods.iter() {
         if method.pe_generics().ty_params.len() == 0u {
             let llfn = get_item_val(ccx, method.id);
-            trans_fn(ccx, method.pe_fn_decl(), method.pe_body(),
-                     llfn, &param_substs::empty(), method.id, []);
+            trans_fn(ccx,
+                     &*method.pe_fn_decl(),
+                     &*method.pe_body(),
+                     llfn,
+                     &param_substs::empty(),
+                     method.id,
+                     []);
         } else {
             let mut v = TransItemVisitor{ ccx: ccx };
             visit::walk_method_helper(&mut v, &**method, ());
@@ -502,15 +507,12 @@ fn emit_vtable_methods(bcx: &Block,
                                                        ExprId(0),
                                                        substs.clone(),
                                                        vtables.clone());
-            match m.explicit_self {
-                ast::SelfValue(_) => {
-                    fn_ref = trans_unboxing_shim(bcx,
-                                                 fn_ref,
-                                                 &*m,
-                                                 m_id,
-                                                 substs.clone());
-                },
-                _ => {}
+            if m.explicit_self == ty::ByValueExplicitSelfCategory {
+                fn_ref = trans_unboxing_shim(bcx,
+                                             fn_ref,
+                                             &*m,
+                                             m_id,
+                                             substs.clone());
             }
             fn_ref
         }
index dc69e3fd6399d3ca908321078e7bca9233e5671d..95ec43738308ebe04cd04597a5f5337bb64eed52 100644 (file)
@@ -85,7 +85,7 @@ pub struct Method {
     pub ident: ast::Ident,
     pub generics: ty::Generics,
     pub fty: BareFnTy,
-    pub explicit_self: ast::ExplicitSelf_,
+    pub explicit_self: ExplicitSelfCategory,
     pub vis: ast::Visibility,
     pub def_id: ast::DefId,
     pub container: MethodContainer,
@@ -98,7 +98,7 @@ impl Method {
     pub fn new(ident: ast::Ident,
                generics: ty::Generics,
                fty: BareFnTy,
-               explicit_self: ast::ExplicitSelf_,
+               explicit_self: ExplicitSelfCategory,
                vis: ast::Visibility,
                def_id: ast::DefId,
                container: MethodContainer,
@@ -311,6 +311,9 @@ pub struct ctxt {
     /// (inferred) variance.
     pub item_variance_map: RefCell<DefIdMap<Rc<ItemVariances>>>,
 
+    /// True if the variance has been computed yet; false otherwise.
+    pub variance_computed: Cell<bool>,
+
     /// A mapping from the def ID of an enum or struct type to the def ID
     /// of the method that implements its destructor. If the type is not
     /// present in this map, it does not have a destructor. This map is
@@ -1055,6 +1058,7 @@ pub fn mk_ctxt(s: Session,
     ctxt {
         named_region_map: named_region_map,
         item_variance_map: RefCell::new(DefIdMap::new()),
+        variance_computed: Cell::new(false),
         interner: RefCell::new(FnvHashMap::new()),
         next_id: Cell::new(primitives::LAST_PRIMITIVE_ID),
         sess: s,
@@ -2034,7 +2038,7 @@ fn tc_ty(cx: &ctxt,
             }
 
             ty_closure(ref c) => {
-                closure_contents(cx, *c)
+                closure_contents(cx, &**c)
             }
 
             ty_box(typ) => {
@@ -4767,3 +4771,13 @@ fn upvar_borrow(&self, upvar_id: ty::UpvarId) -> ty::UpvarBorrow {
         self.upvar_borrow_map.borrow().get_copy(&upvar_id)
     }
 }
+
+/// The category of explicit self.
+#[deriving(Clone, Eq, PartialEq)]
+pub enum ExplicitSelfCategory {
+    StaticExplicitSelfCategory,
+    ByValueExplicitSelfCategory,
+    ByReferenceExplicitSelfCategory(Region, ast::Mutability),
+    ByBoxExplicitSelfCategory,
+}
+
index 5ed92b305be0d1c4da438ea9fc1e247b4941f6f2..6d215282cc45d34e7ddc6c4d8032218446041b78 100644 (file)
 use middle::const_eval;
 use middle::def;
 use middle::lang_items::FnMutTraitLangItem;
-use rl = middle::resolve_lifetime;
 use middle::subst::{FnSpace, TypeSpace, SelfSpace, Subst, Substs};
 use middle::ty;
-use middle::typeck::TypeAndSubsts;
-use middle::typeck::lookup_def_tcx;
+use middle::ty_fold::TypeFolder;
 use middle::typeck::rscope::RegionScope;
-use middle::typeck::rscope;
+use middle::typeck::{TypeAndSubsts, infer, lookup_def_tcx, rscope};
+use middle::typeck;
+use rl = middle::resolve_lifetime;
 use util::ppaux::Repr;
 
 use std::rc::Rc;
@@ -900,58 +900,73 @@ pub fn ty_of_arg<AC: AstConv, RS: RegionScope>(this: &AC, rscope: &RS, a: &ast::
     }
 }
 
-struct SelfInfo {
+struct SelfInfo<'a> {
     untransformed_self_ty: ty::t,
-    explicit_self: ast::ExplicitSelf
+    explicit_self: ast::ExplicitSelf,
 }
 
 pub fn ty_of_method<AC:AstConv>(
-    this: &AC,
-    id: ast::NodeId,
-    fn_style: ast::FnStyle,
-    untransformed_self_ty: ty::t,
-    explicit_self: ast::ExplicitSelf,
-    decl: &ast::FnDecl)
-    -> ty::BareFnTy
-{
-    ty_of_method_or_bare_fn(this, id, fn_style, abi::Rust, Some(SelfInfo {
+                    this: &AC,
+                    id: ast::NodeId,
+                    fn_style: ast::FnStyle,
+                    untransformed_self_ty: ty::t,
+                    explicit_self: ast::ExplicitSelf,
+                    decl: &ast::FnDecl)
+                    -> (ty::BareFnTy, ty::ExplicitSelfCategory) {
+    let self_info = Some(SelfInfo {
         untransformed_self_ty: untransformed_self_ty,
-        explicit_self: explicit_self
-    }), decl)
+        explicit_self: explicit_self,
+    });
+    let (bare_fn_ty, optional_explicit_self_category) =
+        ty_of_method_or_bare_fn(this,
+                                id,
+                                fn_style,
+                                abi::Rust,
+                                self_info,
+                                decl);
+    (bare_fn_ty, optional_explicit_self_category.unwrap())
 }
 
 pub fn ty_of_bare_fn<AC:AstConv>(this: &AC, id: ast::NodeId,
                                  fn_style: ast::FnStyle, abi: abi::Abi,
                                  decl: &ast::FnDecl) -> ty::BareFnTy {
-    ty_of_method_or_bare_fn(this, id, fn_style, abi, None, decl)
+    let (bare_fn_ty, _) =
+        ty_of_method_or_bare_fn(this, id, fn_style, abi, None, decl);
+    bare_fn_ty
 }
 
-fn ty_of_method_or_bare_fn<AC:AstConv>(this: &AC, id: ast::NodeId,
-                                       fn_style: ast::FnStyle, abi: abi::Abi,
-                                       opt_self_info: Option<SelfInfo>,
-                                       decl: &ast::FnDecl) -> ty::BareFnTy {
+fn ty_of_method_or_bare_fn<AC:AstConv>(
+                           this: &AC,
+                           id: ast::NodeId,
+                           fn_style: ast::FnStyle,
+                           abi: abi::Abi,
+                           opt_self_info: Option<SelfInfo>,
+                           decl: &ast::FnDecl)
+                           -> (ty::BareFnTy,
+                               Option<ty::ExplicitSelfCategory>) {
     debug!("ty_of_method_or_bare_fn");
 
     // new region names that appear inside of the fn decl are bound to
     // that function type
     let rb = rscope::BindingRscope::new(id);
 
+    let mut explicit_self_category_result = None;
     let self_ty = opt_self_info.and_then(|self_info| {
-        match self_info.explicit_self.node {
-            ast::SelfStatic => None,
-            ast::SelfValue(_) => {
+        // Figure out and record the explicit self category.
+        let explicit_self_category =
+            determine_explicit_self_category(this, &rb, &self_info);
+        explicit_self_category_result = Some(explicit_self_category);
+        match explicit_self_category {
+            ty::StaticExplicitSelfCategory => None,
+            ty::ByValueExplicitSelfCategory => {
                 Some(self_info.untransformed_self_ty)
             }
-            ast::SelfRegion(ref lifetime, mutability, _) => {
-                let region =
-                    opt_ast_region_to_region(this, &rb,
-                                             self_info.explicit_self.span,
-                                             lifetime);
+            ty::ByReferenceExplicitSelfCategory(region, mutability) => {
                 Some(ty::mk_rptr(this.tcx(), region,
                                  ty::mt {ty: self_info.untransformed_self_ty,
                                          mutbl: mutability}))
             }
-            ast::SelfUniq(_) => {
+            ty::ByBoxExplicitSelfCategory => {
                 Some(ty::mk_uniq(this.tcx(), self_info.untransformed_self_ty))
             }
         }
@@ -972,7 +987,7 @@ fn ty_of_method_or_bare_fn<AC:AstConv>(this: &AC, id: ast::NodeId,
         _ => ast_ty_to_ty(this, &rb, &*decl.output)
     };
 
-    return ty::BareFnTy {
+    (ty::BareFnTy {
         fn_style: fn_style,
         abi: abi,
         sig: ty::FnSig {
@@ -981,7 +996,83 @@ fn ty_of_method_or_bare_fn<AC:AstConv>(this: &AC, id: ast::NodeId,
             output: output_ty,
             variadic: decl.variadic
         }
-    };
+    }, explicit_self_category_result)
+}
+
+fn determine_explicit_self_category<AC:AstConv,
+                                    RS:RegionScope>(
+                                    this: &AC,
+                                    rscope: &RS,
+                                    self_info: &SelfInfo)
+                                    -> ty::ExplicitSelfCategory {
+    match self_info.explicit_self.node {
+        ast::SelfStatic => ty::StaticExplicitSelfCategory,
+        ast::SelfValue(_) => ty::ByValueExplicitSelfCategory,
+        ast::SelfRegion(ref lifetime, mutability, _) => {
+            let region =
+                opt_ast_region_to_region(this,
+                                         rscope,
+                                         self_info.explicit_self.span,
+                                         lifetime);
+            ty::ByReferenceExplicitSelfCategory(region, mutability)
+        }
+        ast::SelfUniq(_) => ty::ByBoxExplicitSelfCategory,
+        ast::SelfExplicit(ast_type, _) => {
+            let explicit_type = ast_ty_to_ty(this, rscope, &*ast_type);
+
+            {
+                let inference_context = infer::new_infer_ctxt(this.tcx());
+                let expected_self = self_info.untransformed_self_ty;
+                let actual_self = explicit_type;
+                let result = infer::mk_eqty(
+                    &inference_context,
+                    false,
+                    infer::Misc(self_info.explicit_self.span),
+                    expected_self,
+                    actual_self);
+                match result {
+                    Ok(_) => {
+                        inference_context.resolve_regions_and_report_errors();
+                        return ty::ByValueExplicitSelfCategory
+                    }
+                    Err(_) => {}
+                }
+            }
+
+            match ty::get(explicit_type).sty {
+                ty::ty_rptr(region, tm) => {
+                    typeck::require_same_types(
+                        this.tcx(),
+                        None,
+                        false,
+                        self_info.explicit_self.span,
+                        self_info.untransformed_self_ty,
+                        tm.ty,
+                        || "not a valid type for `self`".to_owned());
+                    return ty::ByReferenceExplicitSelfCategory(region,
+                                                               tm.mutbl)
+                }
+                ty::ty_uniq(typ) => {
+                    typeck::require_same_types(
+                        this.tcx(),
+                        None,
+                        false,
+                        self_info.explicit_self.span,
+                        self_info.untransformed_self_ty,
+                        typ,
+                        || "not a valid type for `self`".to_owned());
+                    return ty::ByBoxExplicitSelfCategory
+                }
+                _ => {
+                    this.tcx()
+                        .sess
+                        .span_err(self_info.explicit_self.span,
+                                  "not a valid type for `self`");
+                    return ty::ByValueExplicitSelfCategory
+                }
+            }
+        }
+    }
 }
 
 pub fn ty_of_closure<AC:AstConv>(
@@ -1098,3 +1189,4 @@ fn conv_builtin_bounds(tcx: &ty::ctxt,
         (&None, ty::UniqTraitStore) => ty::empty_builtin_bounds(),
     }
 }
+
index 4787837093844233fd86e2b65361cd293be94862..e12fae4f9501e00ea4f325437d6c6b0ba6b7e110 100644 (file)
@@ -100,9 +100,7 @@ trait `ToString` imported, and I call `to_string()` on a value of type `T`,
 
 use std::collections::HashSet;
 use std::rc::Rc;
-use syntax::ast::{DefId, SelfValue, SelfRegion};
-use syntax::ast::{SelfUniq, SelfStatic};
-use syntax::ast::{MutMutable, MutImmutable};
+use syntax::ast::{DefId, MutImmutable, MutMutable};
 use syntax::ast;
 use syntax::codemap::Span;
 use syntax::parse::token;
@@ -267,15 +265,15 @@ fn construct_transformed_self_ty_for_object(
     obj_substs.types.pop(subst::SelfSpace).unwrap();
 
     match method_ty.explicit_self {
-        ast::SelfStatic => {
+        StaticExplicitSelfCategory => {
             tcx.sess.span_bug(span, "static method for object type receiver");
         }
-        ast::SelfValue(_) => {
+        ByValueExplicitSelfCategory => {
             let tr = ty::mk_trait(tcx, trait_def_id, obj_substs,
                                   ty::empty_builtin_bounds());
             ty::mk_uniq(tcx, tr)
         }
-        ast::SelfRegion(..) | ast::SelfUniq(..) => {
+        ByReferenceExplicitSelfCategory(..) | ByBoxExplicitSelfCategory => {
             let transformed_self_ty = *method_ty.fty.sig.inputs.get(0);
             match ty::get(transformed_self_ty).sty {
                 ty::ty_rptr(r, mt) => { // must be SelfRegion
@@ -618,7 +616,7 @@ fn push_inherent_candidates_from_bounds_inner(&mut self,
 
             let trait_methods = ty::trait_methods(tcx, bound_trait_ref.def_id);
             match trait_methods.iter().position(|m| {
-                m.explicit_self != ast::SelfStatic &&
+                m.explicit_self != ty::StaticExplicitSelfCategory &&
                 m.ident.name == self.m_name }) {
                 Some(pos) => {
                     let method = trait_methods.get(pos).clone();
@@ -1023,7 +1021,10 @@ fn consider_candidates(&self, rcvr_ty: ty::t,
 
         if self.report_statics == ReportStaticMethods {
             // lookup should only be called with ReportStaticMethods if a regular lookup failed
-            assert!(relevant_candidates.iter().all(|c| c.method_ty.explicit_self == SelfStatic));
+            assert!(relevant_candidates.iter()
+                                       .all(|c| {
+                c.method_ty.explicit_self == ty::StaticExplicitSelfCategory
+            }));
 
             self.tcx().sess.fileline_note(self.span,
                                 "found defined static methods, maybe a `self` is missing?");
@@ -1100,7 +1101,8 @@ fn confirm_candidate(&self, rcvr_ty: ty::t, candidate: &Candidate)
         self.enforce_drop_trait_limitations(candidate);
 
         // static methods should never have gotten this far:
-        assert!(candidate.method_ty.explicit_self != SelfStatic);
+        assert!(candidate.method_ty.explicit_self !=
+                ty::StaticExplicitSelfCategory);
 
         // Determine the values for the generic parameters of the method.
         // If they were not explicitly supplied, just construct fresh
@@ -1217,12 +1219,16 @@ fn enforce_object_limitations(&self, candidate: &Candidate) {
         }
 
         match candidate.method_ty.explicit_self {
-            ast::SelfStatic => { // reason (a) above
-                span_err!(self.tcx().sess, self.span, E0037,
-                    "cannot call a method without a receiver through an object");
+            ty::StaticExplicitSelfCategory => { // reason (a) above
+                self.tcx().sess.span_err(
+                    self.span,
+                    "cannot call a method without a receiver \
+                     through an object");
             }
 
-            ast::SelfValue(_) | ast::SelfRegion(..) | ast::SelfUniq(_) => {}
+            ty::ByValueExplicitSelfCategory |
+            ty::ByReferenceExplicitSelfCategory(..) |
+            ty::ByBoxExplicitSelfCategory => {}
         }
 
         // reason (a) above
@@ -1284,12 +1290,12 @@ fn is_relevant(&self, rcvr_ty: ty::t, candidate: &Candidate) -> bool {
                self.ty_to_string(rcvr_ty), candidate.repr(self.tcx()));
 
         return match candidate.method_ty.explicit_self {
-            SelfStatic => {
+            StaticExplicitSelfCategory => {
                 debug!("(is relevant?) explicit self is static");
                 self.report_statics == ReportStaticMethods
             }
 
-            SelfValue(_) => {
+            ByValueExplicitSelfCategory => {
                 debug!("(is relevant?) explicit self is by-value");
                 match ty::get(rcvr_ty).sty {
                     ty::ty_uniq(typ) => {
@@ -1312,7 +1318,7 @@ fn is_relevant(&self, rcvr_ty: ty::t, candidate: &Candidate) -> bool {
                 }
             }
 
-            SelfRegion(_, m, _) => {
+            ByReferenceExplicitSelfCategory(_, m) => {
                 debug!("(is relevant?) explicit self is a region");
                 match ty::get(rcvr_ty).sty {
                     ty::ty_rptr(_, mt) => {
@@ -1332,7 +1338,7 @@ fn is_relevant(&self, rcvr_ty: ty::t, candidate: &Candidate) -> bool {
                 }
             }
 
-            SelfUniq(_) => {
+            ByBoxExplicitSelfCategory => {
                 debug!("(is relevant?) explicit self is a unique pointer");
                 match ty::get(rcvr_ty).sty {
                     ty::ty_uniq(typ) => {
@@ -1480,3 +1486,6 @@ fn repr(&self, tcx: &ty::ctxt) -> String {
         }
     }
 }
+
+
+
index bc4d1c73ffbf39cfd08ade998311fe50391b98de..3b860be0f0134a0c40211bec73916807ebfd03dc 100644 (file)
@@ -764,7 +764,12 @@ fn check_method_body(ccx: &CrateCtxt,
 
     let fty = ty::node_id_to_type(ccx.tcx, method.id);
 
-    check_bare_fn(ccx, method.pe_fn_decl(), method.pe_body(), method.id, fty, param_env);
+    check_bare_fn(ccx,
+                  &*method.pe_fn_decl(),
+                  &*method.pe_body(),
+                  method.id,
+                  fty,
+                  param_env);
 }
 
 fn check_impl_methods_against_trait(ccx: &CrateCtxt,
@@ -862,19 +867,26 @@ fn compare_impl_method(tcx: &ty::ctxt,
     // inscrutable, particularly for cases where one method has no
     // self.
     match (&trait_m.explicit_self, &impl_m.explicit_self) {
-        (&ast::SelfStatic, &ast::SelfStatic) => {}
-        (&ast::SelfStatic, _) => {
-            span_err!(tcx.sess, impl_m_span, E0047,
-                "method `{}` has a `{}` declaration in the impl, but not in the trait",
-                token::get_ident(trait_m.ident),
-                pprust::explicit_self_to_string(impl_m.explicit_self));
+        (&ty::StaticExplicitSelfCategory,
+         &ty::StaticExplicitSelfCategory) => {}
+        (&ty::StaticExplicitSelfCategory, _) => {
+            tcx.sess.span_err(
+                impl_m_span,
+                format!("method `{}` has a `{}` declaration in the impl, \
+                        but not in the trait",
+                        token::get_ident(trait_m.ident),
+                        ppaux::explicit_self_category_to_str(
+                            &impl_m.explicit_self)).as_slice());
             return;
         }
-        (_, &ast::SelfStatic) => {
-            span_err!(tcx.sess, impl_m_span, E0048,
-                "method `{}` has a `{}` declaration in the trait, but not in the impl",
-                token::get_ident(trait_m.ident),
-                pprust::explicit_self_to_string(trait_m.explicit_self));
+        (_, &ty::StaticExplicitSelfCategory) => {
+            tcx.sess.span_err(
+                impl_m_span,
+                format!("method `{}` has a `{}` declaration in the trait, \
+                        but not in the impl",
+                        token::get_ident(trait_m.ident),
+                        ppaux::explicit_self_category_to_str(
+                            &trait_m.explicit_self)).as_slice());
             return;
         }
         _ => {
@@ -2363,7 +2375,7 @@ fn check_binop(fcx: &FnCtxt,
 
         if ty::type_is_integral(lhs_t) && ast_util::is_shift_binop(op) {
             // Shift is a special case: rhs must be uint, no matter what lhs is
-            check_expr_has_type(fcx, rhs, ty::mk_uint());
+            check_expr_has_type(fcx, &*rhs, ty::mk_uint());
             fcx.write_ty(expr.id, lhs_t);
             return;
         }
@@ -2950,7 +2962,7 @@ fn check_fn_for_vec_elements_expected(fcx: &FnCtxt,
       }
 
       ast::ExprLit(lit) => {
-        let typ = check_lit(fcx, lit, expected);
+        let typ = check_lit(fcx, &*lit, expected);
         fcx.write_ty(id, typ);
       }
       ast::ExprBinary(op, ref lhs, ref rhs) => {
@@ -3157,8 +3169,11 @@ fn check_fn_for_vec_elements_expected(fcx: &FnCtxt,
         fcx.write_bot(id);
       }
       ast::ExprParen(a) => {
-        check_expr_with_expectation_and_lvalue_pref(fcx, a, expected, lvalue_pref);
-        fcx.write_ty(id, fcx.expr_ty(a));
+        check_expr_with_expectation_and_lvalue_pref(fcx,
+                                                    &*a,
+                                                    expected,
+                                                    lvalue_pref);
+        fcx.write_ty(id, fcx.expr_ty(&*a));
       }
       ast::ExprAssign(ref lhs, ref rhs) => {
         check_expr_with_lvalue_pref(fcx, &**lhs, PreferMutLvalue);
@@ -3319,8 +3334,8 @@ fn check_fn_for_vec_elements_expected(fcx: &FnCtxt,
                 Some(ref fs) if i < fs.len() => ExpectHasType(*fs.get(i)),
                 _ => NoExpectation
             };
-            check_expr_with_expectation(fcx, *e, opt_hint);
-            let t = fcx.expr_ty(*e);
+            check_expr_with_expectation(fcx, &**e, opt_hint);
+            let t = fcx.expr_ty(&**e);
             err_field = err_field || ty::type_is_error(t);
             bot_field = bot_field || ty::type_is_bot(t);
             t
@@ -3667,8 +3682,8 @@ fn check_block_with_expected(fcx: &FnCtxt,
                              e.span,
                              "unreachable expression".to_string());
             }
-            check_expr_with_expectation(fcx, e, expected);
-              let ety = fcx.expr_ty(e);
+            check_expr_with_expectation(fcx, &*e, expected);
+              let ety = fcx.expr_ty(&*e);
               fcx.write_ty(blk.id, ety);
               if any_err {
                   fcx.write_error(blk.id);
@@ -4787,3 +4802,4 @@ fn param(ccx: &CrateCtxt, n: uint) -> ty::t {
             });
     }
 }
+
index e21a7949ec79975154cec27c8c7bdeb51d7b3b87..906cc1e0255aa53bdd96e4e431751ee80cdd7f1e 100644 (file)
 use middle::ty::{ImplContainer, MethodContainer, TraitContainer};
 use middle::ty::{Polytype};
 use middle::ty;
+use middle::ty_fold::TypeFolder;
 use middle::typeck::astconv::{AstConv, ty_of_arg};
 use middle::typeck::astconv::{ast_ty_to_ty};
 use middle::typeck::astconv;
+use middle::typeck::infer;
 use middle::typeck::rscope::*;
 use middle::typeck::{CrateCtxt, lookup_def_tcx, no_params, write_ty_to_tcx};
+use middle::typeck;
 use util::ppaux;
 use util::ppaux::Repr;
 
@@ -212,13 +215,20 @@ pub fn ensure_trait_methods(ccx: &CrateCtxt,
 
                             &ast::Provided(ref m) => {
                                 ty_method_of_trait_method(
-                                    ccx, trait_id, &trait_def.generics,
-                                    &m.id, &m.pe_ident(), m.pe_explicit_self(),
-                                    m.pe_generics(), &m.pe_fn_style(), m.pe_fn_decl())
+                                    ccx,
+                                    trait_id,
+                                    &trait_def.generics,
+                                    &m.id,
+                                    &m.pe_ident(),
+                                    m.pe_explicit_self(),
+                                    m.pe_generics(),
+                                    &m.pe_fn_style(),
+                                    &*m.pe_fn_decl())
                             }
                         });
 
-                        if ty_method.explicit_self == ast::SelfStatic {
+                        if ty_method.explicit_self ==
+                                ty::StaticExplicitSelfCategory {
                             make_static_method_ty(ccx, &*ty_method);
                         }
 
@@ -266,18 +276,26 @@ fn ty_method_of_trait_method(this: &CrateCtxt,
                                  m_fn_style: &ast::FnStyle,
                                  m_decl: &ast::FnDecl) -> ty::Method
     {
-        let trait_self_ty = ty::mk_self_type(this.tcx, local_def(trait_id));
-        let fty = astconv::ty_of_method(this, *m_id, *m_fn_style, trait_self_ty,
-                                        *m_explicit_self, m_decl);
-        let ty_generics =
-            ty_generics_for_fn_or_method(this,
-                                         m_generics,
-                                         (*trait_generics).clone());
+        let trait_self_ty = ty::mk_param(this.tcx,
+                                         subst::SelfSpace,
+                                         0,
+                                         local_def(trait_id));
+        let ty_generics = ty_generics_for_fn_or_method(
+            this,
+            m_generics,
+            (*trait_generics).clone());
+        let (fty, explicit_self_category) =
+            astconv::ty_of_method(this,
+                                  *m_id,
+                                  *m_fn_style,
+                                  trait_self_ty,
+                                  *m_explicit_self,
+                                  m_decl);
         ty::Method::new(
             *m_ident,
             ty_generics,
             fty,
-            m_explicit_self.node,
+            explicit_self_category,
             // assume public, because this is only invoked on trait methods
             ast::Public,
             local_def(*m_id),
@@ -365,9 +383,13 @@ fn ty_of_method(ccx: &CrateCtxt,
                     rcvr_visibility: ast::Visibility)
                     -> ty::Method
     {
-        let fty = astconv::ty_of_method(ccx, m.id, m.pe_fn_style(),
-                                        untransformed_rcvr_ty,
-                                        *m.pe_explicit_self(), m.pe_fn_decl());
+        let (fty, explicit_self_category) =
+            astconv::ty_of_method(ccx,
+                                  m.id,
+                                  m.pe_fn_style(),
+                                  untransformed_rcvr_ty,
+                                  *m.pe_explicit_self(),
+                                  &*m.pe_fn_decl());
 
         // if the method specifies a visibility, use that, otherwise
         // inherit the visibility from the impl (so `foo` in `pub impl
@@ -381,7 +403,7 @@ fn ty_of_method(ccx: &CrateCtxt,
         ty::Method::new(m.pe_ident(),
                         m_ty_generics,
                         fty,
-                        m.pe_explicit_self().node,
+                        explicit_self_category,
                         method_vis,
                         local_def(m.id),
                         container,
@@ -450,6 +472,13 @@ pub fn convert(ccx: &CrateCtxt, it: &ast::Item) {
                 it.vis
             };
 
+            for method in ms.iter() {
+                check_method_self_type(ccx,
+                                       &BindingRscope::new(method.id),
+                                       selfty,
+                                       method.pe_explicit_self())
+            }
+
             convert_methods(ccx,
                             ImplContainer(local_def(it.id)),
                             ms.as_slice(),
@@ -464,6 +493,28 @@ pub fn convert(ccx: &CrateCtxt, it: &ast::Item) {
         ast::ItemTrait(_, _, _, ref trait_methods) => {
             let trait_def = trait_def_of_item(ccx, it);
 
+            for trait_method in trait_methods.iter() {
+                let self_type = ty::mk_param(ccx.tcx,
+                                             subst::SelfSpace,
+                                             0,
+                                             local_def(it.id));
+                match *trait_method {
+                    ast::Required(ref type_method) => {
+                        let rscope = BindingRscope::new(type_method.id);
+                        check_method_self_type(ccx,
+                                               &rscope,
+                                               self_type,
+                                               &type_method.explicit_self)
+                    }
+                    ast::Provided(ref method) => {
+                        check_method_self_type(ccx,
+                                               &BindingRscope::new(method.id),
+                                               self_type,
+                                               method.pe_explicit_self())
+                    }
+                }
+            }
+
             // Run convert_methods on the provided methods.
             let (_, provided_methods) =
                 split_trait_methods(trait_methods.as_slice());
@@ -1240,3 +1291,36 @@ pub fn mk_item_substs(ccx: &CrateCtxt,
 
     subst::Substs::new(types, regions)
 }
+
+/// Verifies that the explicit self type of a method matches the impl or
+/// trait.
+fn check_method_self_type<RS:RegionScope>(
+                          crate_context: &CrateCtxt,
+                          rs: &RS,
+                          required_type: ty::t,
+                          explicit_self: &ast::ExplicitSelf) {
+    match explicit_self.node {
+        ast::SelfExplicit(ref ast_type, _) => {
+            let typ = crate_context.to_ty(rs, &**ast_type);
+            let base_type = match ty::get(typ).sty {
+                ty::ty_rptr(_, tm) => tm.ty,
+                ty::ty_uniq(typ) => typ,
+                _ => typ,
+            };
+            let infcx = infer::new_infer_ctxt(crate_context.tcx);
+            drop(typeck::require_same_types(crate_context.tcx,
+                                            Some(&infcx),
+                                            false,
+                                            explicit_self.span,
+                                            base_type,
+                                            required_type,
+                                            || {
+                format!("mismatched self type: expected `{}`",
+                        ppaux::ty_to_string(crate_context.tcx, required_type))
+            }));
+            infcx.resolve_regions_and_report_errors();
+        }
+        _ => {}
+    }
+}
+
index f8efb3c38c2002eec6156bce21005d34e8d38425..03890250f77013c39602e086f3b22b2945a4a99f 100644 (file)
@@ -76,7 +76,6 @@ fn foo<A>(a: A, b: A) { ... }
 use util::ppaux::Repr;
 
 use syntax::abi;
-use syntax::ast::MutImmutable;
 use syntax::ast;
 
 // Note: Coerce is not actually a combiner, in that it does not
@@ -248,12 +247,7 @@ pub fn coerce_borrowed_pointer(&self,
         let r_borrow = self.get_ref().infcx.next_region_var(coercion);
 
         let inner_ty = match *sty_a {
-            ty::ty_box(typ) | ty::ty_uniq(typ) => {
-                if mt_b.mutbl == ast::MutMutable {
-                    return Err(ty::terr_mutability)
-                }
-                typ
-            }
+            ty::ty_box(_) | ty::ty_uniq(_) => return Err(ty::terr_mismatch),
             ty::ty_rptr(_, mt_a) => mt_a.ty,
             _ => {
                 return self.subtype(a, b);
@@ -280,23 +274,9 @@ pub fn coerce_borrowed_string(&self,
                b.repr(self.get_ref().infcx.tcx));
 
         match *sty_a {
-            ty::ty_uniq(t) => match ty::get(t).sty {
-                ty::ty_str => {}
-                _ => return self.subtype(a, b),
-            },
-            _ => {
-                return self.subtype(a, b);
-            }
-        };
-
-        let coercion = Coercion(self.get_ref().trace.clone());
-        let r_a = self.get_ref().infcx.next_region_var(coercion);
-        let a_borrowed = ty::mk_str_slice(self.get_ref().infcx.tcx, r_a, ast::MutImmutable);
-        if_ok!(self.subtype(a_borrowed, b));
-        Ok(Some(AutoDerefRef(AutoDerefRef {
-            autoderefs: 0,
-            autoref: Some(AutoBorrowVec(r_a, MutImmutable))
-        })))
+            ty::ty_uniq(_) => return Err(ty::terr_mismatch),
+            _ => return self.subtype(a, b),
+        }
     }
 
     pub fn coerce_borrowed_vector(&self,
@@ -313,7 +293,8 @@ pub fn coerce_borrowed_vector(&self,
         let coercion = Coercion(self.get_ref().trace.clone());
         let r_borrow = self.get_ref().infcx.next_region_var(coercion);
         let ty_inner = match *sty_a {
-            ty::ty_uniq(t) | ty::ty_ptr(ty::mt{ty: t, ..}) |
+            ty::ty_uniq(_) => return Err(ty::terr_mismatch),
+            ty::ty_ptr(ty::mt{ty: t, ..}) |
             ty::ty_rptr(_, ty::mt{ty: t, ..}) => match ty::get(t).sty {
                 ty::ty_vec(mt, None) => mt.ty,
                 _ => {
index 1e33b1d5d0ebd5368044a1a6c51a5c273a95ed64..d82e6e74778e5d7df032b7be9c0fa3305dcb018c 100644 (file)
@@ -111,7 +111,11 @@ fn substs(&self,
               b_subst: &subst::Substs)
               -> cres<subst::Substs>
     {
-        let variances = ty::item_variances(self.infcx().tcx, item_def_id);
+        let variances = if self.infcx().tcx.variance_computed.get() {
+            Some(ty::item_variances(self.infcx().tcx, item_def_id))
+        } else {
+            None
+        };
         let mut substs = subst::Substs::empty();
 
         for &space in subst::ParamSpace::all().iter() {
@@ -121,7 +125,18 @@ fn substs(&self,
 
             let a_regions = a_subst.regions().get_slice(space);
             let b_regions = b_subst.regions().get_slice(space);
-            let r_variances = variances.regions.get_slice(space);
+
+            let mut invariance = Vec::new();
+            let r_variances = match variances {
+                Some(ref variances) => variances.regions.get_slice(space),
+                None => {
+                    for _ in a_regions.iter() {
+                        invariance.push(ty::Invariant);
+                    }
+                    invariance.as_slice()
+                }
+            };
+
             let regions = if_ok!(relate_region_params(self,
                                                       item_def_id,
                                                       r_variances,
@@ -537,7 +552,7 @@ fn check_ptr_to_unsized<C:Combine>(this: &C,
       }
 
       (&ty::ty_closure(ref a_fty), &ty::ty_closure(ref b_fty)) => {
-        this.closure_tys(*a_fty, *b_fty).and_then(|fty| {
+        this.closure_tys(&**a_fty, &**b_fty).and_then(|fty| {
             Ok(ty::mk_closure(tcx, fty))
         })
       }
index 16e758df9dbbd2ad7c3354f7d716bace80d93f5b..30fffc42a3f97f1b28bac0722d7d39300370bfcb 100644 (file)
@@ -30,8 +30,8 @@
 use middle::typeck::check::regionmanip::replace_late_bound_regions_in_fn_sig;
 use middle::typeck::infer::coercion::Coerce;
 use middle::typeck::infer::combine::{Combine, CombineFields, eq_tys};
-use middle::typeck::infer::region_inference::{RegionVarBindings,
-                                              RegionSnapshot};
+use middle::typeck::infer::region_inference::{RegionSnapshot};
+use middle::typeck::infer::region_inference::{RegionVarBindings};
 use middle::typeck::infer::resolve::{resolver};
 use middle::typeck::infer::sub::Sub;
 use middle::typeck::infer::lub::Lub;
index 28240686dc358f2fdb7e8d3dc288e60a0f540c67..d17553e9c39b39b30e6801f46ff2b795765719c0 100644 (file)
 
 use middle::ty;
 use middle::ty::{BoundRegion, FreeRegion, Region, RegionVid};
-use middle::ty::{ReEmpty, ReStatic, ReInfer, ReFree, ReEarlyBound,
-                 ReLateBound};
-use middle::ty::{ReScope, ReVar, ReSkolemized, BrFresh};
+use middle::ty::{ReEmpty, ReStatic, ReInfer, ReFree, ReEarlyBound};
+use middle::ty::{ReLateBound, ReScope, ReVar, ReSkolemized, BrFresh};
 use middle::typeck::infer::cres;
 use middle::typeck::infer::{RegionVariableOrigin, SubregionOrigin, TypeTrace};
 use middle::typeck::infer;
 use middle::graph;
 use middle::graph::{Direction, NodeIndex};
 use util::common::indenter;
-use util::ppaux::{Repr};
+use util::ppaux::Repr;
 
 use std::cell::{Cell, RefCell};
 use std::uint;
@@ -318,6 +317,11 @@ pub fn make_subregion(&self,
                origin.repr(self.tcx));
 
         match (sub, sup) {
+          (ReEarlyBound(..), ReEarlyBound(..)) => {
+            // This case is used only to make sure that explicitly-specified
+            // `Self` types match the real self type in implementations.
+            self.add_constraint(ConstrainRegSubReg(sub, sup), origin);
+          }
           (ReEarlyBound(..), _) |
           (ReLateBound(..), _) |
           (_, ReEarlyBound(..)) |
index c06e40fce14f915e410208e5393bb57eccbf885f..c8f6836b20596cd9e98b0e6c10267a745dcc17d6 100644 (file)
@@ -95,7 +95,7 @@ fn custom_emit(&mut self,
 }
 
 fn errors(msgs: &[&str]) -> (Box<Emitter+Send>, uint) {
-    let v = Vec::from_fn(msgs.len(), |i| msgs[i].to_owned());
+    let v = msgs.iter().map(|m| m.to_string()).collect();
     (box ExpectErrorEmitter { messages: v } as Box<Emitter+Send>, msgs.len())
 }
 
@@ -114,7 +114,7 @@ fn test_env(_test_name: &str,
 
     let sess = session::build_session_(options, None, span_diagnostic_handler);
     let krate_config = Vec::new();
-    let input = driver::StrInput(source_string.to_owned());
+    let input = driver::StrInput(source_string.to_string());
     let krate = driver::phase_1_parse_input(&sess, krate_config, &input);
     let (krate, ast_map) =
         driver::phase_2_configure_and_expand(&sess, krate, "test")
@@ -174,7 +174,7 @@ fn search_mod(this: &Env,
             assert!(idx < names.len());
             for item in m.items.iter() {
                 if item.ident.user_string(this.tcx) == names[idx] {
-                    return search(this, *item, idx+1, names);
+                    return search(this, &**item, idx+1, names);
                 }
             }
             return None;
index 8b5d16620b0f5898d02a5f0b89bdea289b6a34c2..a65aa0423a6d0a20d3790726a7ffaf04e237a74f 100644 (file)
@@ -214,6 +214,7 @@ pub fn infer_variance(tcx: &ty::ctxt,
     let terms_cx = determine_parameters_to_be_inferred(tcx, &mut arena, krate);
     let constraints_cx = add_constraints_from_crate(terms_cx, krate);
     solve_constraints(constraints_cx);
+    tcx.variance_computed.set(true);
 }
 
 /**************************************************************************
index 6526943955c92860c3c9500ed1719666fab0a937..8b8e37fe280d90db2da9a1df82835aa9dbf85997 100644 (file)
@@ -14,7 +14,7 @@
 use middle::subst::{VecPerParamSpace,Subst};
 use middle::ty::{ReSkolemized, ReVar};
 use middle::ty::{BoundRegion, BrAnon, BrNamed};
-use middle::ty::{BrFresh, ctxt};
+use middle::ty::{ReEarlyBound, BrFresh, ctxt};
 use middle::ty::{mt, t, ParamTy};
 use middle::ty::{ReFree, ReScope, ReInfer, ReStatic, Region, ReEmpty};
 use middle::ty::{ty_bool, ty_char, ty_bot, ty_box, ty_struct, ty_enum};
@@ -130,9 +130,13 @@ pub fn explain_region_and_span(cx: &ctxt, region: ty::Region)
 
       ReEmpty => { ("the empty lifetime".to_string(), None) }
 
+      ReEarlyBound(_, _, _, name) => {
+        (format!("{}", token::get_name(name)), None)
+      }
+
       // I believe these cases should not occur (except when debugging,
       // perhaps)
-      ty::ReInfer(_) | ty::ReEarlyBound(..) | ty::ReLateBound(..) => {
+      ty::ReInfer(_) | ty::ReLateBound(..) => {
         (format!("lifetime {:?}", region), None)
       }
     };
@@ -370,7 +374,7 @@ fn push_sig_to_string(cx: &ctxt,
         format!("({})", strs.connect(","))
       }
       ty_closure(ref f) => {
-          closure_to_string(cx, *f)
+          closure_to_string(cx, &**f)
       }
       ty_bare_fn(ref f) => {
           bare_fn_to_string(cx, f.fn_style, f.abi, None, &f.sig)
@@ -421,6 +425,19 @@ fn push_sig_to_string(cx: &ctxt,
     }
 }
 
+pub fn explicit_self_category_to_str(category: &ty::ExplicitSelfCategory)
+                                     -> &'static str {
+    match *category {
+        ty::StaticExplicitSelfCategory => "static",
+        ty::ByValueExplicitSelfCategory => "self",
+        ty::ByReferenceExplicitSelfCategory(_, ast::MutMutable) => {
+            "&mut self"
+        }
+        ty::ByReferenceExplicitSelfCategory(_, ast::MutImmutable) => "&self",
+        ty::ByBoxExplicitSelfCategory => "Box<self>",
+    }
+}
+
 pub fn parameterized(cx: &ctxt,
                      base: &str,
                      substs: &subst::Substs,
@@ -1083,3 +1100,10 @@ fn repr(&self, tcx: &ctxt) -> String {
         }
     }
 }
+
+impl Repr for ty::ExplicitSelfCategory {
+    fn repr(&self, _: &ctxt) -> String {
+        explicit_self_category_to_str(self).to_string()
+    }
+}
+
index fdf98f392a7430515eeabc6460cedb3ddf02b547..c94759d7d7e8deef96b7bb838cb44c55d753b4fe 100644 (file)
@@ -394,7 +394,7 @@ fn clean(&self) -> Item {
     }
 }
 
-#[deriving(Clone, Encodable, Decodable)]
+#[deriving(Clone, Encodable, Decodable, PartialEq)]
 pub enum Attribute {
     Word(String),
     List(String, Vec<Attribute> ),
@@ -447,7 +447,7 @@ fn value_str(&self) -> Option<InternedString> { (**self).value_str() }
     fn meta_item_list<'a>(&'a self) -> Option<&'a [Gc<ast::MetaItem>]> { None }
 }
 
-#[deriving(Clone, Encodable, Decodable)]
+#[deriving(Clone, Encodable, Decodable, PartialEq)]
 pub struct TyParam {
     pub name: String,
     pub did: ast::DefId,
@@ -479,7 +479,7 @@ fn clean(&self) -> TyParam {
     }
 }
 
-#[deriving(Clone, Encodable, Decodable)]
+#[deriving(Clone, Encodable, Decodable, PartialEq)]
 pub enum TyParamBound {
     RegionBound,
     TraitBound(Type)
@@ -638,7 +638,7 @@ fn clean(&self) -> Option<Lifetime> {
 }
 
 // maybe use a Generic enum and use ~[Generic]?
-#[deriving(Clone, Encodable, Decodable)]
+#[deriving(Clone, Encodable, Decodable, PartialEq)]
 pub struct Generics {
     pub lifetimes: Vec<Lifetime>,
     pub type_params: Vec<TyParam>,
@@ -771,6 +771,7 @@ pub enum SelfTy {
     SelfValue,
     SelfBorrowed(Option<Lifetime>, Mutability),
     SelfOwned,
+    SelfExplicit(Type),
 }
 
 impl Clean<SelfTy> for ast::ExplicitSelf_ {
@@ -779,7 +780,10 @@ fn clean(&self) -> SelfTy {
             ast::SelfStatic => SelfStatic,
             ast::SelfValue(_) => SelfValue,
             ast::SelfUniq(_) => SelfOwned,
-            ast::SelfRegion(lt, mt, _) => SelfBorrowed(lt.clean(), mt.clean()),
+            ast::SelfRegion(lt, mt, _) => {
+                SelfBorrowed(lt.clean(), mt.clean())
+            }
+            ast::SelfExplicit(typ, _) => SelfExplicit(typ.clean()),
         }
     }
 }
@@ -809,7 +813,7 @@ fn clean(&self) -> Item {
     }
 }
 
-#[deriving(Clone, Encodable, Decodable)]
+#[deriving(Clone, Encodable, Decodable, PartialEq)]
 pub struct ClosureDecl {
     pub lifetimes: Vec<Lifetime>,
     pub decl: FnDecl,
@@ -833,7 +837,7 @@ fn clean(&self) -> ClosureDecl {
     }
 }
 
-#[deriving(Clone, Encodable, Decodable)]
+#[deriving(Clone, Encodable, Decodable, PartialEq)]
 pub struct FnDecl {
     pub inputs: Arguments,
     pub output: Type,
@@ -841,7 +845,7 @@ pub struct FnDecl {
     pub attrs: Vec<Attribute>,
 }
 
-#[deriving(Clone, Encodable, Decodable)]
+#[deriving(Clone, Encodable, Decodable, PartialEq)]
 pub struct Arguments {
     pub values: Vec<Argument>,
 }
@@ -888,7 +892,7 @@ fn clean(&self) -> FnDecl {
     }
 }
 
-#[deriving(Clone, Encodable, Decodable)]
+#[deriving(Clone, Encodable, Decodable, PartialEq)]
 pub struct Argument {
     pub type_: Type,
     pub name: String,
@@ -905,7 +909,7 @@ fn clean(&self) -> Argument {
     }
 }
 
-#[deriving(Clone, Encodable, Decodable)]
+#[deriving(Clone, Encodable, Decodable, PartialEq)]
 pub enum RetStyle {
     NoReturn,
     Return
@@ -991,22 +995,28 @@ impl Clean<Item> for ty::Method {
     fn clean(&self) -> Item {
         let cx = get_cx();
         let (self_, sig) = match self.explicit_self {
-            ast::SelfStatic => (ast::SelfStatic.clean(), self.fty.sig.clone()),
+            ty::StaticExplicitSelfCategory => (ast::SelfStatic.clean(), self.fty.sig.clone()),
             s => {
                 let sig = ty::FnSig {
                     inputs: Vec::from_slice(self.fty.sig.inputs.slice_from(1)),
                     ..self.fty.sig.clone()
                 };
                 let s = match s {
-                    ast::SelfRegion(..) => {
-                        match ty::get(*self.fty.sig.inputs.get(0)).sty {
+                    ty::ByReferenceExplicitSelfCategory(..) => {
+                        match ty::get(self.fty.sig.inputs[0]).sty {
                             ty::ty_rptr(r, mt) => {
                                 SelfBorrowed(r.clean(), mt.mutbl.clean())
                             }
-                            _ => s.clean(),
+                            _ => {
+                                // FIXME(pcwalton): This is wrong.
+                                SelfStatic
+                            }
                         }
                     }
-                    s => s.clean(),
+                    _ => {
+                        // FIXME(pcwalton): This is wrong.
+                        SelfStatic
+                    }
                 };
                 (s, sig)
             }
@@ -1032,7 +1042,7 @@ fn clean(&self) -> Item {
 /// A representation of a Type suitable for hyperlinking purposes. Ideally one can get the original
 /// type out of the AST/ty::ctxt given one of these, if more information is needed. Most importantly
 /// it does not preserve mutability or boxes.
-#[deriving(Clone, Encodable, Decodable)]
+#[deriving(Clone, Encodable, Decodable, PartialEq)]
 pub enum Type {
     /// structs/enums/traits (anything that'd be an ast::TyPath)
     ResolvedPath {
@@ -1550,7 +1560,7 @@ fn clean(&self) -> Span {
     }
 }
 
-#[deriving(Clone, Encodable, Decodable)]
+#[deriving(Clone, Encodable, Decodable, PartialEq)]
 pub struct Path {
     pub global: bool,
     pub segments: Vec<PathSegment>,
@@ -1565,7 +1575,7 @@ fn clean(&self) -> Path {
     }
 }
 
-#[deriving(Clone, Encodable, Decodable)]
+#[deriving(Clone, Encodable, Decodable, PartialEq)]
 pub struct PathSegment {
     pub name: String,
     pub lifetimes: Vec<Lifetime>,
@@ -1631,7 +1641,7 @@ fn clean(&self) -> Item {
     }
 }
 
-#[deriving(Clone, Encodable, Decodable)]
+#[deriving(Clone, Encodable, Decodable, PartialEq)]
 pub struct BareFunctionDecl {
     pub fn_style: ast::FnStyle,
     pub generics: Generics,
index c549469dcdeaaa19e90ef72caec2f9d438ebf4ea..d0f9b37cc4ce403a7b7dd8421ebb43caa74377c6 100644 (file)
@@ -210,7 +210,7 @@ fn path(w: &mut fmt::Formatter, path: &clean::Path, print_all: bool,
     let loc = current_location_key.get().unwrap();
     let cache = cache_key.get().unwrap();
     let abs_root = root(&**cache, loc.as_slice());
-    let rel_root = match path.segments.get(0).name.as_slice() {
+    let rel_root = match path.segments[0].name.as_slice() {
         "self" => Some("./".to_string()),
         _ => None,
     };
@@ -500,6 +500,9 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
                 args.push_str(format!("&amp;{}self",
                                       MutableSpace(mtbl)).as_slice());
             }
+            clean::SelfExplicit(ref typ) => {
+                args.push_str(format!("self: {}", *typ).as_slice());
+            }
         }
         for (i, input) in d.inputs.values.iter().enumerate() {
             if i > 0 || args.len() > 0 { args.push_str(", "); }
index 244fada5b9adad07787661991342c9ff2d337020..eed058878e0820f9c41f1ffb51803e58710588fd 100644 (file)
@@ -551,7 +551,7 @@ fn collect(path: &Path, krate: &str,
         }
         mydst.push(format!("{}.{}.js",
                            remote_item_type.to_static_str(),
-                           *remote_path.get(remote_path.len() - 1)));
+                           remote_path[remote_path.len() - 1]));
         let all_implementors = try!(collect(&mydst, krate.name.as_slice(),
                                             "implementors"));
 
index 2cbac090835edf95b730f2e353cbfc4d3008196c..245dc9a0a34e5cbef07bb60834c86814109357f0 100644 (file)
@@ -167,7 +167,7 @@ pub fn main_args(args: &[String]) -> int {
         println!("only one input file may be specified");
         return 1;
     }
-    let input = matches.free.get(0).as_slice();
+    let input = matches.free[0].as_slice();
 
     let libs = matches.opt_strs("L").iter().map(|s| Path::new(s.as_slice())).collect();
 
index da271be4768e3de393d2a22389a4db620cd7a360..f9bc59888ae3b9704f09668929799afc3b24403c 100644 (file)
@@ -75,7 +75,7 @@ pub fn render(input: &str, mut output: Path, matches: &getopts::Matches,
                          "invalid markdown file: expecting initial line with `% ...TITLE...`");
         return 5;
     }
-    let title = metadata.get(0).as_slice();
+    let title = metadata[0].as_slice();
 
     reset_headers();
 
index 5145a4f254eea0d8c97482cc87bf4bf5989a1684..cc5bc5cb7c170de7265e18f3ab14bc8ad234e937 100644 (file)
@@ -339,7 +339,7 @@ pub fn unindent(s: &str) -> String {
     });
 
     if lines.len() >= 1 {
-        let mut unindented = vec![ lines.get(0).trim().to_string() ];
+        let mut unindented = vec![ lines[0].trim().to_string() ];
         unindented.push_all(lines.tail().iter().map(|&line| {
             if line.is_whitespace() {
                 line.to_string()
index 396d51f4fcb13a4128d62046199608646d72c385..0f2fcaff31036a66c7a2fcb674ae3df75d700798 100644 (file)
@@ -778,11 +778,11 @@ fn foo(f: |c: &CString|) {
             c_ = Some(c.clone());
             c.clone();
             // force a copy, reading the memory
-            c.as_bytes().to_owned();
+            c.as_bytes().to_vec();
         });
         let c_ = c_.unwrap();
         // force a copy, reading the memory
-        c_.as_bytes().to_owned();
+        c_.as_bytes().to_vec();
     }
 
     #[test]
index f7301abef51f23b485b8c79f279df477edf8bc8b..e28c51d517ea3488775f09ca7dac7f98de5931f1 100644 (file)
 
 ## Using Autoserialization
 
-Create a struct called TestStruct1 and serialize and deserialize it to and from JSON
-using the serialization API, using the derived serialization code.
+Create a struct called `TestStruct` and serialize and deserialize it to and from JSON using the
+serialization API, using the derived serialization code.
 
 ```rust
 extern crate serialize;
 use serialize::json;
 
-#[deriving(Decodable, Encodable)] //generate Decodable, Encodable impl.
-pub struct TestStruct1  {
+// Automatically generate `Decodable` and `Encodable` trait implementations
+#[deriving(Decodable, Encodable)]
+pub struct TestStruct  {
     data_int: u8,
     data_str: String,
     data_vector: Vec<u8>,
 }
 
 fn main() {
-    let object = TestStruct1
-         {data_int: 1, data_str:"toto".to_string(), data_vector:vec![2,3,4,5]};
+    let object = TestStruct {
+        data_int: 1,
+        data_str: "toto".to_string(),
+        data_vector: vec![2,3,4,5],
+    };
 
     // Serialize using `json::encode`
     let encoded = json::encode(&object);
 
     // Deserialize using `json::decode`
-    let decoded: TestStruct1 = json::decode(encoded.as_slice()).unwrap();
+    let decoded: TestStruct = json::decode(encoded.as_slice()).unwrap();
 }
 ```
 
-## Using `ToJson`
+## Using the `ToJson` trait
+
+The examples above use the `ToJson` trait to generate the JSON string, which required
+for custom mappings.
+
+### Simple example of `ToJson` usage
+
+```rust
+extern crate serialize;
+use serialize::json::ToJson;
+use serialize::json;
+
+// A custom data structure
+struct ComplexNum {
+    a: f64,
+    b: f64,
+}
+
+// JSON value representation
+impl ToJson for ComplexNum {
+    fn to_json(&self) -> json::Json {
+        json::String(format!("{}+{}i", self.a, self.b))
+    }
+}
 
-This example uses the `ToJson` trait to generate the JSON string.
+// Only generate `Encodable` trait implementation
+#[deriving(Encodable)]
+pub struct ComplexNumRecord {
+    uid: u8,
+    dsc: String,
+    val: json::Json,
+}
+
+fn main() {
+    let num = ComplexNum { a: 0.0001, b: 12.539 };
+    let data: String = json::encode(&ComplexNumRecord{
+        uid: 1,
+        dsc: "test".to_string(),
+        val: num.to_json(),
+    });
+    println!("data: {}", data);
+    // data: {"uid":1,"dsc":"test","val":"0.0001+12.539j"};
+}
+```
+
+### Verbose example of `ToJson` usage
 
 ```rust
+extern crate serialize;
 use std::collections::TreeMap;
 use serialize::json::ToJson;
 use serialize::json;
 
+// Only generate `Decodable` trait implementation
 #[deriving(Decodable)]
-pub struct TestStruct {
+pub struct TestStruct {
     data_int: u8,
     data_str: String,
     data_vector: Vec<u8>,
 }
 
-impl ToJson for TestStruct1 {
-    fn to_json( &self ) -> json::Json {
+// Specify encoding method manually
+impl ToJson for TestStruct {
+    fn to_json(&self) -> json::Json {
         let mut d = TreeMap::new();
+        // All standard types implement `to_json()`, so use it
         d.insert("data_int".to_string(), self.data_int.to_json());
         d.insert("data_str".to_string(), self.data_str.to_json());
         d.insert("data_vector".to_string(), self.data_vector.to_json());
@@ -128,12 +179,16 @@ fn to_json( &self ) -> json::Json {
 
 fn main() {
     // Serialize using `ToJson`
-    let test2 = TestStruct1 {data_int: 1, data_str:"toto".to_string(), data_vector:vec![2,3,4,5]};
-    let tjson: json::Json = test2.to_json();
-    let json_str: String = tjson.to_string();
+    let input_data = TestStruct {
+        data_int: 1,
+        data_str: "toto".to_string(),
+        data_vector: vec![2,3,4,5],
+    };
+    let json_obj: json::Json = input_data.to_json();
+    let json_str: String = json_obj.to_string();
 
     // Deserialize like before
-    let decoded: TestStruct1 = json::decode(json_str.as_slice()).unwrap();
+    let decoded: TestStruct = json::decode(json_str.as_slice()).unwrap();
 }
 ```
 
@@ -1015,7 +1070,7 @@ pub fn is_empty(&self) -> bool { self.stack.is_empty() }
     /// lower indices are at the bottom of the stack while higher indices are
     /// at the top.
     pub fn get<'l>(&'l self, idx: uint) -> StackElement<'l> {
-        match *self.stack.get(idx) {
+        match self.stack[idx] {
             InternalIndex(i) => { Index(i) }
             InternalKey(start, size) => {
                 Key(str::from_utf8(
index b700d57bc033df1b2323fad022fdd15d75619a45..7343838f19e6156d536ca764de216964b0df4a20 100644 (file)
@@ -90,7 +90,7 @@ fn push(&self, value: T) -> bool {
         let mask = self.mask;
         let mut pos = self.enqueue_pos.load(Relaxed);
         loop {
-            let node = self.buffer.get(pos & mask);
+            let node = &self.buffer[pos & mask];
             let seq = unsafe { (*node.get()).sequence.load(Acquire) };
             let diff: int = seq as int - pos as int;
 
@@ -118,7 +118,7 @@ fn pop(&self) -> Option<T> {
         let mask = self.mask;
         let mut pos = self.dequeue_pos.load(Relaxed);
         loop {
-            let node = self.buffer.get(pos & mask);
+            let node = &self.buffer[pos & mask];
             let seq = unsafe { (*node.get()).sequence.load(Acquire) };
             let diff: int = seq as int - (pos + 1) as int;
             if diff == 0 {
index 26cc0b2c6a23cd772889819cfad701cd48c523e3..d056566bb9a97908a61b134f1fe80cabe1c802c0 100644 (file)
@@ -243,7 +243,7 @@ pub fn wait_on(&self, condvar_id: uint) {
                     }
                     // Create waiter nobe, and enqueue ourself to
                     // be woken up by a signaller.
-                    wait_end = Some(state.blocked.get(condvar_id).wait_end());
+                    wait_end = Some(state.blocked[condvar_id].wait_end());
                 } else {
                     out_of_bounds = Some(state.blocked.len());
                 }
@@ -281,7 +281,7 @@ pub fn signal_on(&self, condvar_id: uint) -> bool {
             let mut result = false;
             self.sem.with(|state| {
                 if condvar_id < state.blocked.len() {
-                    result = state.blocked.get(condvar_id).signal();
+                    result = state.blocked[condvar_id].signal();
                 } else {
                     out_of_bounds = Some(state.blocked.len());
                 }
index 857cb4c0162ce530d930950aa3699ca722db97ca..d9f14bfa15661da7b5d59db64208a77c992b580e 100644 (file)
@@ -949,12 +949,14 @@ pub enum RetStyle {
 pub enum ExplicitSelf_ {
     /// No self
     SelfStatic,
-    /// `self
+    /// `self`
     SelfValue(Ident),
     /// `&'lt self`, `&'lt mut self`
     SelfRegion(Option<Lifetime>, Mutability, Ident),
     /// `~self`
-    SelfUniq(Ident)
+    SelfUniq(Ident),
+    /// `self: TYPE`
+    SelfExplicit(P<Ty>, Ident),
 }
 
 pub type ExplicitSelf = Spanned<ExplicitSelf_>;
index 46efdccadec8033d16b185da5a534b31dd8a316e..f1c1784146a84b930c9afe2ee1d76401078ee9c8 100644 (file)
@@ -954,7 +954,9 @@ fn build_enum_match_tuple(
                 // expressions for referencing every field of every
                 // Self arg, assuming all are instances of VariantK.
                 // Build up code associated with such a case.
-                let substructure = EnumMatching(index, variant, field_tuples);
+                let substructure = EnumMatching(index,
+                                                &*variant,
+                                                field_tuples);
                 let arm_expr = self.call_substructure_method(
                     cx, trait_, type_ident, self_args, nonself_args,
                     &substructure);
index f6a39d7b2e6c1b6dda6c57356f7de62592c1a98e..06eb92e1b271b1c1e333f7639be97b84a124aa02 100644 (file)
@@ -25,8 +25,6 @@
 
 /// The types of pointers
 pub enum PtrTy<'a> {
-    /// ~
-    Send,
     /// &'lifetime mut
     Borrowed(Option<&'a str>, ast::Mutability),
 }
@@ -138,9 +136,6 @@ pub fn to_ty(&self,
             Ptr(ref ty, ref ptr) => {
                 let raw_ty = ty.to_ty(cx, span, self_ty, self_generics);
                 match *ptr {
-                    Send => {
-                        cx.ty_uniq(span, raw_ty)
-                    }
                     Borrowed(ref lt, mutbl) => {
                         let lt = mk_lifetime(cx, span, lt);
                         cx.ty_rptr(span, raw_ty, lt, mutbl)
@@ -260,7 +255,6 @@ pub fn get_explicit_self(cx: &ExtCtxt, span: Span, self_ptr: &Option<PtrTy>)
             let self_ty = respan(
                 span,
                 match *ptr {
-                    Send => ast::SelfUniq(special_idents::self_),
                     Borrowed(ref lt, mutbl) => {
                         let lt = lt.map(|s| cx.lifetime(span, cx.ident_of(s).name));
                         ast::SelfRegion(lt, mutbl, special_idents::self_)
index 58689389769c9979b063793d3cc69131cd251c0a..1cbe863e4e4f9adc2ad5b191c1bc83bcea5ed920 100644 (file)
@@ -166,14 +166,14 @@ pub fn expand_expr(e: Gc<ast::Expr>, fld: &mut MacroExpander) -> Gc<ast::Expr> {
 
         ast::ExprFnBlock(fn_decl, block) => {
             let (rewritten_fn_decl, rewritten_block)
-                = expand_and_rename_fn_decl_and_block(fn_decl, block, fld);
+                = expand_and_rename_fn_decl_and_block(&*fn_decl, block, fld);
             let new_node = ast::ExprFnBlock(rewritten_fn_decl, rewritten_block);
             box(GC) ast::Expr{id:e.id, node: new_node, span: fld.new_span(e.span)}
         }
 
         ast::ExprProc(fn_decl, block) => {
             let (rewritten_fn_decl, rewritten_block)
-                = expand_and_rename_fn_decl_and_block(fn_decl, block, fld);
+                = expand_and_rename_fn_decl_and_block(&*fn_decl, block, fld);
             let new_node = ast::ExprProc(rewritten_fn_decl, rewritten_block);
             box(GC) ast::Expr{id:e.id, node: new_node, span: fld.new_span(e.span)}
         }
@@ -422,7 +422,7 @@ fn expand_item_underscore(item: &ast::Item_, fld: &mut MacroExpander) -> ast::It
     match *item {
         ast::ItemFn(decl, fn_style, abi, ref generics, body) => {
             let (rewritten_fn_decl, rewritten_body)
-                = expand_and_rename_fn_decl_and_block(decl,body,fld);
+                = expand_and_rename_fn_decl_and_block(&*decl, body, fld);
             let expanded_generics = fold::fold_generics(generics,fld);
             ast::ItemFn(rewritten_fn_decl, fn_style, abi, expanded_generics, rewritten_body)
         }
@@ -572,7 +572,9 @@ fn expand_stmt(s: &Stmt, fld: &mut MacroExpander) -> SmallVector<Gc<Stmt>> {
     };
     let expanded_stmt = match expand_mac_invoc(mac,&s.span,
                                                 |r|{r.make_stmt()},
-                                                |sts,mrk|{mark_stmt(sts,mrk)},
+                                                |sts,mrk| {
+                                                    mark_stmt(&*sts,mrk)
+                                                },
                                                 fld) {
         Some(stmt) => stmt,
         None => {
@@ -628,7 +630,7 @@ fn expand_non_macro_stmt(s: &Stmt, fld: &mut MacroExpander)
                     // names, as well... but that should be okay, as long as
                     // the new names are gensyms for the old ones.
                     // generate fresh names, push them to a new pending list
-                    let idents = pattern_bindings(expanded_pat);
+                    let idents = pattern_bindings(&*expanded_pat);
                     let mut new_pending_renames =
                         idents.iter().map(|ident| (*ident, fresh_name(ident))).collect();
                     // rewrite the pattern using the new names (the old
@@ -677,7 +679,7 @@ fn expand_arm(arm: &ast::Arm, fld: &mut MacroExpander) -> ast::Arm {
     // all of the pats must have the same set of bindings, so use the
     // first one to extract them and generate new names:
     let first_pat = expanded_pats.get(0);
-    let idents = pattern_bindings(*first_pat);
+    let idents = pattern_bindings(&**first_pat);
     let new_renames =
         idents.iter().map(|id| (*id,fresh_name(id))).collect();
     // apply the renaming, but only to the PatIdents:
@@ -732,7 +734,7 @@ fn pattern_bindings(pat : &ast::Pat) -> Vec<ast::Ident> {
 fn fn_decl_arg_bindings(fn_decl: &ast::FnDecl) -> Vec<ast::Ident> {
     let mut pat_idents = PatIdentFinder{ident_accumulator:Vec::new()};
     for arg in fn_decl.inputs.iter() {
-        pat_idents.visit_pat(arg.pat,());
+        pat_idents.visit_pat(&*arg.pat, ());
     }
     pat_idents.ident_accumulator
 }
@@ -910,7 +912,7 @@ fn expand_method(m: &ast::Method, fld: &mut MacroExpander) -> SmallVector<Gc<ast
     match m.node {
         ast::MethDecl(ident, ref generics, ref explicit_self, fn_style, decl, body, vis) => {
             let (rewritten_fn_decl, rewritten_body)
-                = expand_and_rename_fn_decl_and_block(decl,body,fld);
+                = expand_and_rename_fn_decl_and_block(&*decl,body,fld);
             SmallVector::one(box(GC) ast::Method {
                     attrs: m.attrs.iter().map(|a| fld.fold_attribute(*a)).collect(),
                     id: id,
@@ -951,12 +953,12 @@ fn expand_and_rename_fn_decl_and_block(fn_decl: &ast::FnDecl, block: Gc<ast::Blo
                                        fld: &mut MacroExpander)
     -> (Gc<ast::FnDecl>, Gc<ast::Block>) {
     let expanded_decl = fld.fold_fn_decl(fn_decl);
-    let idents = fn_decl_arg_bindings(expanded_decl);
+    let idents = fn_decl_arg_bindings(&*expanded_decl);
     let renames =
         idents.iter().map(|id : &ast::Ident| (*id,fresh_name(id))).collect();
     // first, a renamer for the PatIdents, for the fn_decl:
     let mut rename_pat_fld = PatIdentRenamer{renames: &renames};
-    let rewritten_fn_decl = rename_pat_fld.fold_fn_decl(expanded_decl);
+    let rewritten_fn_decl = rename_pat_fld.fold_fn_decl(&*expanded_decl);
     // now, a renamer for *all* idents, for the body:
     let mut rename_fld = IdentRenamer{renames: &renames};
     let rewritten_body = fld.fold_block(rename_fld.fold_block(block));
@@ -999,7 +1001,7 @@ fn fold_arm(&mut self, arm: &ast::Arm) -> ast::Arm {
     }
 
     fn fold_method(&mut self, method: Gc<ast::Method>) -> SmallVector<Gc<ast::Method>> {
-        expand_method(method, self)
+        expand_method(&*method, self)
     }
 
     fn new_span(&mut self, span: Span) -> Span {
@@ -1544,7 +1546,7 @@ macro_rules! iterator_impl {
     fn run_renaming_test(t: &RenamingTest, test_idx: uint) {
         let invalid_name = token::special_idents::invalid.name;
         let (teststr, bound_connections, bound_ident_check) = match *t {
-            (ref str,ref conns, bic) => (str.to_owned(), conns.clone(), bic)
+            (ref str,ref conns, bic) => (str.to_string(), conns.clone(), bic)
         };
         let cr = expand_crate_str(teststr.to_string());
         let bindings = crate_bindings(&cr);
@@ -1660,7 +1662,7 @@ fn run_renaming_test(t: &RenamingTest, test_idx: uint) {
     fn pat_idents(){
         let pat = string_to_pat(
             "(a,Foo{x:c @ (b,9),y:Bar(4,d)})".to_string());
-        let idents = pattern_bindings(pat);
+        let idents = pattern_bindings(&*pat);
         assert_eq!(idents, strs_to_idents(vec!("a","c","b","d")));
     }
 
index fd786192cb48c181745bf1ed0a7b7022ec9b2440..5467afab9f515e6d2f5299b1dedb61601003b388 100644 (file)
@@ -344,6 +344,7 @@ fn fold_explicit_self_(&mut self, es: &ExplicitSelf_) -> ExplicitSelf_ {
             SelfRegion(ref lifetime, m, id) => {
                 SelfRegion(fold_opt_lifetime(lifetime, self), m, id)
             }
+            SelfExplicit(ref typ, id) => SelfExplicit(self.fold_ty(*typ), id),
         }
     }
 
@@ -471,7 +472,7 @@ fn fold_interpolated<T: Folder>(nt : &token::Nonterminal, fld: &mut T) -> token:
                           .expect_one("expected fold to produce exactly one item")),
         token::NtBlock(block) => token::NtBlock(fld.fold_block(block)),
         token::NtStmt(stmt) =>
-            token::NtStmt(fld.fold_stmt(stmt)
+            token::NtStmt(fld.fold_stmt(&*stmt)
                           // this is probably okay, because the only folds likely
                           // to peek inside interpolated nodes will be renamings/markings,
                           // which map single items to single items
@@ -482,8 +483,8 @@ fn fold_interpolated<T: Folder>(nt : &token::Nonterminal, fld: &mut T) -> token:
         token::NtIdent(ref id, is_mod_name) =>
             token::NtIdent(box fld.fold_ident(**id),is_mod_name),
         token::NtMeta(meta_item) => token::NtMeta(fold_meta_item_(meta_item,fld)),
-        token::NtPath(ref path) => token::NtPath(box fld.fold_path(*path)),
-        token::NtTT(tt) => token::NtTT(box (GC) fold_tt(tt,fld)),
+        token::NtPath(ref path) => token::NtPath(box fld.fold_path(&**path)),
+        token::NtTT(tt) => token::NtTT(box (GC) fold_tt(&*tt,fld)),
         // it looks to me like we can leave out the matchers: token::NtMatchers(matchers)
         _ => (*nt).clone()
     }
index cadae7ef12f8078b38dfc67a6dde7aed99d7000f..ba401d313d87fac1a3e9b600cd49ce1679894359 100644 (file)
@@ -76,7 +76,7 @@ fn obsolete(&mut self, sp: Span, kind: ObsoleteSyntax) {
             ),
             ObsoleteManagedExpr => (
                 "`@` notation for a managed pointer allocation",
-                "use the `box(GC)` oeprator instead of `@`"
+                "use the `box(GC)` operator instead of `@`"
             ),
         };
 
index e0c94dffb5cae342603ddb9cf1fcdc6e9e9dc777..a77f24f98f81803eb6ab1317c4904dbe0d7dfbfa 100644 (file)
@@ -45,7 +45,7 @@
 use ast::{StmtExpr, StmtSemi, StmtMac, StructDef, StructField};
 use ast::{StructVariantKind, BiSub};
 use ast::StrStyle;
-use ast::{SelfRegion, SelfStatic, SelfUniq, SelfValue};
+use ast::{SelfExplicit, SelfRegion, SelfStatic, SelfUniq, SelfValue};
 use ast::{TokenTree, TraitMethod, TraitRef, TTDelim, TTSeq, TTTok};
 use ast::{TTNonterminal, TupleVariantKind, Ty, Ty_, TyBot, TyBox};
 use ast::{TypeField, TyFixedLengthVec, TyClosure, TyProc, TyBareFn};
@@ -502,7 +502,9 @@ pub fn commit_stmt(&mut self, s: Gc<Stmt>, edible: &[token::Token],
                        inedible: &[token::Token]) {
         debug!("commit_stmt {:?}", s);
         let _s = s; // unused, but future checks might want to inspect `s`.
-        if self.last_token.as_ref().map_or(false, |t| is_ident_or_path(*t)) {
+        if self.last_token
+               .as_ref()
+               .map_or(false, |t| is_ident_or_path(&**t)) {
             let expected = edible.iter().map(|x| (*x).clone()).collect::<Vec<_>>()
                            .append(inedible.as_slice());
             self.check_for_erroneous_unit_struct_expecting(
@@ -3843,7 +3845,15 @@ fn maybe_parse_borrowed_explicit_self(this: &mut Parser)
                 }
             }
             token::IDENT(..) if self.is_self_ident() => {
-                SelfValue(self.expect_self_ident())
+                let self_ident = self.expect_self_ident();
+
+                // Determine whether this is the fully explicit form, `self:
+                // TYPE`.
+                if self.eat(&token::COLON) {
+                    SelfExplicit(self.parse_ty(false), self_ident)
+                } else {
+                    SelfValue(self_ident)
+                }
             }
             token::BINOP(token::STAR) => {
                 // Possibly "*self" or "*mut self" -- not supported. Try to avoid
@@ -3851,7 +3861,9 @@ fn maybe_parse_borrowed_explicit_self(this: &mut Parser)
                 self.bump();
                 let _mutability = if Parser::token_is_mutability(&self.token) {
                     self.parse_mutability()
-                } else { MutImmutable };
+                } else {
+                    MutImmutable
+                };
                 if self.is_self_ident() {
                     let span = self.span;
                     self.span_err(span, "cannot pass self by unsafe pointer");
@@ -3863,7 +3875,15 @@ fn maybe_parse_borrowed_explicit_self(this: &mut Parser)
             _ if Parser::token_is_mutability(&self.token) &&
                     self.look_ahead(1, |t| token::is_keyword(keywords::Self, t)) => {
                 mutbl_self = self.parse_mutability();
-                SelfValue(self.expect_self_ident())
+                let self_ident = self.expect_self_ident();
+
+                // Determine whether this is the fully explicit form, `self:
+                // TYPE`.
+                if self.eat(&token::COLON) {
+                    SelfExplicit(self.parse_ty(false), self_ident)
+                } else {
+                    SelfValue(self_ident)
+                }
             }
             _ if Parser::token_is_mutability(&self.token) &&
                     self.look_ahead(1, |t| *t == token::TILDE) &&
@@ -3914,8 +3934,8 @@ macro_rules! parse_remaining_arguments {
             }
             SelfValue(id) => parse_remaining_arguments!(id),
             SelfRegion(_,_,id) => parse_remaining_arguments!(id),
-            SelfUniq(id) => parse_remaining_arguments!(id)
-
+            SelfUniq(id) => parse_remaining_arguments!(id),
+            SelfExplicit(_,id) => parse_remaining_arguments!(id),
         };
 
 
index d524622f8ecf59ad9a36eb22badd0ff88f4dd504..10caaea86cf4bc13f39d7a3be1d2d91de8268af2 100644 (file)
@@ -1859,6 +1859,11 @@ fn print_explicit_self(&mut self,
                 try!(self.print_mutability(m));
                 try!(word(&mut self.s, "self"));
             }
+            ast::SelfExplicit(ref typ, _) => {
+                try!(word(&mut self.s, "self"));
+                try!(self.word_space(":"));
+                try!(self.print_type(&**typ));
+            }
         }
         return Ok(true);
     }
index 795f19d0cfb06170050fea6da1206a8e09390189..cd953607ea22b02b2f181b2ccc5b7bf312bcf3e1 100644 (file)
@@ -215,6 +215,7 @@ pub fn walk_explicit_self<E: Clone, V: Visitor<E>>(visitor: &mut V,
         SelfRegion(ref lifetime, _, _) => {
             visitor.visit_opt_lifetime_ref(explicit_self.span, lifetime, env)
         }
+        SelfExplicit(ref typ, _) => visitor.visit_ty(&**typ, env.clone()),
     }
 }
 
@@ -564,8 +565,8 @@ pub fn walk_method_helper<E: Clone, V: Visitor<E>>(visitor: &mut V,
         MethDecl(ident, ref generics, _, _, decl, body, _) => {
             visitor.visit_ident(method.span, ident, env.clone());
             visitor.visit_fn(&FkMethod(ident, generics, method),
-                             decl,
-                             body,
+                             &*decl,
+                             &*body,
                              method.span,
                              method.id,
                              env.clone());
index 139f1113aaf9434fa3454cd3a5e85e458a306acf..db76e78d1617c89b065bd2436bf68dba90f30670 100644 (file)
@@ -512,13 +512,13 @@ fn format(val: Param, op: FormatOp, flags: Flags) -> Result<Vec<u8> ,String> {
             assert!(!s.is_empty(), "string conversion produced empty result");
             match op {
                 FormatDigit => {
-                    if flags.space && !(*s.get(0) == '-' as u8 ||
-                                        *s.get(0) == '+' as u8) {
+                    if flags.space && !(s[0] == '-' as u8 ||
+                                        s[0] == '+' as u8) {
                         s.unshift(' ' as u8);
                     }
                 }
                 FormatOctal => {
-                    if flags.alternate && *s.get(0) != '0' as u8 {
+                    if flags.alternate && s[0] != '0' as u8 {
                         s.unshift('0' as u8);
                     }
                 }
index 7ad14d797549391cf69e8b554829a08a6c1fa8e5..ebec59924e8f33094cc9e22d03c121401f3d4ca7 100644 (file)
@@ -79,7 +79,7 @@ pub fn get_dbpath_for_term(term: &str) -> Option<Box<Path>> {
 pub fn open(term: &str) -> Result<File, String> {
     match get_dbpath_for_term(term) {
         Some(x) => {
-            match File::open(x) {
+            match File::open(&*x) {
                 Ok(file) => Ok(file),
                 Err(e) => Err(format!("error opening file: {}", e)),
             }
index a857bc7535d9c3250061f2f376dede132923c088..15c5fa6b75a5ab6492b6f36681e2d25eb32feab9 100644 (file)
@@ -373,7 +373,7 @@ pub fn parse_opts(args: &[String]) -> Option<OptRes> {
     if matches.opt_present("h") { usage(args[0].as_slice()); return None; }
 
     let filter = if matches.free.len() > 0 {
-        let s = matches.free.get(0).as_slice();
+        let s = matches.free[0].as_slice();
         match Regex::new(s) {
             Ok(re) => Some(re),
             Err(e) => return Some(Err(format!("could not parse /{}/: {}", s, e)))
index 51696521165325596e99ad4df8464255dc3699ba..d8f628e2196f5780197e445dea9d45ac852c0420 100644 (file)
@@ -175,7 +175,7 @@ fn sum(self) -> T {
             // This inner loop applies `hi`/`lo` summation to each
             // partial so that the list of partial sums remains exact.
             for i in range(0, partials.len()) {
-                let mut y = *partials.get(i);
+                let mut y = partials[i];
                 if num::abs(x) < num::abs(y) {
                     mem::swap(&mut x, &mut y);
                 }
index 233743175b503f748a19c41251febe8dcf2e1474..aa13ae82e76d9758000a36c3daed2a11272c13c9 100644 (file)
@@ -398,8 +398,8 @@ pub fn parse_string(us: &str) -> Result<Uuid, ParseError> {
         match group_lens.len() {
             // Single group, no hyphens
             1 => {
-                if *group_lens.get(0) != 32 {
-                    return Err(ErrorInvalidLength(*group_lens.get(0)));
+                if group_lens[0] != 32 {
+                    return Err(ErrorInvalidLength(group_lens[0]));
                 }
             },
             // Five groups, hyphens in between each
index b63aa18b75d346a6ff9314503d0eebaabfc0a164..b0090c63969ab0e7fa0c76d629f06a0cb835f285 100644 (file)
@@ -10,6 +10,9 @@
 #![crate_id="lint_stability#0.1"]
 #![crate_type = "lib"]
 
+#![feature(macro_rules)]
+#![macro_escape]
+
 #[deprecated]
 pub fn deprecated() {}
 #[deprecated="text"]
@@ -173,3 +176,8 @@ pub enum Enum {
 pub struct FrozenTupleStruct(pub int);
 #[locked]
 pub struct LockedTupleStruct(pub int);
+
+#[macro_export]
+macro_rules! macro_test(
+    () => (deprecated());
+)
index b3deb88543ed46bdec52e56732c69bc2d20886fe..143175e558b6dbe922b8b1951c3ef9f624487e5a 100644 (file)
@@ -72,7 +72,7 @@ fn sortKV(mut orig: Vec<(Vec<u8> ,f64)> ) -> Vec<(Vec<u8> ,f64)> {
 
 // given a map, search for the frequency of a pattern
 fn find(mm: &HashMap<Vec<u8> , uint>, key: String) -> uint {
-   let key = key.to_owned().into_ascii().as_slice().to_lower().into_string();
+   let key = key.into_ascii().as_slice().to_lower().into_string();
    match mm.find_equiv(&key.as_bytes()) {
       option::None      => { return 0u; }
       option::Some(&num) => { return num; }
@@ -179,7 +179,7 @@ fn main() {
    let mut proc_mode = false;
 
    for line in rdr.lines() {
-       let line = line.unwrap().as_slice().trim().to_owned();
+       let line = line.unwrap().as_slice().trim().to_string();
 
        if line.len() == 0u { continue; }
 
index bdf6862d0b133ffa1150b60874e13ba0f14e0952..8908b5b87ed3c80f59dfc36046b473df0e254797 100644 (file)
@@ -109,7 +109,7 @@ fn main() {
     let (mut variant_strs, mut counts) = (vec!(), vec!());
     for variant in variants.move_iter() {
         let seq_arc_copy = seq_arc.clone();
-        variant_strs.push(variant.to_string().to_owned());
+        variant_strs.push(variant.to_string());
         counts.push(Future::spawn(proc() {
             count_matches(seq_arc_copy.as_slice(), &variant)
         }));
index fd96b750fc16c3c9af9c4d37b11693210a0901c5..ab2fc6c67b40171e2b3d55b44cf76b5d53d621cb 100644 (file)
@@ -30,7 +30,7 @@ fn implicit() {
     //    evaluated, but it gets freed when evaluating the second
     //    argument!
     add(
-        a,
+        &*a,
         rewrite(&mut a)); //~ ERROR cannot borrow
 }
 
index d1ab70e4aedcc0305839c2fcfa6708f6d707f21b..708eed0d113bdae823c8ca514744d6268ce4b11a 100644 (file)
@@ -30,7 +30,7 @@ fn implicit() {
     //    evaluated, but it gets moved when evaluating the second
     //    argument!
     add(
-        a,
+        &*a,
         a); //~ ERROR cannot move
 }
 
index ec31160f0d535f8e9a7e8b69d4118a907e84e3a7..735d9ece9b1a500844cf22701ee8f9412cfeee25 100644 (file)
@@ -28,5 +28,5 @@ fn main() {
   let test = |foo: &Foo| {
     ptr = box Foo { x: ptr.x + 1 };
   };
-  test(ptr); //~ ERROR cannot borrow `*ptr`
+  test(&*ptr); //~ ERROR cannot borrow `*ptr`
 }
index 561d8c679a1a444b6ea16e03cd32802360b08406..12e1240d10d633ed60cd64f8dfca1c5c2d409278 100644 (file)
@@ -31,7 +31,7 @@ fn loop_overarching_alias_mut() {
     let mut x = &mut v;
     **x += 1;
     loop {
-        borrow(v); //~ ERROR cannot borrow
+        borrow(&*v); //~ ERROR cannot borrow
     }
 }
 
@@ -41,7 +41,7 @@ fn block_overarching_alias_mut() {
     let mut v = box 3;
     let mut x = &mut v;
     for _ in range(0i, 3) {
-        borrow(v); //~ ERROR cannot borrow
+        borrow(&*v); //~ ERROR cannot borrow
     }
     *x = box 5;
 }
@@ -105,7 +105,7 @@ fn while_aliased_mut_cond(cond: bool, cond2: bool) {
     let mut x = &mut w;
     while cond {
         **x += 1;
-        borrow(v); //~ ERROR cannot borrow
+        borrow(&*v); //~ ERROR cannot borrow
         if cond2 {
             x = &mut v; //~ ERROR cannot borrow
         }
index c11a08b254f1cacce9ddb20090c180bdb623dac1..bfa890ada9f1925fc44611c2b15dfd6080a4e7e4 100644 (file)
@@ -14,7 +14,7 @@ fn borrow(v: &int, f: |x: &int|) {
 
 fn box_imm() {
     let mut v = box 3;
-    borrow(v,
+    borrow(&*v,
            |w| { //~ ERROR cannot borrow `v` as mutable
             v = box 4;
             assert_eq!(*v, 3);
index 1ea4a98c45beeefaf196787c5501b30931af1261..b9dc7953580833b18bf3df8f3f3ce612afbb3949 100644 (file)
@@ -25,7 +25,7 @@ struct F { f: Box<int> }
 
 pub fn main() {
     let mut x = box(GC) F {f: box 3};
-    borrow(x.f, |b_x| {
+    borrow(&*x.f, |b_x| {
     //~^ ERROR cannot borrow `x` as mutable because `*x.f` is also borrowed as immutable
         assert_eq!(*b_x, 3);
         assert_eq!(&(*x.f) as *const int, &(*b_x) as *const int);
index 979791ad763f56b33cfa09e4be5d0435e6d18aab..38c80f293ef248c1138b5b4b84fefab5ab41d6ef 100644 (file)
@@ -25,7 +25,7 @@ struct F { f: Box<int> }
 
 pub fn main() {
     let mut x = box box(GC) F{f: box 3};
-    borrow(x.f, |b_x| {
+    borrow(&*x.f, |b_x| {
     //~^ ERROR cannot borrow `x` as mutable because `*x.f` is also borrowed as immutable
         assert_eq!(*b_x, 3);
         assert_eq!(&(*x.f) as *const int, &(*b_x) as *const int);
index 9eadb62c3a059b0dd911ec5d45b68749562ff1a8..d838851e922ca21feba4359d108b1919f4eabce2 100644 (file)
@@ -23,7 +23,7 @@ fn borrow(x: &int, f: |x: &int|) {
 
 pub fn main() {
     let mut x = box(GC) 3;
-    borrow(x, |b_x| {
+    borrow(&*x, |b_x| {
     //~^ ERROR cannot borrow `x` as mutable because `*x` is also borrowed as immutable
         assert_eq!(*b_x, 3);
         assert_eq!(&(*x) as *const int, &(*b_x) as *const int);
index 066bb53cdc4d3ffc2cab5923e6c590b7fa0c561a..d00bded2d79cafc722811ffd699d2a5425e34779 100644 (file)
@@ -25,7 +25,7 @@ struct F { f: Box<int> }
 
 pub fn main() {
     let mut x = box(GC) F {f: box 3};
-    borrow((*x).f, |b_x| {
+    borrow(&*(*x).f, |b_x| {
     //~^ ERROR cannot borrow `x` as mutable because `*x.f` is also borrowed as immutable
         assert_eq!(*b_x, 3);
         assert_eq!(&(*x.f) as *const int, &(*b_x) as *const int);
index 5a129956487c9956069e168882fe13b99cf32cee..9785b6a8f69a349a704509a65ce47f20b80de6e8 100644 (file)
@@ -13,13 +13,13 @@ fn borrow(_v: &int) {}
 
 fn local() {
     let mut v = box 3i;
-    borrow(v);
+    borrow(&*v);
 }
 
 fn local_rec() {
     struct F { f: Box<int> }
     let mut v = F {f: box 3};
-    borrow(v.f);
+    borrow(&*v.f);
 }
 
 fn local_recs() {
@@ -27,26 +27,26 @@ struct F { f: G }
     struct G { g: H }
     struct H { h: Box<int> }
     let mut v = F {f: G {g: H {h: box 3}}};
-    borrow(v.f.g.h);
+    borrow(&*v.f.g.h);
 }
 
 fn aliased_imm() {
     let mut v = box 3i;
     let _w = &v;
-    borrow(v);
+    borrow(&*v);
 }
 
 fn aliased_mut() {
     let mut v = box 3i;
     let _w = &mut v;
-    borrow(v); //~ ERROR cannot borrow `*v`
+    borrow(&*v); //~ ERROR cannot borrow `*v`
 }
 
 fn aliased_other() {
     let mut v = box 3i;
     let mut w = box 4i;
     let _x = &mut w;
-    borrow(v);
+    borrow(&*v);
 }
 
 fn aliased_other_reassign() {
@@ -54,7 +54,7 @@ fn aliased_other_reassign() {
     let mut w = box 4i;
     let mut _x = &mut w;
     _x = &mut v;
-    borrow(v); //~ ERROR cannot borrow `*v`
+    borrow(&*v); //~ ERROR cannot borrow `*v`
 }
 
 fn main() {
diff --git a/src/test/compile-fail/explicit-self-lifetime-mismatch.rs b/src/test/compile-fail/explicit-self-lifetime-mismatch.rs
new file mode 100644 (file)
index 0000000..285792e
--- /dev/null
@@ -0,0 +1,26 @@
+// Copyright 2014 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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+struct Foo<'a,'b> {
+    x: &'a int,
+    y: &'b int,
+}
+
+impl<'a,'b> Foo<'a,'b> {
+    // The number of errors is related to the way invariance works.
+    fn bar(self: Foo<'b,'a>) {}
+    //~^ ERROR mismatched types: expected `Foo<'a,'b>` but found `Foo<'b,'a>`
+    //~^^ ERROR mismatched types: expected `Foo<'a,'b>` but found `Foo<'b,'a>`
+    //~^^^ ERROR mismatched types: expected `Foo<'b,'a>` but found `Foo<'a,'b>`
+    //~^^^^ ERROR mismatched types: expected `Foo<'b,'a>` but found `Foo<'a,'b>`
+}
+
+fn main() {}
+
index e7fa8300bcb698467d07553842fe299b66b1455a..18a00d15eafe36610d5763fa63a6a28251e2fd20 100644 (file)
@@ -25,7 +25,7 @@ fn main() {
         ptr = box Foo { x: ptr.x + 1 };
         println!("access {}", foo.x);
     };
-    test(ptr);
+    test(&*ptr);
     //~^ ERROR: cannot borrow `*ptr` as immutable
 }
 
index f8c1a91464271c58f81621e9e74822d317e61efc..57a158d2438dd98ab5b9efb0cf08fccc0b57d848 100644 (file)
 // error-pattern: type `&Foo` does not implement any method in scope named `foo`
 
 trait Foo {
-    fn foo(~self);
+    fn foo(self: Box<Self>);
 }
 
 impl Foo for int {
-    fn foo(~self) { }
+    fn foo(self: Box<int>) { }
 }
 
 fn main() {
index 18bfb7abe6c861fe89bc75b1db369bcf5fe21fae..d4073a5e98479230fd6a471426359c067c992c7d 100644 (file)
@@ -33,7 +33,7 @@ fn make_a<'a>(p: &'a X) -> A<'a> {
 
 fn make_make_a() -> A {
     let b: Box<B> = box B {i:1};
-    let bb: &B = b;    //~ ERROR does not live long enough
+    let bb: &B = &*b;    //~ ERROR does not live long enough
     make_a(bb)
 }
 
diff --git a/src/test/compile-fail/lint-allocation.rs b/src/test/compile-fail/lint-allocation.rs
deleted file mode 100644 (file)
index 1600043..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-#![deny(unnecessary_allocation)]
-
-fn f(_: &int) {}
-
-fn main() {
-    f(box 1); //~ ERROR unnecessary allocation, use & instead
-}
index 5d06ad79c9bdfe5e33d394ecaf16e4bbf4bd2357..3a9380befbcb4460401308c7574c492fdc1574bd 100644 (file)
 // aux-build:lint_stability.rs
 // aux-build:inherited_stability.rs
 
-#![feature(globs)]
+#![feature(globs, phase)]
 #![deny(unstable)]
 #![deny(deprecated)]
 #![deny(experimental)]
 #![allow(dead_code)]
 
 mod cross_crate {
+    #[phase(plugin, link)]
     extern crate lint_stability;
     use self::lint_stability::*;
 
@@ -76,7 +77,6 @@ fn test() {
         foo.method_locked_text();
         foo.trait_locked_text();
 
-
         let _ = DeprecatedStruct { i: 0 }; //~ ERROR use of deprecated item
         let _ = ExperimentalStruct { i: 0 }; //~ ERROR use of experimental item
         let _ = UnstableStruct { i: 0 }; //~ ERROR use of unstable item
@@ -108,6 +108,13 @@ fn test() {
         let _ = StableTupleStruct (1);
         let _ = FrozenTupleStruct (1);
         let _ = LockedTupleStruct (1);
+
+        // At the moment, the following just checks that the stability
+        // level of expanded code does not trigger the
+        // lint. Eventually, we will want to lint the contents of the
+        // macro in the module *defining* it. Also, stability levels
+        // on macros themselves are not yet linted.
+        macro_test!();
     }
 
     fn test_method_param<F: Trait>(foo: F) {
index 84c484a91e2c4f4f78cc7180efff3a956c353a79..fc19a1ba06f9b2324435ba2faa2d7d36cb2c38d3 100644 (file)
@@ -16,7 +16,7 @@
 struct Foo;
 impl Foo {
     fn foo(mut self) {} //~ ERROR: variable does not need to be mutable
-    fn bar(mut ~self) {} //~ ERROR: variable does not need to be mutable
+    fn bar(mut self: Box<Foo>) {} //~ ERROR: variable does not need to be mutable
 }
 
 fn main() {}
index 8868ddd4dfa302f8ac20f6533314fc1c12d95b81..84e7f98a40dc2229bd04fa6b7a6efcd1f8b7ecb8 100644 (file)
@@ -13,7 +13,7 @@ trait Foo {
     fn borrowed(&self);
     fn borrowed_mut(&mut self);
 
-    fn owned(~self);
+    fn owned(self: Box<Self>);
 }
 
 fn borrowed_receiver(x: &Foo) {
index 77988d1867952aab4d266f289844b5da1c5c1be5..028988dbd4fa5f93bb9ada80657577833fd423e9 100644 (file)
@@ -22,7 +22,7 @@ fn x_coord<'r>(p: &'r point) -> &'r int {
 }
 
 fn foo(p: Gc<point>) -> &int {
-    let xc = x_coord(p); //~ ERROR `*p` does not live long enough
+    let xc = x_coord(&*p); //~ ERROR `*p` does not live long enough
     assert_eq!(*xc, 3);
     return xc;
 }
index 0aff58c34cc23d21e70aa002f7d51769db7a1f4a..bb021d4135a160cd320847414c7ca3f23c57503f 100644 (file)
@@ -21,7 +21,7 @@ fn foo(cond: || -> bool, make_box: || -> Gc<int>) {
 
         // Here we complain because the resulting region
         // of this borrow is the fn body as a whole.
-        y = borrow(x); //~ ERROR `*x` does not live long enough
+        y = borrow(&*x); //~ ERROR `*x` does not live long enough
 
         assert_eq!(*x, *y);
         if cond() { break; }
index 62e6a404838c240639b7e171de8e597489851d0a..24dcfb87ad884e24d4985ba8ff6e576f21007080 100644 (file)
@@ -42,7 +42,7 @@ fn make_make_a() -> A {
     let b: Box<B> = box B {
         i: 1,
     };
-    let bb: &B = b; //~ ERROR `*b` does not live long enough
+    let bb: &B = &*b; //~ ERROR `*b` does not live long enough
     make_a(bb)
 }
 
index b6ce848a7d8fb17e03685d9d1de7657065ec7f55..bfa8f402a82db33d356f14d4931f7edacd0ef1da 100644 (file)
@@ -1,3 +1,5 @@
+// ignore-test
+
 // Copyright 2014 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 +19,6 @@ struct Foo<'a> {
 }
 
 pub fn main() {
-    let f = Foo { x: box(GC) 3 }; //~ ERROR borrowed value does not live long enough
+    let f = Foo { x: &*(box(GC) 3) }; //~ ERROR borrowed value does not live long enough
     assert_eq!(*f.x, 3);
 }
diff --git a/src/test/compile-fail/ufcs-explicit-self-bad.rs b/src/test/compile-fail/ufcs-explicit-self-bad.rs
new file mode 100644 (file)
index 0000000..e5bad7e
--- /dev/null
@@ -0,0 +1,49 @@
+// 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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use std::owned::Box;
+
+struct Foo {
+    f: int,
+}
+
+impl Foo {
+    fn foo(self: int, x: int) -> int {  //~ ERROR mismatched self type
+//~^ ERROR not a valid type for `self`
+        self.f + x
+    }
+}
+
+struct Bar<T> {
+    f: T,
+}
+
+impl<T> Bar<T> {
+    fn foo(self: Bar<int>, x: int) -> int { //~ ERROR mismatched self type
+//~^ ERROR not a valid type for `self`
+        x
+    }
+    fn bar(self: &Bar<uint>, x: int) -> int {   //~ ERROR mismatched self type
+//~^ ERROR not a valid type for `self`
+        x
+    }
+}
+
+fn main() {
+    let foo = box Foo {
+        f: 1,
+    };
+    println!("{}", foo.foo(2));
+    let bar = box Bar {
+        f: 1,
+    };
+    println!("{} {}", bar.foo(2), bar.bar(2));
+}
+
index 82e44b46d3c8c10e183851b0cf6c2b7883475c8f..8e924a46d9aaa944261ac8d0f32e617cea59d8e8 100644 (file)
 
 fn main() {
     let bool_box: Gc<bool> = box(GC) true;
-    let bool_ref: &bool = bool_box;
+    let bool_ref: &bool = &*bool_box;
 
     let int_box: Gc<int> = box(GC) -1;
-    let int_ref: &int = int_box;
+    let int_ref: &int = &*int_box;
 
     let char_box: Gc<char> = box(GC) 'a';
-    let char_ref: &char = char_box;
+    let char_ref: &char = &*char_box;
 
     let i8_box: Gc<i8> = box(GC) 68;
-    let i8_ref: &i8 = i8_box;
+    let i8_ref: &i8 = &*i8_box;
 
     let i16_box: Gc<i16> = box(GC) -16;
-    let i16_ref: &i16 = i16_box;
+    let i16_ref: &i16 = &*i16_box;
 
     let i32_box: Gc<i32> = box(GC) -32;
-    let i32_ref: &i32 = i32_box;
+    let i32_ref: &i32 = &*i32_box;
 
     let i64_box: Gc<i64> = box(GC) -64;
-    let i64_ref: &i64 = i64_box;
+    let i64_ref: &i64 = &*i64_box;
 
     let uint_box: Gc<uint> = box(GC) 1;
-    let uint_ref: &uint = uint_box;
+    let uint_ref: &uint = &*uint_box;
 
     let u8_box: Gc<u8> = box(GC) 100;
-    let u8_ref: &u8 = u8_box;
+    let u8_ref: &u8 = &*u8_box;
 
     let u16_box: Gc<u16> = box(GC) 16;
-    let u16_ref: &u16 = u16_box;
+    let u16_ref: &u16 = &*u16_box;
 
     let u32_box: Gc<u32> = box(GC) 32;
-    let u32_ref: &u32 = u32_box;
+    let u32_ref: &u32 = &*u32_box;
 
     let u64_box: Gc<u64> = box(GC) 64;
-    let u64_ref: &u64 = u64_box;
+    let u64_ref: &u64 = &*u64_box;
 
     let f32_box: Gc<f32> = box(GC) 2.5;
-    let f32_ref: &f32 = f32_box;
+    let f32_ref: &f32 = &*f32_box;
 
     let f64_box: Gc<f64> = box(GC) 3.5;
-    let f64_ref: &f64 = f64_box;
+    let f64_ref: &f64 = &*f64_box;
 
     zzz(); // #break
 }
index 5ad0fe89d2cdfefd7916d0fd6e2de4ed0f22a2b1..ed56c19869f2261b87f8693c561d4ce106b3e416 100644 (file)
@@ -100,12 +100,12 @@ fn main() {
     let ref_to_unnamed: &SomeStruct = &SomeStruct { x: 11, y: 24.5 };
 
     let managed_val = box(GC) SomeStruct { x: 12, y: 25.5 };
-    let managed_val_ref: &SomeStruct = managed_val;
+    let managed_val_ref: &SomeStruct = &*managed_val;
     let managed_val_interior_ref_1: &int = &managed_val.x;
     let managed_val_interior_ref_2: &f64 = &managed_val.y;
 
     let unique_val = box SomeStruct { x: 13, y: 26.5 };
-    let unique_val_ref: &SomeStruct = unique_val;
+    let unique_val_ref: &SomeStruct = &*unique_val;
     let unique_val_interior_ref_1: &int = &unique_val.x;
     let unique_val_interior_ref_2: &f64 = &unique_val.y;
 
index 5c20c7471ec26a012f64cc7455109fb4100527ac..583906b7b3070ea0a997d3c784f4ae1b82574297 100644 (file)
@@ -60,10 +60,10 @@ fn main() {
     let ref_to_unnamed: &(i16, f32) = &(-15, -20f32);
 
     let managed_val: Gc<(i16, f32)> = box(GC) (-16, -21f32);
-    let managed_val_ref: &(i16, f32) = managed_val;
+    let managed_val_ref: &(i16, f32) = &*managed_val;
 
     let unique_val: Box<(i16, f32)> = box() (-17, -22f32);
-    let unique_val_ref: &(i16, f32) = unique_val;
+    let unique_val_ref: &(i16, f32) = &*unique_val;
 
     zzz(); // #break
 }
index 821c85fdcf3a06e54415014cdc1e9e3bc45d313a..4a5df78b5c61ecb4399e0ca4a117e742bdbdb811 100644 (file)
 
 fn main() {
     let bool_box: Box<bool> = box true;
-    let bool_ref: &bool = bool_box;
+    let bool_ref: &bool = &*bool_box;
 
     let int_box: Box<int> = box -1;
-    let int_ref: &int = int_box;
+    let int_ref: &int = &*int_box;
 
     let char_box: Box<char> = box 'a';
-    let char_ref: &char = char_box;
+    let char_ref: &char = &*char_box;
 
     let i8_box: Box<i8> = box 68;
-    let i8_ref: &i8 = i8_box;
+    let i8_ref: &i8 = &*i8_box;
 
     let i16_box: Box<i16> = box -16;
-    let i16_ref: &i16 = i16_box;
+    let i16_ref: &i16 = &*i16_box;
 
     let i32_box: Box<i32> = box -32;
-    let i32_ref: &i32 = i32_box;
+    let i32_ref: &i32 = &*i32_box;
 
     let i64_box: Box<i64> = box -64;
-    let i64_ref: &i64 = i64_box;
+    let i64_ref: &i64 = &*i64_box;
 
     let uint_box: Box<uint> = box 1;
-    let uint_ref: &uint = uint_box;
+    let uint_ref: &uint = &*uint_box;
 
     let u8_box: Box<u8> = box 100;
-    let u8_ref: &u8 = u8_box;
+    let u8_ref: &u8 = &*u8_box;
 
     let u16_box: Box<u16> = box 16;
-    let u16_ref: &u16 = u16_box;
+    let u16_ref: &u16 = &*u16_box;
 
     let u32_box: Box<u32> = box 32;
-    let u32_ref: &u32 = u32_box;
+    let u32_ref: &u32 = &*u32_box;
 
     let u64_box: Box<u64> = box 64;
-    let u64_ref: &u64 = u64_box;
+    let u64_ref: &u64 = &*u64_box;
 
     let f32_box: Box<f32> = box 2.5;
-    let f32_ref: &f32 = f32_box;
+    let f32_ref: &f32 = &*f32_box;
 
     let f64_box: Box<f64> = box 3.5;
-    let f64_ref: &f64 = f64_box;
+    let f64_ref: &f64 = &*f64_box;
 
     zzz(); // #break
 }
index 0f05eea62821318510363eb4f2580b5ff326f38b..2e43dcdeb498efe9599b35386b922dd65ad09696 100644 (file)
@@ -134,7 +134,7 @@ fn self_by_val<T2>(self, arg1: int, arg2: T2) -> int {
         arg1
     }
 
-    fn self_owned<T2>(~self, arg1: int, arg2: T2) -> int {
+    fn self_owned<T2>(self: Box<Struct<T1>>, arg1: int, arg2: T2) -> int {
         zzz(); // #break
         arg1
     }
index f3d723e88bc515d6bc0f11d3ffd15835247b7048..74f4882bd4bf494918a01cb3515fcf98735a90c5 100644 (file)
@@ -136,7 +136,7 @@ fn self_by_val(self, arg1: int, arg2: int) -> int {
         arg1 + arg2
     }
 
-    fn self_owned(~self, arg1: int, arg2: int) -> int {
+    fn self_owned(self: Box<Enum>, arg1: int, arg2: int) -> int {
         zzz(); // #break
         arg1 + arg2
     }
index 489ea114e1f598766f708016e67baac5bd292e8c..590a821fcb6e10017d1af6240eca4af91613c925 100644 (file)
@@ -134,7 +134,7 @@ fn self_by_val(self, arg1: int, arg2: int) -> int {
         arg1 + arg2
     }
 
-    fn self_owned(~self, arg1: int, arg2: int) -> int {
+    fn self_owned(self: Box<Struct<T>>, arg1: int, arg2: int) -> int {
         zzz(); // #break
         arg1 + arg2
     }
index f2db6e3af471e2d6bcb33a42724f5fd97b35c207..5ea89f1548915e520dca0b9accf293edf72759aa 100644 (file)
@@ -133,7 +133,7 @@ fn self_by_val(self, arg1: int, arg2: int) -> int {
         self.x + arg1 + arg2
     }
 
-    fn self_owned(~self, arg1: int, arg2: int) -> int {
+    fn self_owned(self: Box<Struct>, arg1: int, arg2: int) -> int {
         zzz(); // #break
         self.x + arg1 + arg2
     }
index e38aace11b93bf334c9fab100296495e5a31b427..1fc136ac1f695c95945871dbebc40f604cb1f5bb 100644 (file)
@@ -124,7 +124,7 @@ struct Struct {
 trait Trait {
     fn self_by_ref(&self, arg1: int, arg2: int) -> int;
     fn self_by_val(self, arg1: int, arg2: int) -> int;
-    fn self_owned(~self, arg1: int, arg2: int) -> int;
+    fn self_owned(self: Box<Self>, arg1: int, arg2: int) -> int;
 }
 
 impl Trait for Struct {
@@ -139,7 +139,7 @@ fn self_by_val(self, arg1: int, arg2: int) -> int {
         self.x + arg1 + arg2
     }
 
-    fn self_owned(~self, arg1: int, arg2: int) -> int {
+    fn self_owned(self: Box<Struct>, arg1: int, arg2: int) -> int {
         zzz(); // #break
         self.x + arg1 + arg2
     }
index 6f8a6182063b7ccab0fe531851c357e0e6d352bd..d4051e333c184319761c5e21e7853e2ed28f1529 100644 (file)
@@ -131,7 +131,7 @@ fn self_by_val(self, arg1: int, arg2: int) -> int {
         arg1 + arg2
     }
 
-    fn self_owned(~self, arg1: int, arg2: int) -> int {
+    fn self_owned(self: Box<TupleStruct>, arg1: int, arg2: int) -> int {
         zzz(); // #break
         arg1 + arg2
     }
index ddca9bf0792f22199244aa9de271e99eb74e3bd9..4268c0adcc396f6408b976ab139c88009c10161f 100644 (file)
@@ -133,7 +133,7 @@ fn self_by_val(self, arg1: int, arg2: int) -> int {
         arg1 + arg2
     }
 
-    fn self_owned(~self, arg1: int, arg2: int) -> int {
+    fn self_owned(self: Box<Self>, arg1: int, arg2: int) -> int {
         zzz(); // #break
         arg1 + arg2
     }
index 57ffc4a2e19d68129b66805ff0c2f88a60fa9d70..35f3dffa0b63748fe64c1e66d1353768e2385450 100644 (file)
@@ -134,7 +134,7 @@ fn self_by_val<T>(self, arg1: int, arg2: T) -> int {
         arg1
     }
 
-    fn self_owned<T>(~self, arg1: int, arg2: T) -> int {
+    fn self_owned<T>(self: Box<Self>, arg1: int, arg2: T) -> int {
         zzz(); // #break
         arg1
     }
index cd100415cbec6bc753983261ae900b6ae3ce3e6d..e87c23b96e276079592a67677099e752d1affd53 100644 (file)
@@ -58,7 +58,7 @@ fn main() {
 
     let closure: proc() = proc() {
         zzz(); // #break
-        do_something(&constant, &a_struct.a, owned);
+        do_something(&constant, &a_struct.a, &*owned);
     };
 
     closure();
index e50825a401fc6da83d1173962c879b63bc0b9aa9..f13f598fda28c26032f3bf7bc96574e77392fb48 100644 (file)
 
 
 trait double {
-    fn double(~self) -> uint;
+    fn double(self: Box<Self>) -> uint;
 }
 
 impl double for uint {
-    fn double(~self) -> uint { *self * 2u }
+    fn double(self: Box<uint>) -> uint { *self * 2u }
 }
 
 pub fn main() {
index 7acd54788a8c2d0016072e9ae43373a41932058f..856ee686db30e89c988c547aa97b6d6b5197ed7b 100644 (file)
 
 
 trait double {
-    fn double(~self) -> uint;
+    fn double(self: Box<Self>) -> uint;
 }
 
 impl double for Box<uint> {
-    fn double(~self) -> uint { **self * 2u }
+    fn double(self: Box<Box<uint>>) -> uint { **self * 2u }
 }
 
 pub fn main() {
index a8b6b6f74f4ff7dc3d8ec088e65c57d97daaca1d..94da61483eaaecf1f58f57996f2491c8b97a13ca 100644 (file)
@@ -9,11 +9,11 @@
 // except according to those terms.
 
 trait double {
-    fn double(~self) -> uint;
+    fn double(self: Box<Self>) -> uint;
 }
 
 impl double for uint {
-    fn double(~self) -> uint { *self * 2u }
+    fn double(self: Box<uint>) -> uint { *self * 2u }
 }
 
 pub fn main() {
index 4c4ebdc94f030232f0c7d40de09b7fb0718d8c0b..2e9751ce6acfccd405f527709718962891cf0898 100644 (file)
@@ -9,11 +9,11 @@
 // except according to those terms.
 
 trait double {
-    fn double(~self) -> uint;
+    fn double(self: Box<Self>) -> uint;
 }
 
 impl double for uint {
-    fn double(~self) -> uint { *self * 2u }
+    fn double(self: Box<uint>) -> uint { *self * 2u }
 }
 
 pub fn main() {
index 3823a7033f5a61c536ab9a57ed5a81d5660d8aa7..281167ff46c86aca23c79ef984270c667f9bb061 100644 (file)
@@ -15,7 +15,7 @@
 fn bitv_test() {
     let mut v1 = box Bitv::with_capacity(31, false);
     let v2 = box Bitv::with_capacity(31, true);
-    v1.union(v2);
+    v1.union(&*v2);
 }
 
 pub fn main() {
index 68d1b74e2019be47c30f5c4602a5d79f03e6f354..9b8fa8f9f79b2a0e48a244c55ddcdc35409f0bc2 100644 (file)
 fn borrow(_v: &int) {}
 
 fn borrow_from_arg_imm_ref(v: Box<int>) {
-    borrow(v);
+    borrow(&*v);
 }
 
 fn borrow_from_arg_mut_ref(v: &mut Box<int>) {
-    borrow(*v);
+    borrow(&**v);
 }
 
 fn borrow_from_arg_copy(v: Box<int>) {
-    borrow(v);
+    borrow(&*v);
 }
 
 pub fn main() {
index c0be4abafbe9a2f28c22d0919ed40bf81f4f79f1..993ce37a1eca7b88ef6950acba11faab385cf724 100644 (file)
@@ -32,7 +32,7 @@ pub fn main() {
     add_int(&mut *ints, 22);
     add_int(&mut *ints, 44);
 
-    iter_ints(ints, |i| {
+    iter_ints(&*ints, |i| {
         println!("int = {}", *i);
         true
     });
index eda8637adc4cf245039443f8b809b513320f1f7a..35cdfb41abca047268b7bc53e7d9af6eb0ba6b58 100644 (file)
@@ -18,5 +18,5 @@ struct Rec { f: Gc<int> }
 
 pub fn main() {
     let rec = box(GC) Rec {f: box(GC) 22};
-    while *borrow(rec.f) == 23 {}
+    while *borrow(&*rec.f) == 23 {}
 }
index 451f9ccf5bd6d9d12200a9f0b037ad7ac9b67b9c..84bd70c78d4871c2ed5550fddb94c117889b476c 100644 (file)
@@ -28,27 +28,27 @@ struct Innermost {
 fn borrow(_v: &int) {}
 
 fn box_mut(v: &mut Box<int>) {
-    borrow(*v); // OK: &mut -> &imm
+    borrow(&**v); // OK: &mut -> &imm
 }
 
 fn box_mut_rec(v: &mut Rec) {
-    borrow(v.f); // OK: &mut -> &imm
+    borrow(&*v.f); // OK: &mut -> &imm
 }
 
 fn box_mut_recs(v: &mut Outer) {
-    borrow(v.f.g.h); // OK: &mut -> &imm
+    borrow(&*v.f.g.h); // OK: &mut -> &imm
 }
 
 fn box_imm(v: &Box<int>) {
-    borrow(*v); // OK
+    borrow(&**v); // OK
 }
 
 fn box_imm_rec(v: &Rec) {
-    borrow(v.f); // OK
+    borrow(&*v.f); // OK
 }
 
 fn box_imm_recs(v: &Outer) {
-    borrow(v.f.g.h); // OK
+    borrow(&*v.f.g.h); // OK
 }
 
 pub fn main() {
index 324fb428df019d49f34d927decfe1fa0589cc4c6..32b4065439f93e1411d8bc0c53281525b028e14e 100644 (file)
@@ -18,7 +18,7 @@
 
 pub fn main() {
     let p = box(GC) 22u;
-    let r = foo(p);
+    let r = foo(&*p);
     println!("r={}", r);
     assert_eq!(r, 22u);
 }
index 595bb4f6b9e442b48bcfb2b97bbc85c27669056d..e566f218aa8f61b02486073e7774071f545be693 100644 (file)
@@ -10,7 +10,7 @@
 
 
 trait Foo {
-    fn f(~self);
+    fn f(self: Box<Self>);
 }
 
 struct S {
@@ -18,7 +18,7 @@ struct S {
 }
 
 impl Foo for S {
-    fn f(~self) {
+    fn f(self: Box<S>) {
         assert_eq!(self.x, 3);
     }
 }
index 6c2e17046d3c17498a02fa99d7ad000d782e7c77..32ac14ab18074ccdce1e5ae26191203bf5693874 100644 (file)
@@ -57,7 +57,7 @@ fn thing(x: A) -> thing {
 }
 
 impl thing {
-    pub fn bar(~self) -> int { self.x.a }
+    pub fn bar(self: Box<thing>) -> int { self.x.a }
     pub fn quux(&self) -> int { self.x.a }
     pub fn baz<'a>(&'a self) -> &'a A { &self.x }
     pub fn spam(self) -> int { self.x.a }
index c05e84b6e69f58964caee33907d020778eeca8ad..291fab29584ddb5841595c6f9033f926ce61a496 100644 (file)
@@ -15,6 +15,6 @@
 
 pub fn main() {
     let mut m = HashMap::new();
-    m.insert("foo".as_bytes().to_owned(), "bar".as_bytes().to_owned());
+    m.insert(b"foo".to_vec(), b"bar".to_vec());
     println!("{:?}", m);
 }
index 00878189627aebf0a64f4b5404d33ca0d4280fac..9414a6f2302df7fe6285cf8c49bf1df73a45f3d1 100644 (file)
@@ -34,8 +34,7 @@ fn print_s(s: &S) {
 
 pub fn main() {
     let s: Box<S> = box S { s: 5 };
-    print_s(s);
+    print_s(&*s);
     let t: Box<T> = s as Box<T>;
     print_t(t);
-
 }
index 3ebc3e645737626a839859effb12ba98a3d4a16c..15423121fda6c4581a3ff6bfb6743ae5e37e1620 100644 (file)
@@ -56,7 +56,7 @@ enum Result {
 }
 
 priv fn chop(s: String) -> String {
-  s.slice(0, s.len() - 1).to_owned()
+  s.slice(0, s.len() - 1).to_string()
 }
 
 priv fn parse_bulk(io: @io::Reader) -> Result {
index c99fb7765fb23324046740c9f96d24d246f7fc1d..2d8f966caf1bfb80b41d0de537bfab19b28f60d5 100644 (file)
@@ -22,7 +22,7 @@ struct Bar<'a> {
 }
 
 fn check(a: Gc<Foo>) {
-    let _ic = Bar{ b: a, a: box None };
+    let _ic = Bar{ b: &*a, a: box None };
 }
 
 pub fn main(){}
index 99ed4288a7ec109bd6d7b06d89a4dd484c5c9880..c7087f8e3a8ca5982663b681e72850ff75d27f26 100644 (file)
@@ -10,7 +10,7 @@
 
 
 trait Foo {
-    fn foo(~self) { bar(self as Box<Foo>); }
+    fn foo(self: Box<Self>) { bar(self as Box<Foo>); }
 }
 
 fn bar(_b: Box<Foo>) { }
index 477f3b2acafda53ee608b36574dd02c06d0e3110..6bea1aebc458815496d1d789eae4d0da734bd71e 100644 (file)
@@ -10,7 +10,7 @@
 
 fn f() {
     let a = box 1;
-    let b: &int = a;
+    let b: &int = &*a;
     println!("{}", b);
 }
 
index d41896ffb41d09d695acecadff2ed10781a5b305..38f552e9a9846e4085ba67fd3d3dedd9dd4ee4d7 100644 (file)
@@ -10,7 +10,7 @@
 
 
 fn f(x: Box<int>) {
-    let y: &int = x;
+    let y: &int = &*x;
     println!("{}", *x);
     println!("{}", *y);
 }
index 540593c43fbfd6b84f59381b6f4158cf28c6c81f..14ddc5d660f0cea9d71ab409c065643ce2aa3c2e 100644 (file)
@@ -14,7 +14,7 @@
 
 
 trait FooTrait {
-    fn foo(~self) -> uint;
+    fn foo(self: Box<Self>) -> uint;
 }
 
 struct BarStruct {
@@ -22,7 +22,7 @@ struct BarStruct {
 }
 
 impl FooTrait for BarStruct {
-    fn foo(~self) -> uint {
+    fn foo(self: Box<BarStruct>) -> uint {
         self.x
     }
 }
index c6dfbabd448db02be25cb0028f56687901ed53ba..74990432d03e0241fc0a32a31374a5a7fac3fcfc 100644 (file)
@@ -18,7 +18,7 @@ fn foo(x: &uint) -> uint {
 
 pub fn main() {
     let p = box(GC) 22u;
-    let r = foo(p);
+    let r = foo(&*p);
     println!("r={}", r);
     assert_eq!(r, 22u);
 }
index 6b35c0768d79a5018d1bd26e57edefd30e3a8608..36f7d88f7d79731fb4a29d2e8256b36b9df3142a 100644 (file)
@@ -14,6 +14,6 @@ fn foo(x: &uint) -> uint {
 
 pub fn main() {
     let p = box 3u;
-    let r = foo(p);
+    let r = foo(&*p);
     assert_eq!(r, 3u);
 }
index 695a1b110da4e6a86d4980cecb9021ccbce7324a..5e2893c49809e45e901752866063ea2a83ca7c44 100644 (file)
@@ -17,5 +17,5 @@ fn bar(x: &uint) -> uint { *x }
 
 pub fn main() {
     let p = box(GC) 3u;
-    assert_eq!(bar(foo(p)), 3);
+    assert_eq!(bar(foo(&*p)), 3);
 }
index 8f05531853390cd2f51d395e0e60c49595ea241f..0b42f71fccb051e41fb69a318b6dbdeb45fcf599 100644 (file)
@@ -15,7 +15,7 @@ fn borrow<'r, T>(x: &'r T) -> &'r T {x}
 pub fn main() {
     let x = box(GC) 3i;
     loop {
-        let y = borrow(x);
+        let y = borrow(&*x);
         assert_eq!(*x, *y);
         break;
     }
index c757762245325038657ddefe0ff425fd4affd501..abbbb51580fb7f0ccf2f3dfd63c463720f91b7ac 100644 (file)
@@ -20,6 +20,6 @@ fn x_coord<'r>(p: &'r Point) -> &'r int {
 
 pub fn main() {
     let p = box(GC) Point {x: 3, y: 4};
-    let xc = x_coord(p);
+    let xc = x_coord(&*p);
     assert_eq!(*xc, 3);
 }
index 8ab27cfb4ee232d7f9c050dea488469d47084bf4..b4a46f34015a2455e78c0a27b74ff7e08d9550ea 100644 (file)
@@ -19,7 +19,7 @@ fn change(mut self) -> Self {
         self
     }
 
-    fn change_again(mut ~self) -> Box<Self> {
+    fn change_again(mut self: Box<Self>) -> Box<Self> {
         self.set_to(45);
         self
     }
diff --git a/src/test/run-pass/ufcs-explicit-self.rs b/src/test/run-pass/ufcs-explicit-self.rs
new file mode 100644 (file)
index 0000000..9ffb56c
--- /dev/null
@@ -0,0 +1,57 @@
+// 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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use std::owned::Box;
+
+struct Foo {
+    f: int,
+}
+
+impl Foo {
+    fn foo(self: Foo, x: int) -> int {
+        self.f + x
+    }
+    fn bar(self: &Foo, x: int) -> int {
+        self.f + x
+    }
+    fn baz(self: Box<Foo>, x: int) -> int {
+        self.f + x
+    }
+}
+
+struct Bar<T> {
+    f: T,
+}
+
+impl<T> Bar<T> {
+    fn foo(self: Bar<T>, x: int) -> int {
+        x
+    }
+    fn bar<'a>(self: &'a Bar<T>, x: int) -> int {
+        x
+    }
+    fn baz(self: Bar<T>, x: int) -> int {
+        x
+    }
+}
+
+fn main() {
+    let foo = box Foo {
+        f: 1,
+    };
+    println!("{} {} {}", foo.foo(2), foo.bar(2), foo.baz(2));
+    let bar = box Bar {
+        f: 1,
+    };
+    println!("{} {} {}", bar.foo(2), bar.bar(2), bar.baz(2));
+    let bar: Box<Bar<int>> = bar;
+    println!("{} {} {}", bar.foo(2), bar.bar(2), bar.baz(2));
+}
+
index 3700e02051a699ef6299206c076c6ec273174007..4d7830e1cdca1ee70435b871410ca31d1cb1a7a0 100644 (file)
@@ -14,11 +14,11 @@ struct X {
 }
 
 trait Changer {
-    fn change(mut ~self) -> Box<Self>;
+    fn change(mut self: Box<Self>) -> Box<Self>;
 }
 
 impl Changer for X {
-    fn change(mut ~self) -> Box<X> {
+    fn change(mut self: Box<X>) -> Box<X> {
         self.a = 55;
         self
     }