]> git.lizzy.rs Git - rust.git/commitdiff
auto merge of #15377 : alexcrichton/rust/rollup, r=alexcrichton
authorbors <bors@rust-lang.org>
Thu, 3 Jul 2014 21:46:47 +0000 (21:46 +0000)
committerbors <bors@rust-lang.org>
Thu, 3 Jul 2014 21:46:47 +0000 (21:46 +0000)
Closes #15276 (Guide: if)
Closes #15280 (std::os - Add join_paths, make setenv non-utf8 capable)
Closes #15314 (Guide: functions)
Closes #15327 (Simplify PatIdent to contain an Ident rather than a Path)
Closes #15340 (Guide: add mutable binding section)
Closes #15342 (Fix ICE with nested macro_rules!-style macros)
Closes #15350 (Remove duplicated slash in install script path)
Closes #15351 (correct a few spelling mistakes in the tutorial)
Closes #15352 (librustc: Have the kind checker check sub-bounds in trait casts.)
Closes #15359 (Fix spelling errors.)
Closes #15361 (Rename set_broadast() to set_broadcast().)
Closes #15366 (Simplify creating a parser from a token tree)
Closes #15367 (Add examples for StrVector methods)
Closes #15372 (Vec::grow should use reserve_additional, Vec::reserve should check against capacity)
Closes #15373 (Fix minor issues in the documentation of libtime.)

68 files changed:
src/doc/guide.md
src/doc/tutorial.md
src/etc/install.sh
src/liballoc/arc.rs
src/libcollections/str.rs
src/libcollections/vec.rs
src/libfourcc/lib.rs
src/libgreen/stack.rs
src/libhexfloat/lib.rs
src/liblog/lib.rs
src/libnative/io/net.rs
src/libnative/io/pipe_win32.rs
src/libregex_macros/lib.rs
src/librlibc/lib.rs
src/librustc/back/link.rs
src/librustc/lint/builtin.rs
src/librustc/metadata/encoder.rs
src/librustc/middle/borrowck/gather_loans/gather_moves.rs
src/librustc/middle/borrowck/gather_loans/move_error.rs
src/librustc/middle/dead.rs
src/librustc/middle/kind.rs
src/librustc/middle/liveness.rs
src/librustc/middle/mem_categorization.rs
src/librustc/middle/pat_util.rs
src/librustc/middle/privacy.rs
src/librustc/middle/resolve.rs
src/librustc/middle/save/mod.rs
src/librustc/middle/trans/_match.rs
src/librustc/middle/trans/debuginfo.rs
src/librustc/middle/ty.rs
src/librustc/middle/typeck/check/_match.rs
src/librustc/middle/typeck/check/mod.rs
src/librustc/middle/typeck/check/vtable.rs
src/librustc/middle/typeck/infer/unify.rs
src/librustc/middle/typeck/mod.rs
src/librustdoc/clean/mod.rs
src/librustrt/c_str.rs
src/librustrt/libunwind.rs
src/librustrt/task.rs
src/librustrt/thread.rs
src/librustuv/lib.rs
src/librustuv/stream.rs
src/librustuv/timer.rs
src/libstd/io/net/ip.rs
src/libstd/io/net/udp.rs
src/libstd/os.rs
src/libstd/rt/backtrace.rs
src/libsync/comm/oneshot.rs
src/libsync/comm/shared.rs
src/libsync/mutex.rs
src/libsyntax/ast.rs
src/libsyntax/ast_util.rs
src/libsyntax/ext/asm.rs
src/libsyntax/ext/base.rs
src/libsyntax/ext/build.rs
src/libsyntax/ext/cfg.rs
src/libsyntax/ext/deriving/generic/mod.rs
src/libsyntax/ext/expand.rs
src/libsyntax/ext/format.rs
src/libsyntax/ext/quote.rs
src/libsyntax/fold.rs
src/libsyntax/parse/mod.rs
src/libsyntax/parse/parser.rs
src/libsyntax/print/pprust.rs
src/libsyntax/visit.rs
src/libtime/lib.rs
src/test/compile-fail/issue-10536.rs [new file with mode: 0644]
src/test/compile-fail/kindck-impl-type-params.rs [new file with mode: 0644]

index 0fc9671c4db292c4bcc05baa38eea38c1a52c261..aca726812d2c6b1bc3710d0e2170226e4e88eed2 100644 (file)
@@ -515,9 +515,45 @@ let x: int = 5;
 ```
 
 If I asked you to read this out loud to the rest of the class, you'd say "`x`
-is a binding with the type `int` and the value `five`." Rust requires you to
-initialize the binding with a value before you're allowed to use it. If
-we try...
+is a binding with the type `int` and the value `five`."
+
+By default, bindings are **immutable**. This code will not compile:
+
+```{ignore}
+let x = 5i;
+x = 10i;
+```
+
+It will give you this error:
+
+```{ignore,notrust}
+error: re-assignment of immutable variable `x`
+     x = 10i;
+     ^~~~~~~
+```
+
+If you want a binding to be mutable, you can use `mut`:
+
+```{rust}
+let mut x = 5i;
+x = 10i;
+```
+
+There is no single reason that bindings are immutable by default, but we can
+think about it through one of Rust's primary focuses: safety. If you forget to
+say `mut`, the compiler will catch it, and let you know that you have mutated
+something you may not have cared to mutate. If bindings were mutable by
+default, the compiler would not be able to tell you this. If you _did_ intend
+mutation, then the solution is quite easy: add `mut`.
+
+There are other good reasons to avoid mutable state when possible, but they're
+out of the scope of this guide. In general, you can often avoid explicit
+mutation, and so it is preferable in Rust. That said, sometimes, mutation is
+what you need, so it's not verboten.
+
+Let's get back to bindings. Rust variable bindings have one more aspect that
+differs from other languages: bindings are required to be initialized with a
+value before you're allowed to use it. If we try...
 
 ```{ignore}
 let x;
@@ -611,8 +647,301 @@ concept: `if`.
 
 ## If
 
+Rust's take on `if` is not particularly complex, but it's much more like the
+`if` you'll find in a dynamically typed language than in a more traditional
+systems language. So let's talk about it, to make sure you grasp the nuances.
+
+`if` is a specific form of a more general concept, the 'branch.' The name comes
+from a branch in a tree: a decision point, where depending on a choice,
+multiple paths can be taken.
+
+In the case of `if`, there is one choice that leads down two paths:
+
+```rust
+let x = 5i;
+
+if x == 5i {
+    println!("x is five!");
+}
+```
+
+If we changed the value of `x` to something else, this line would not print.
+More specifically, if the expression after the `if` evaluates to `true`, then
+the block is executed. If it's `false`, then it is not.
+
+If you want something to happen in the `false` case, use an `else`:
+
+```
+let x = 5i;
+
+if x == 5i {
+    println!("x is five!");
+} else {
+    println!("x is not five :(");
+}
+```
+
+This is all pretty standard. However, you can also do this:
+
+
+```
+let x = 5i;
+
+let y = if x == 5i {
+    10i
+} else {
+    15i
+};
+```
+
+Which we can (and probably should) write like this:
+
+```
+let x = 5i;
+
+let y = if x == 5i { 10i } else { 15i };
+```
+
+This reveals two interesting things about Rust: it is an expression-based
+language, and semicolons are different than in other 'curly brace and
+semicolon'-based languages. These two things are related.
+
+### Expressions vs. Statements
+
+Rust is primarily an expression based language. There are only two kinds of
+statements, and everything else is an expression.
+
+So what's the difference? Expressions return a value, and statements do not.
+In many languages, `if` is a statement, and therefore, `let x = if ...` would
+make no sense. But in Rust, `if` is an expression, which means that it returns
+a value. We can then use this value to initialize the binding.
+
+Speaking of which, bindings are a kind of the first of Rust's two statements.
+The proper name is a **declaration statement**. So far, `let` is the only kind
+of declaration statement we've seen. Let's talk about that some more.
+
+In some languages, variable bindings can be written as expressions, not just
+statements. Like Ruby:
+
+```{ruby}
+x = y = 5
+```
+
+In Rust, however, using `let` to introduce a binding is _not_ an expression. The
+following will produce a compile-time error:
+
+```{ignore}
+let x = (let y = 5i); // found `let` in ident position
+```
+
+The compiler is telling us here that it was expecting to see the beginning of
+an expression, and a `let` can only begin a statement, not an expression.
+
+However, re-assigning to a mutable binding is an expression:
+
+```{rust}
+let mut x = 0i;
+let y = x = 5i;
+```
+
+In this case, we have an assignment expression (`x = 5`) whose value is
+being used as part of a `let` declaration statement (`let y = ...`).
+
+The second kind of statement in Rust is the **expression statement**. Its
+purpose is to turn any expression into a statement. In practical terms, Rust's
+grammar expects statements to follow other statements. This means that you use
+semicolons to separate expressions from each other. This means that Rust
+looks a lot like most other languages that require you to use semicolons
+at the end of every line, and you will see semicolons at the end of almost
+every line of Rust code you see.
+
+What is this exception that makes us say 'almost?' You saw it already, in this
+code:
+
+```
+let x = 5i;
+
+let y: int = if x == 5i { 10i } else { 15i };
+```
+
+Note that I've added the type annotation to `y`, to specify explicitly that I
+want `y` to be an integer.
+
+This is not the same as this, which won't compile:
+
+```{ignore}
+let x = 5i;
+
+let y: int = if x == 5 { 10i; } else { 15i; };
+```
+
+Note the semicolons after the 10 and 15. Rust will give us the following error:
+
+```{ignore,notrust}
+error: mismatched types: expected `int` but found `()` (expected int but found ())
+```
+
+We expected an integer, but we got `()`. `()` is pronounced 'unit', and is a
+special type in Rust's type system. `()` is different than `null` in other
+languages, because `()` is distinct from other types. For example, in C, `null`
+is a valid value for a variable of type `int`. In Rust, `()` is _not_ a valid
+value for a variable of type `int`. It's only a valid value for variables of
+the type `()`, which aren't very useful. Remember how we said statements don't
+return a value? Well, that's the purpose of unit in this case. The semicolon
+turns any expression into a statement by throwing away its value and returning
+unit instead.
+
+There's one more time in which you won't see a semicolon at the end of a line
+of Rust code. For that, we'll need our next concept: functions.
+
 ## Functions
 
+You've already seen one function so far, the `main` function:
+
+```{rust}
+fn main() {
+}
+```
+
+This is the simplest possible function declaration. As we mentioned before,
+`fn` says 'this is a function,' followed by the name, some parenthesis because
+this function takes no arguments, and then some curly braces to indicate the
+body. Here's a function named `foo`:
+
+```{rust}
+fn foo() {
+}
+```
+
+So, what about taking arguments? Here's a function that prints a number:
+
+```{rust}
+fn print_number(x: int) {
+    println!("x is: {}", x);
+}
+```
+
+Here's a complete program that uses `print_number`:
+
+```{rust}
+fn main() {
+    print_number(5);
+}
+
+fn print_number(x: int) {
+    println!("x is: {}", x);
+}
+```
+
+As you can see, function arguments work very similar to `let` declarations:
+you add a type to the argument name, after a colon.
+
+Here's a complete program that adds two numbers together and prints them:
+
+```{rust}
+fn main() {
+    print_sum(5, 6);
+}
+
+fn print_sum(x: int, y: int) {
+    println!("sum is: {}", x + y);
+}
+```
+
+You separate arguments with a comma, both when you call the function, as well
+as when you declare it.
+
+Unlike `let`, you _must_ declare the types of function arguments. This does
+not work:
+
+```{ignore}
+fn print_number(x, y) {
+    println!("x is: {}", x + y);
+}
+```
+
+You get this error:
+
+```{ignore,notrust}
+hello.rs:5:18: 5:19 error: expected `:` but found `,`
+hello.rs:5 fn print_number(x, y) {
+```
+
+This is a deliberate design decision. While full-program inference is possible,
+languages which have it, like Haskell, often suggest that documenting your
+types explicitly is a best-practice. We agree that forcing functions to declare
+types while allowing for inference inside of function bodies is a wonderful
+compromise between full inference and no inference.
+
+What about returning a value? Here's a function that adds one to an integer:
+
+```{rust}
+fn add_one(x: int) -> int {
+    x + 1
+}
+```
+
+Rust functions return exactly one value, and you declare the type after an
+'arrow', which is a dash (`-`) followed by a greater-than sign (`>`).
+
+You'll note the lack of a semicolon here. If we added it in:
+
+```{ignore}
+fn add_one(x: int) -> int {
+    x + 1;
+}
+```
+
+We would get an error:
+
+```{ignore,notrust}
+note: consider removing this semicolon:
+     x + 1;
+          ^
+error: not all control paths return a value
+fn add_one(x: int) -> int {
+     x + 1;
+}
+```
+
+Remember our earlier discussions about semicolons and `()`? Our function claims
+to return an `int`, but with a semicolon, it would return `()` instead. Rust
+realizes this probably isn't what we want, and suggests removing the semicolon.
+
+This is very much like our `if` statement before: the result of the block
+(`{}`) is the value of the expression. Other expression-oriented languages,
+such as Ruby, work like this, but it's a bit unusual in the systems programming
+world. When people first learn about this, they usually assume that it
+introduces bugs. But because Rust's type system is so strong, and because unit
+is its own unique type, we have never seen an issue where adding or removing a
+semicolon in a return position would cause a bug.
+
+But what about early returns? Rust does have a keyword for that, `return`:
+
+```{rust}
+fn foo(x: int) -> int {
+    if x < 5 { return x; }
+
+    x + 1
+}
+```
+
+Using a `return` as the last line of a function works, but is considered poor
+style:
+
+```{rust}
+fn foo(x: int) -> int {
+    if x < 5 { return x; }
+
+    return x + 1;
+}
+```
+
+There are some additional ways to define functions, but they involve features
+that we haven't learned about yet, so let's just leave it at that for now.
+
+## Comments
+
 return
 
 comments
index 5fe6a5f14c2b426d55d112a6083dbc0889ddab6e..2a788d7e7934c495d1d6ca218209faa3181c062c 100644 (file)
@@ -469,7 +469,7 @@ fn signum(x: int) -> int {
 
 Rust's `match` construct is a generalized, cleaned-up version of C's
 `switch` construct. You provide it with a value and a number of
-*arms*, each labelled with a pattern, and the code compares the value
+*arms*, each labeled with a pattern, and the code compares the value
 against each pattern in order until one matches. The matching pattern
 executes its corresponding arm.
 
@@ -2524,7 +2524,7 @@ of the components of types. By design, trait objects don't know the exact type
 of their contents and so the compiler cannot reason about those properties.
 
 You can instruct the compiler, however, that the contents of a trait object must
-acribe to a particular bound with a trailing colon (`:`). These are examples of
+ascribe to a particular bound with a trailing colon (`:`). These are examples of
 valid types:
 
 ~~~rust
@@ -2579,7 +2579,7 @@ This is a silly way to compute the radius of a circle
 
 In type-parameterized functions,
 methods of the supertrait may be called on values of subtrait-bound type parameters.
-Refering to the previous example of `trait Circle : Shape`:
+Referring to the previous example of `trait Circle : Shape`:
 
 ~~~
 # trait Shape { fn area(&self) -> f64; }
index fd4c20d73c5d1df40979ed95a3f691026caed0b3..2ed7a9dd6c28ab246cf857376ec3d33571f6631d 100644 (file)
@@ -214,7 +214,7 @@ need_cmd uname
 need_cmd tr
 need_cmd sed
 
-CFG_SRC_DIR="$(cd $(dirname $0) && pwd)/"
+CFG_SRC_DIR="$(cd $(dirname $0) && pwd)"
 CFG_SELF="$0"
 CFG_ARGS="$@"
 
index 38ed511c4589a5004a12b6510fff04bde660d845..9b4f879e61ea4a8474cc172002d31e021b4b6bd6 100644 (file)
@@ -185,7 +185,7 @@ fn drop(&mut self) {
         // deletion of the data. Because it is marked `Release`, the
         // decreasing of the reference count synchronizes with this `Acquire`
         // fence. This means that use of the data happens before decreasing
-        // the refernce count, which happens before this fence, which
+        // the reference count, which happens before this fence, which
         // happens before the deletion of the data.
         //
         // As explained in the [Boost documentation][1],
index fd8ce11d0b5a4bfdfc0256a830edff57445a8229..ddba4b34e3a2a4e8a5664f54b61d95e08ffeb943 100644 (file)
@@ -160,9 +160,27 @@ pub fn from_chars(chs: &[char]) -> String {
 /// Methods for vectors of strings
 pub trait StrVector {
     /// Concatenate a vector of strings.
+    ///
+    /// # Example
+    ///
+    /// ```rust
+    /// let first = "Restaurant at the End of the".to_string();
+    /// let second = " Universe".to_string();
+    /// let string_vec = vec![first, second];
+    /// assert_eq!(string_vec.concat(), "Restaurant at the End of the Universe".to_string());
+    /// ```
     fn concat(&self) -> String;
 
     /// Concatenate a vector of strings, placing a given separator between each.
+    ///
+    /// # Example
+    ///
+    /// ```rust
+    /// let first = "Roast".to_string();
+    /// let second = "Sirloin Steak".to_string();
+    /// let string_vec = vec![first, second];
+    /// assert_eq!(string_vec.connect(", "), "Roast, Sirloin Steak".to_string());
+    /// ```
     fn connect(&self, sep: &str) -> String;
 }
 
@@ -172,7 +190,7 @@ fn concat(&self) -> String {
             return String::new();
         }
 
-        // `len` calculation may overflow but push_str but will check boundaries
+        // `len` calculation may overflow but push_str will check boundaries
         let len = self.iter().map(|s| s.as_slice().len()).sum();
 
         let mut result = String::with_capacity(len);
index 2ffc168f82c0eef4b4d77244a873ed3cd327d1a6..d53ecabd5a9cb147e5093e7ce172dd91acf1835a 100644 (file)
@@ -253,8 +253,7 @@ pub fn push_all(&mut self, other: &[T]) {
     /// assert_eq!(vec, vec!("hello", "world", "world"));
     /// ```
     pub fn grow(&mut self, n: uint, value: &T) {
-        let new_len = self.len() + n;
-        self.reserve(new_len);
+        self.reserve_additional(n);
         let mut i: uint = 0u;
 
         while i < n {
@@ -497,7 +496,7 @@ pub fn reserve_additional(&mut self, extra: uint) {
     /// assert!(vec.capacity() >= 10);
     /// ```
     pub fn reserve(&mut self, capacity: uint) {
-        if capacity >= self.len {
+        if capacity > self.cap {
             self.reserve_exact(num::next_power_of_two(capacity))
         }
     }
index a5880f3247242eb0c5ffefe54a5dfdcd4e8a2aad..848509cbab27883f21b589bd8c91660c43a60e06 100644 (file)
@@ -59,7 +59,6 @@ fn main() {
 use syntax::ext::base;
 use syntax::ext::base::{ExtCtxt, MacExpr};
 use syntax::ext::build::AstBuilder;
-use syntax::parse;
 use syntax::parse::token;
 use syntax::parse::token::InternedString;
 use rustc::plugin::Registry;
@@ -135,11 +134,7 @@ struct Ident {
 
 fn parse_tts(cx: &ExtCtxt,
              tts: &[ast::TokenTree]) -> (Gc<ast::Expr>, Option<Ident>) {
-    let p = &mut parse::new_parser_from_tts(cx.parse_sess(),
-                                            cx.cfg(),
-                                            tts.iter()
-                                               .map(|x| (*x).clone())
-                                               .collect());
+    let p = &mut cx.new_parser_from_tts(tts);
     let ex = p.parse_expr();
     let id = if p.token == token::EOF {
         None
index c4885edb7d3a776f63cb3df282c6c65f6ed36a13..5faa9cfe6f6a2bd0cbbb0c7d80cf95754de2331f 100644 (file)
@@ -124,7 +124,7 @@ fn drop(&mut self) {
 }
 
 pub struct StackPool {
-    // Ideally this would be some datastructure that preserved ordering on
+    // Ideally this would be some data structure that preserved ordering on
     // Stack.min_size.
     stacks: Vec<Stack>,
 }
index 1b43f236e69b554b9ba877f98c393d1b617415f0..369de484e8e84059d11b9517e48dc5724c81da9b 100644 (file)
@@ -54,7 +54,6 @@ fn main() {
 use syntax::ext::base;
 use syntax::ext::base::{ExtCtxt, MacExpr};
 use syntax::ext::build::AstBuilder;
-use syntax::parse;
 use syntax::parse::token;
 use rustc::plugin::Registry;
 
@@ -167,11 +166,7 @@ struct Ident {
 
 fn parse_tts(cx: &ExtCtxt,
              tts: &[ast::TokenTree]) -> (Gc<ast::Expr>, Option<Ident>) {
-    let p = &mut parse::new_parser_from_tts(cx.parse_sess(),
-                                            cx.cfg(),
-                                            tts.iter()
-                                               .map(|x| (*x).clone())
-                                               .collect());
+    let p = &mut cx.new_parser_from_tts(tts);
     let ex = p.parse_expr();
     let id = if p.token == token::EOF {
         None
index ba102a85c1bcb16b6cd3d533274372ba01201302..17349f41b98f74889a1df242ddc81ea041e37b90 100644 (file)
@@ -288,7 +288,7 @@ pub fn mod_enabled(level: u32, module: &str) -> bool {
     unsafe { INIT.doit(init); }
 
     // It's possible for many threads are in this function, only one of them
-    // will peform the global initialization, but all of them will need to check
+    // will perform the global initialization, but all of them will need to check
     // again to whether they should really be here or not. Hence, despite this
     // check being expanded manually in the logging macro, this function checks
     // the log level again.
index dfc2c55cde7cb511bb79303ed6942d7b69f1572f..f052826d303861f8b24b60d3f83380ef839c91d6 100644 (file)
@@ -877,7 +877,7 @@ pub fn write<T>(fd: sock_t,
             }
 
             // Also as with read(), we use MSG_DONTWAIT to guard ourselves
-            // against unforseen circumstances.
+            // against unforeseen circumstances.
             let _guard = lock();
             let ptr = buf.slice_from(written).as_ptr();
             let len = buf.len() - written;
index da713e3f2a931e9394a02f90b5bd3061175d2601..e5e8cdeffd7e4c2249b44d5a7f1db0fa2fee47f7 100644 (file)
@@ -376,7 +376,7 @@ fn read(&mut self, buf: &mut [u8]) -> IoResult<uint> {
         if ret != 0 { return Ok(bytes_read as uint) }
 
         // If our errno doesn't say that the I/O is pending, then we hit some
-        // legitimate error and reeturn immediately.
+        // legitimate error and return immediately.
         if os::errno() != libc::ERROR_IO_PENDING as uint {
             return Err(super::last_error())
         }
index ff5cada05ea2e18adbc63282cbbdf86d075d5567..4108388e7766979df1df4e8a06e095d89d31e771 100644 (file)
@@ -32,7 +32,6 @@
 use syntax::codemap;
 use syntax::ext::build::AstBuilder;
 use syntax::ext::base::{ExtCtxt, MacResult, MacExpr, DummyResult};
-use syntax::parse;
 use syntax::parse::token;
 use syntax::print::pprust;
 
@@ -615,8 +614,7 @@ fn vec_expr<T, It: Iterator<T>>(&self, xs: It,
 /// Looks for a single string literal and returns it.
 /// Otherwise, logs an error with cx.span_err and returns None.
 fn parse(cx: &mut ExtCtxt, tts: &[ast::TokenTree]) -> Option<String> {
-    let mut parser = parse::new_parser_from_tts(cx.parse_sess(), cx.cfg(),
-                                                Vec::from_slice(tts));
+    let mut parser = cx.new_parser_from_tts(tts);
     let entry = cx.expand_expr(parser.parse_expr());
     let regex = match entry.node {
         ast::ExprLit(lit) => {
index c85e0099ab832f9012f59c4ece785ac7298e43e4..4423ab62f0dcfc83c851edcf86102a0f924298b3 100644 (file)
@@ -31,7 +31,7 @@
 #![no_std]
 #![experimental]
 
-// This library is definining the builtin functions, so it would be a shame for
+// This library defines the builtin functions, so it would be a shame for
 // LLVM to optimize these function calls to themselves!
 #![no_builtins]
 
index 17f29639601dd72455e0e7e38202970df8f3a298..a190d9309cc8df8612f6fbe85f5a8b76173be14f 100644 (file)
@@ -119,7 +119,7 @@ pub mod write {
     // get all hardware potential via VFP3 (hardware floating point)
     // and NEON (SIMD) instructions supported by LLVM.
     // Note that without those flags various linking errors might
-    // arise as some of intrinsicts are converted into function calls
+    // arise as some of intrinsics are converted into function calls
     // and nobody provides implementations those functions
     fn target_feature<'a>(sess: &'a Session) -> &'a str {
         match sess.targ_cfg.os {
index 30296cb318617af1fdc0a544374596a44e5a37c8..a8f778934ae47e21c28b9b3c016d5326598bd1ea 100644 (file)
@@ -902,12 +902,10 @@ fn get_lints(&self) -> LintArray {
     fn check_pat(&mut self, cx: &Context, p: &ast::Pat) {
         // Lint for constants that look like binding identifiers (#7526)
         match (&p.node, cx.tcx.def_map.borrow().find(&p.id)) {
-            (&ast::PatIdent(_, ref path, _), Some(&def::DefStatic(_, false))) => {
-                // last identifier alone is right choice for this lint.
-                let ident = path.segments.last().unwrap().identifier;
-                let s = token::get_ident(ident);
+            (&ast::PatIdent(_, ref path1, _), Some(&def::DefStatic(_, false))) => {
+                let s = token::get_ident(path1.node);
                 if s.get().chars().any(|c| c.is_lowercase()) {
-                    cx.span_lint(NON_UPPERCASE_PATTERN_STATICS, path.span,
+                    cx.span_lint(NON_UPPERCASE_PATTERN_STATICS, path1.span,
                         format!("static constant in pattern `{}` should have an uppercase \
                                  name such as `{}`",
                                 s.get(), s.get().chars().map(|c| c.to_uppercase())
@@ -931,15 +929,13 @@ fn get_lints(&self) -> LintArray {
 
     fn check_pat(&mut self, cx: &Context, p: &ast::Pat) {
         match &p.node {
-            &ast::PatIdent(_, ref path, _) => {
+            &ast::PatIdent(_, ref path1, _) => {
                 match cx.tcx.def_map.borrow().find(&p.id) {
                     Some(&def::DefLocal(_, _)) | Some(&def::DefBinding(_, _)) |
                             Some(&def::DefArg(_, _)) => {
-                        // last identifier alone is right choice for this lint.
-                        let ident = path.segments.last().unwrap().identifier;
-                        let s = token::get_ident(ident);
+                        let s = token::get_ident(path1.node);
                         if s.get().len() > 0 && s.get().char_at(0).is_uppercase() {
-                            cx.span_lint(UPPERCASE_VARIABLES, path.span,
+                            cx.span_lint(UPPERCASE_VARIABLES, path1.span,
                                          "variable names should start with \
                                           a lowercase character");
                         }
@@ -989,7 +985,7 @@ fn check_unnecessary_parens_core(&self, cx: &Context, value: &ast::Expr, msg: &s
             _ => {}
         }
 
-        /// Expressions that syntatically contain an "exterior" struct
+        /// Expressions that syntactically contain an "exterior" struct
         /// literal i.e. not surrounded by any parens or other
         /// delimiters, e.g. `X { y: 1 }`, `X { y: 1 }.method()`, `foo
         /// == X { y: 1 }` and `X { y: 1 } == foo` all do, but `(X {
@@ -1113,15 +1109,10 @@ fn check_unused_mut_pat(&self, cx: &Context, pats: &[Gc<ast::Pat>]) {
         // avoid false warnings in match arms with multiple patterns
         let mut mutables = HashMap::new();
         for &p in pats.iter() {
-            pat_util::pat_bindings(&cx.tcx.def_map, &*p, |mode, id, _, path| {
+            pat_util::pat_bindings(&cx.tcx.def_map, &*p, |mode, id, _, path1| {
+                let ident = path1.node;
                 match mode {
                     ast::BindByValue(ast::MutMutable) => {
-                        if path.segments.len() != 1 {
-                            cx.sess().span_bug(p.span,
-                                               "mutable binding that doesn't consist \
-                                                of exactly one segment");
-                        }
-                        let ident = path.segments.get(0).identifier;
                         if !token::get_ident(ident).get().starts_with("_") {
                             mutables.insert_or_update_with(ident.name as uint,
                                 vec!(id), |_, old| { old.push(id); });
index 96284f8de261a78254f0faa3ff837c660049cf2b..6eb7c5a4310e6f9cb61abc55001000ae275839cc 100644 (file)
@@ -809,9 +809,8 @@ fn encode_method_argument_names(ebml_w: &mut Encoder,
     for arg in decl.inputs.iter() {
         ebml_w.start_tag(tag_method_argument_name);
         match arg.pat.node {
-            ast::PatIdent(_, ref name, _) => {
-                let name = name.segments.last().unwrap().identifier;
-                let name = token::get_ident(name);
+            ast::PatIdent(_, ref path1, _) => {
+                let name = token::get_ident(path1.node);
                 ebml_w.writer.write(name.get().as_bytes());
             }
             _ => {}
@@ -1106,8 +1105,9 @@ fn add_to_index(item: &Item, ebml_w: &Encoder,
         match ty.node {
             ast::TyPath(ref path, ref bounds, _) if path.segments
                                                         .len() == 1 => {
+                let ident = path.segments.last().unwrap().identifier;
                 assert!(bounds.is_none());
-                encode_impl_type_basename(ebml_w, ast_util::path_to_ident(path));
+                encode_impl_type_basename(ebml_w, ident);
             }
             _ => {}
         }
index 6df474809779ac37cd62eebe2b80a6c86f002b7b..de77fa602c9b406a0bf85a4e8c58b04bb72b7975 100644 (file)
@@ -66,9 +66,9 @@ pub fn gather_move_from_pat(bccx: &BorrowckCtxt,
                             move_pat: &ast::Pat,
                             cmt: mc::cmt) {
     let pat_span_path_opt = match move_pat.node {
-        ast::PatIdent(_, ref path, _) => {
-            Some(MoveSpanAndPath::with_span_and_path(move_pat.span,
-                                                     (*path).clone()))
+        ast::PatIdent(_, ref path1, _) => {
+            Some(MoveSpanAndPath{span: move_pat.span,
+                                 ident: path1.node})
         },
         _ => None,
     };
index 925244849bc8ab408f340242155d4c9f3812a742..f5c91f7b1b3bf4441e664ff0fd479486864b6d22 100644 (file)
@@ -56,19 +56,8 @@ pub fn with_move_info(move_from: mc::cmt,
 
 #[deriving(Clone)]
 pub struct MoveSpanAndPath {
-    span: codemap::Span,
-    path: ast::Path
-}
-
-impl MoveSpanAndPath {
-    pub fn with_span_and_path(span: codemap::Span,
-                              path: ast::Path)
-                              -> MoveSpanAndPath {
-        MoveSpanAndPath {
-            span: span,
-            path: path,
-        }
-    }
+    pub span: codemap::Span,
+    pub ident: ast::Ident
 }
 
 pub struct GroupedMoveErrors {
@@ -83,7 +72,7 @@ fn report_move_errors(bccx: &BorrowckCtxt, errors: &Vec<MoveError>) {
         let mut is_first_note = true;
         for move_to in error.move_to_places.iter() {
             note_move_destination(bccx, move_to.span,
-                                  &move_to.path, is_first_note);
+                                  &move_to.ident, is_first_note);
             is_first_note = false;
         }
     }
@@ -154,9 +143,9 @@ fn report_cannot_move_out_of(bccx: &BorrowckCtxt, move_from: mc::cmt) {
 
 fn note_move_destination(bccx: &BorrowckCtxt,
                          move_to_span: codemap::Span,
-                         pat_ident_path: &ast::Path,
+                         pat_ident: &ast::Ident,
                          is_first_note: bool) {
-    let pat_name = pprust::path_to_str(pat_ident_path);
+    let pat_name = pprust::ident_to_str(pat_ident);
     if is_first_note {
         bccx.span_note(
             move_to_span,
index e7457f370d9adea16253276cb4fa5bc0b9224758..70db3e964abb3273cc2f4d078a3c809b1c7fdad0 100644 (file)
@@ -247,6 +247,10 @@ fn visit_pat(&mut self, pat: &ast::Pat, ctxt: MarkSymbolVisitorContext) {
             ast::PatStruct(_, ref fields, _) => {
                 self.handle_field_pattern_match(pat, fields.as_slice());
             }
+            ast::PatIdent(_, _, _) => {
+                // it might be the only use of a static:
+                self.lookup_and_handle_definition(&pat.id)
+            }
             _ => ()
         }
 
index 34754f045ffce8b00ecc1d677d3c2df6b6d536b5..a7154e78bc58612d7243430bd2aa3a106be75ac1 100644 (file)
@@ -13,6 +13,7 @@
 use middle::freevars;
 use middle::subst;
 use middle::ty;
+use middle::typeck::{MethodCall, NoAdjustment};
 use middle::typeck;
 use util::ppaux::{Repr, ty_to_str};
 use util::ppaux::UserString;
@@ -20,7 +21,7 @@
 use syntax::ast::*;
 use syntax::attr;
 use syntax::codemap::Span;
-use syntax::print::pprust::{expr_to_str,path_to_str};
+use syntax::print::pprust::{expr_to_str, ident_to_str};
 use syntax::{visit};
 use syntax::visit::Visitor;
 
@@ -261,7 +262,15 @@ pub fn check_expr(cx: &mut Context, e: &Expr) {
         ExprCast(ref source, _) => {
             let source_ty = ty::expr_ty(cx.tcx, &**source);
             let target_ty = ty::expr_ty(cx.tcx, e);
-            check_trait_cast(cx, source_ty, target_ty, source.span);
+            let method_call = MethodCall {
+                expr_id: e.id,
+                adjustment: NoAdjustment,
+            };
+            check_trait_cast(cx,
+                             source_ty,
+                             target_ty,
+                             source.span,
+                             method_call);
         }
         ExprRepeat(ref element, ref count_expr) => {
             let count = ty::eval_repeat_count(cx.tcx, &**count_expr);
@@ -281,7 +290,15 @@ pub fn check_expr(cx: &mut Context, e: &Expr) {
                 ty::AutoObject(..) => {
                     let source_ty = ty::expr_ty(cx.tcx, e);
                     let target_ty = ty::expr_ty_adjusted(cx.tcx, e);
-                    check_trait_cast(cx, source_ty, target_ty, e.span);
+                    let method_call = MethodCall {
+                        expr_id: e.id,
+                        adjustment: typeck::AutoObject,
+                    };
+                    check_trait_cast(cx,
+                                     source_ty,
+                                     target_ty,
+                                     e.span,
+                                     method_call);
                 }
                 ty::AutoAddEnv(..) |
                 ty::AutoDerefRef(..) => {}
@@ -364,15 +381,62 @@ fn check_bounds_on_type_parameters(cx: &mut Context, e: &Expr) {
     }
 }
 
-fn check_trait_cast(cx: &mut Context, source_ty: ty::t, target_ty: ty::t, span: Span) {
+fn check_type_parameter_bounds_in_vtable_result(
+        cx: &mut Context,
+        span: Span,
+        vtable_res: &typeck::vtable_res) {
+    for origins in vtable_res.iter() {
+        for origin in origins.iter() {
+            let (type_param_defs, substs) = match *origin {
+                typeck::vtable_static(def_id, ref tys, _) => {
+                    let type_param_defs =
+                        ty::lookup_item_type(cx.tcx, def_id).generics
+                                                            .types
+                                                            .clone();
+                    (type_param_defs, (*tys).clone())
+                }
+                _ => {
+                    // Nothing to do here.
+                    continue
+                }
+            };
+            for type_param_def in type_param_defs.iter() {
+                let typ = substs.types.get(type_param_def.space,
+                                           type_param_def.index);
+                check_typaram_bounds(cx, span, *typ, type_param_def)
+            }
+        }
+    }
+}
+
+fn check_trait_cast(cx: &mut Context,
+                    source_ty: ty::t,
+                    target_ty: ty::t,
+                    span: Span,
+                    method_call: MethodCall) {
     check_cast_for_escaping_regions(cx, source_ty, target_ty, span);
     match ty::get(target_ty).sty {
-        ty::ty_uniq(ty) | ty::ty_rptr(_, ty::mt{ ty, .. }) => match ty::get(ty).sty {
-            ty::ty_trait(box ty::TyTrait { bounds, .. }) => {
-                check_trait_cast_bounds(cx, span, source_ty, bounds);
+        ty::ty_uniq(ty) | ty::ty_rptr(_, ty::mt{ ty, .. }) => {
+            match ty::get(ty).sty {
+                ty::ty_trait(box ty::TyTrait { bounds, .. }) => {
+                     match cx.tcx.vtable_map.borrow().find(&method_call) {
+                        None => {
+                            cx.tcx.sess.span_bug(span,
+                                                 "trait cast not in vtable \
+                                                  map?!")
+                        }
+                        Some(vtable_res) => {
+                            check_type_parameter_bounds_in_vtable_result(
+                                cx,
+                                span,
+                                vtable_res)
+                        }
+                    };
+                    check_trait_cast_bounds(cx, span, source_ty, bounds);
+                }
+                _ => {}
             }
-            _ => {}
-        },
+        }
         _ => {}
     }
 }
@@ -627,7 +691,7 @@ fn check_sized(tcx: &ty::ctxt, ty: ty::t, name: String, sp: Span) {
 fn check_pat(cx: &mut Context, pat: &Pat) {
     let var_name = match pat.node {
         PatWild => Some("_".to_string()),
-        PatIdent(_, ref path, _) => Some(path_to_str(path).to_string()),
+        PatIdent(_, ref path1, _) => Some(ident_to_str(&path1.node).to_string()),
         _ => None
     };
 
index 5c09466cd96820bdfb686760caf70ba973302ba7..d48f7f541f0da016d1c85cfe980a529656c89031 100644 (file)
@@ -367,9 +367,9 @@ fn visit_fn(ir: &mut IrMaps,
     for arg in decl.inputs.iter() {
         pat_util::pat_bindings(&ir.tcx.def_map,
                                &*arg.pat,
-                               |_bm, arg_id, _x, path| {
+                               |_bm, arg_id, _x, path1| {
             debug!("adding argument {}", arg_id);
-            let ident = ast_util::path_to_ident(path);
+            let ident = path1.node;
             fn_maps.add_variable(Arg(arg_id, ident));
         })
     };
@@ -399,9 +399,9 @@ fn visit_fn(ir: &mut IrMaps,
 }
 
 fn visit_local(ir: &mut IrMaps, local: &Local) {
-    pat_util::pat_bindings(&ir.tcx.def_map, &*local.pat, |_, p_id, sp, path| {
+    pat_util::pat_bindings(&ir.tcx.def_map, &*local.pat, |_, p_id, sp, path1| {
         debug!("adding local variable {}", p_id);
-        let name = ast_util::path_to_ident(path);
+        let name = path1.node;
         ir.add_live_node_for_node(p_id, VarDefNode(sp));
         ir.add_variable(Local(LocalInfo {
           id: p_id,
@@ -413,10 +413,10 @@ fn visit_local(ir: &mut IrMaps, local: &Local) {
 
 fn visit_arm(ir: &mut IrMaps, arm: &Arm) {
     for pat in arm.pats.iter() {
-        pat_util::pat_bindings(&ir.tcx.def_map, &**pat, |bm, p_id, sp, path| {
+        pat_util::pat_bindings(&ir.tcx.def_map, &**pat, |bm, p_id, sp, path1| {
             debug!("adding local variable {} from match with bm {:?}",
                    p_id, bm);
-            let name = ast_util::path_to_ident(path);
+            let name = path1.node;
             ir.add_live_node_for_node(p_id, VarDefNode(sp));
             ir.add_variable(Local(LocalInfo {
                 id: p_id,
@@ -1522,10 +1522,10 @@ fn warn_about_unused_args(&self, decl: &FnDecl, entry_ln: LiveNode) {
         for arg in decl.inputs.iter() {
             pat_util::pat_bindings(&self.ir.tcx.def_map,
                                    &*arg.pat,
-                                   |_bm, p_id, sp, path| {
+                                   |_bm, p_id, sp, path1| {
                 let var = self.variable(p_id, sp);
                 // Ignore unused self.
-                let ident = ast_util::path_to_ident(path);
+                let ident = path1.node;
                 if ident.name != special_idents::self_.name {
                     self.warn_about_unused(sp, p_id, entry_ln, var);
                 }
index e1a2a5741fbe1b0d0e03ba62c41dd7666e647f6e..54cca082e0de86950a10f7c26aeb8672369b6ae4 100644 (file)
@@ -383,7 +383,7 @@ pub fn cat_expr(&self, expr: &ast::Expr) -> McResult<cmt> {
             Some(adjustment) => {
                 match *adjustment {
                     ty::AutoObject(..) => {
-                        // Implicity cast a concrete object to trait object.
+                        // Implicitly cast a concrete object to trait object.
                         // Result is an rvalue.
                         let expr_ty = if_ok!(self.expr_ty_adjusted(expr));
                         Ok(self.cat_rvalue_node(expr.id(), expr.span(), expr_ty))
index 24d97f5aac354212171f61b1110cae7506c0fb96..2d53d742ee44b15800ed580c6f375f65b1e87a24 100644 (file)
@@ -14,7 +14,7 @@
 use std::collections::HashMap;
 use std::gc::{Gc, GC};
 use syntax::ast::*;
-use syntax::ast_util::{path_to_ident, walk_pat};
+use syntax::ast_util::{walk_pat};
 use syntax::codemap::{Span, DUMMY_SP};
 
 pub type PatIdMap = HashMap<Ident, NodeId>;
@@ -23,8 +23,8 @@
 // use the NodeId of their namesake in the first pattern.
 pub fn pat_id_map(dm: &resolve::DefMap, pat: &Pat) -> PatIdMap {
     let mut map = HashMap::new();
-    pat_bindings(dm, pat, |_bm, p_id, _s, n| {
-      map.insert(path_to_ident(n), p_id);
+    pat_bindings(dm, pat, |_bm, p_id, _s, path1| {
+      map.insert(path1.node, p_id);
     });
     map
 }
@@ -75,7 +75,7 @@ pub fn pat_is_binding_or_wild(dm: &resolve::DefMap, pat: &Pat) -> bool {
 /// `match foo() { Some(a) => (), None => () }`
 pub fn pat_bindings(dm: &resolve::DefMap,
                     pat: &Pat,
-                    it: |BindingMode, NodeId, Span, &Path|) {
+                    it: |BindingMode, NodeId, Span, &SpannedIdent|) {
     walk_pat(pat, |p| {
         match p.node {
           PatIdent(binding_mode, ref pth, _) if pat_is_binding(dm, p) => {
@@ -102,10 +102,10 @@ pub fn pat_contains_bindings(dm: &resolve::DefMap, pat: &Pat) -> bool {
     contains_bindings
 }
 
-pub fn simple_identifier<'a>(pat: &'a Pat) -> Option<&'a Path> {
+pub fn simple_identifier<'a>(pat: &'a Pat) -> Option<&'a Ident> {
     match pat.node {
-        PatIdent(BindByValue(_), ref path, None) => {
-            Some(path)
+        PatIdent(BindByValue(_), ref path1, None) => {
+            Some(&path1.node)
         }
         _ => {
             None
index 414aac47cdcc0882719525d04160e9e6bf1fabc3..76e962a3bc4da6a1894def5f64c29b5c0b374072 100644 (file)
@@ -1267,7 +1267,7 @@ fn visit_item(&mut self, item: &ast::Item, _: ()) {
             // error messages without (too many) false positives
             // (i.e. we could just return here to not check them at
             // all, or some worse estimation of whether an impl is
-            // publically visible.
+            // publicly visible.
             ast::ItemImpl(ref g, ref trait_ref, self_, ref methods) => {
                 // `impl [... for] Private` is never visible.
                 let self_contains_private;
index d42befc65421b36bb184bb7f1a3053b1f986eb86..b7b4618a7904619a97f34eacd6d26a0efe1a2b0f 100644 (file)
 use syntax::ast::*;
 use syntax::ast;
 use syntax::ast_util::{local_def};
-use syntax::ast_util::{path_to_ident, walk_pat, trait_method_to_ty_method};
+use syntax::ast_util::{walk_pat, trait_method_to_ty_method};
 use syntax::ext::mtwt;
 use syntax::parse::token::special_idents;
 use syntax::parse::token;
-use syntax::print::pprust::path_to_str;
 use syntax::codemap::{Span, DUMMY_SP, Pos};
 use syntax::owned_slice::OwnedSlice;
 use syntax::visit;
@@ -1247,7 +1246,7 @@ fn build_reduced_graph_for_item(&mut self,
                 // Create the module and add all methods.
                 match ty.node {
                     TyPath(ref path, _, _) if path.segments.len() == 1 => {
-                        let name = path_to_ident(path);
+                        let name = path.segments.last().unwrap().identifier;
 
                         let parent_opt = parent.module().children.borrow()
                                                .find_copy(&name.name);
@@ -4104,8 +4103,8 @@ fn resolve_local(&mut self, local: &Local) {
     // user and one 'x' came from the macro.
     fn binding_mode_map(&mut self, pat: &Pat) -> BindingMap {
         let mut result = HashMap::new();
-        pat_bindings(&self.def_map, pat, |binding_mode, _id, sp, path| {
-            let name = mtwt::resolve(path_to_ident(path));
+        pat_bindings(&self.def_map, pat, |binding_mode, _id, sp, path1| {
+            let name = mtwt::resolve(path1.node);
             result.insert(name,
                           binding_info {span: sp,
                                         binding_mode: binding_mode});
@@ -4314,8 +4313,7 @@ fn resolve_pattern(&mut self,
         let pat_id = pattern.id;
         walk_pat(pattern, |pattern| {
             match pattern.node {
-                PatIdent(binding_mode, ref path, _)
-                        if !path.global && path.segments.len() == 1 => {
+                PatIdent(binding_mode, ref path1, _) => {
 
                     // The meaning of pat_ident with no type parameters
                     // depends on whether an enum variant or unit-like struct
@@ -4326,7 +4324,7 @@ fn resolve_pattern(&mut self,
                     // such a value is simply disallowed (since it's rarely
                     // what you want).
 
-                    let ident = path.segments.get(0).identifier;
+                    let ident = path1.node;
                     let renamed = mtwt::resolve(ident);
 
                     match self.resolve_bare_identifier_pattern(ident) {
@@ -4416,57 +4414,12 @@ struct or enum variant",
                                     format!("identifier `{}` is bound \
                                              more than once in the same \
                                              pattern",
-                                            path_to_str(path)).as_slice());
+                                            token::get_ident(ident)).as_slice());
                             }
                             // Else, not bound in the same pattern: do
                             // nothing.
                         }
                     }
-
-                    // Check the types in the path pattern.
-                    for ty in path.segments
-                                  .iter()
-                                  .flat_map(|seg| seg.types.iter()) {
-                        self.resolve_type(&**ty);
-                    }
-                }
-
-                PatIdent(binding_mode, ref path, _) => {
-                    // This must be an enum variant, struct, or constant.
-                    match self.resolve_path(pat_id, path, ValueNS, false) {
-                        Some(def @ (DefVariant(..), _)) |
-                        Some(def @ (DefStruct(..), _)) => {
-                            self.record_def(pattern.id, def);
-                        }
-                        Some(def @ (DefStatic(..), _)) => {
-                            self.enforce_default_binding_mode(
-                                pattern,
-                                binding_mode,
-                                "a constant");
-                            self.record_def(pattern.id, def);
-                        }
-                        Some(_) => {
-                            self.resolve_error(
-                                path.span,
-                                format!("`{}` is not an enum variant or constant",
-                                        token::get_ident(
-                                            path.segments
-                                                .last()
-                                                .unwrap()
-                                                .identifier)).as_slice())
-                        }
-                        None => {
-                            self.resolve_error(path.span,
-                                                  "unresolved enum variant");
-                        }
-                    }
-
-                    // Check the types in the path pattern.
-                    for ty in path.segments
-                                  .iter()
-                                  .flat_map(|s| s.types.iter()) {
-                        self.resolve_type(&**ty);
-                    }
                 }
 
                 PatEnum(ref path, _) => {
@@ -5202,8 +5155,8 @@ fn resolve_expr(&mut self, expr: &Expr) {
                                              in a static method. Maybe a \
                                              `self` argument is missing?");
                                 } else {
-                                    let name = path_to_ident(path).name;
-                                    let mut msg = match self.find_fallback_in_self_type(name) {
+                                    let last_name = path.segments.last().unwrap().identifier.name;
+                                    let mut msg = match self.find_fallback_in_self_type(last_name) {
                                         NoSuggestion => {
                                             // limit search to 5 to reduce the number
                                             // of stupid suggestions
index 2b2f3b8fb0b5fd085ba00cdc24736f1bde36644d..bdb7d30339d66f010f0ba8e170dffe17dcaafe4b 100644 (file)
@@ -484,7 +484,7 @@ fn process_static(&mut self,
     {
         let qualname = self.analysis.ty_cx.map.path_to_str(item.id);
 
-        // If the variable is immutable, save the initialising expresion.
+        // If the variable is immutable, save the initialising expression.
         let value = match mt {
             ast::MutMutable => String::from_str("<mutable>"),
             ast::MutImmutable => self.span.snippet(expr.span),
@@ -845,7 +845,7 @@ fn process_method_call(&mut self,
                 let decl_id = ty::trait_method_of_method(&self.analysis.ty_cx, def_id);
 
                 // This incantation is required if the method referenced is a trait's
-                // defailt implementation.
+                // default implementation.
                 let def_id = ty::method(&self.analysis.ty_cx, def_id).provided_source
                                     .unwrap_or(def_id);
                 (Some(def_id), decl_id)
@@ -926,7 +926,7 @@ fn process_pat(&mut self, p:&ast::Pat, e: DxrVisitorEnv) {
                 self.collected_paths.push((p.id, path.clone(), false, recorder::VarRef));
                 visit::walk_pat(self, p, e);
             }
-            ast::PatIdent(bm, ref path, ref optional_subpattern) => {
+            ast::PatIdent(bm, ref path1, ref optional_subpattern) => {
                 let immut = match bm {
                     // Even if the ref is mut, you can't change the ref, only
                     // the data pointed at, so showing the initialising expression
@@ -940,7 +940,8 @@ fn process_pat(&mut self, p:&ast::Pat, e: DxrVisitorEnv) {
                     }
                 };
                 // collect path for either visit_local or visit_arm
-                self.collected_paths.push((p.id, path.clone(), immut, recorder::VarRef));
+                let path = ast_util::ident_to_path(path1.span,path1.node);
+                self.collected_paths.push((p.id, path, immut, recorder::VarRef));
                 match *optional_subpattern {
                     None => {}
                     Some(subpattern) => self.visit_pat(&*subpattern, e),
@@ -1402,7 +1403,7 @@ pub fn process_crate(sess: &Session,
         info!("Writing output to {}", disp);
     }
 
-    // Create ouput file.
+    // Create output file.
     let mut out_name = cratename.clone();
     out_name.push_str(".csv");
     root_path.push(out_name);
index 310d0f19c329a391d88b7ec242f60021fd3daecb..655973c3d33d4a55f2f20f355c0d4e87416a49c0 100644 (file)
 use std::gc::{Gc};
 use syntax::ast;
 use syntax::ast::Ident;
-use syntax::ast_util::path_to_ident;
-use syntax::ast_util;
 use syntax::codemap::Span;
 use syntax::parse::token::InternedString;
 
@@ -429,13 +427,13 @@ fn expand_nested_bindings<'a, 'b>(
 
     m.iter().map(|br| {
         match br.pats.get(col).node {
-            ast::PatIdent(_, ref path, Some(inner)) => {
+            ast::PatIdent(_, ref path1, Some(inner)) => {
                 let pats = Vec::from_slice(br.pats.slice(0u, col))
                            .append((vec!(inner))
                                    .append(br.pats.slice(col + 1u, br.pats.len())).as_slice());
 
                 let mut bound_ptrs = br.bound_ptrs.clone();
-                bound_ptrs.push((path_to_ident(path), val));
+                bound_ptrs.push((path1.node, val));
                 Match {
                     pats: pats,
                     data: &*br.data,
@@ -473,9 +471,9 @@ fn enter_match<'a, 'b>(
             let this = *br.pats.get(col);
             let mut bound_ptrs = br.bound_ptrs.clone();
             match this.node {
-                ast::PatIdent(_, ref path, None) => {
+                ast::PatIdent(_, ref path1, None) => {
                     if pat_is_binding(dm, &*this) {
-                        bound_ptrs.push((path_to_ident(path), val));
+                        bound_ptrs.push((path1.node, val));
                     }
                 }
                 _ => {}
@@ -1366,8 +1364,8 @@ fn create_bindings_map(bcx: &Block, pat: Gc<ast::Pat>) -> BindingsMap {
     let ccx = bcx.ccx();
     let tcx = bcx.tcx();
     let mut bindings_map = HashMap::new();
-    pat_bindings(&tcx.def_map, &*pat, |bm, p_id, span, path| {
-        let ident = path_to_ident(path);
+    pat_bindings(&tcx.def_map, &*pat, |bm, p_id, span, path1| {
+        let ident = path1.node;
         let variable_ty = node_id_type(bcx, p_id);
         let llvariable_ty = type_of::type_of(ccx, variable_ty);
         let tcx = bcx.tcx();
@@ -1520,10 +1518,10 @@ pub fn store_local<'a>(bcx: &'a Block<'a>,
             // In such cases, the more general path is unsafe, because
             // it assumes it is matching against a valid value.
             match simple_identifier(&*pat) {
-                Some(path) => {
+                Some(ident) => {
                     let var_scope = cleanup::var_scope(tcx, local.id);
                     return mk_binding_alloca(
-                        bcx, pat.id, path, BindLocal, var_scope, (),
+                        bcx, pat.id, ident, BindLocal, var_scope, (),
                         |(), bcx, v, _| expr::trans_into(bcx, &*init_expr,
                                                          expr::SaveIn(v)));
                 }
@@ -1555,10 +1553,10 @@ fn create_dummy_locals<'a>(mut bcx: &'a Block<'a>,
         // create dummy memory for the variables if we have no
         // value to store into them immediately
         let tcx = bcx.tcx();
-        pat_bindings(&tcx.def_map, &*pat, |_, p_id, _, path| {
+        pat_bindings(&tcx.def_map, &*pat, |_, p_id, _, path1| {
                 let scope = cleanup::var_scope(tcx, p_id);
                 bcx = mk_binding_alloca(
-                    bcx, p_id, path, BindLocal, scope, (),
+                    bcx, p_id, &path1.node, BindLocal, scope, (),
                     |(), bcx, llval, ty| { zero_mem(bcx, llval, ty); bcx });
             });
         bcx
@@ -1586,7 +1584,7 @@ pub fn store_arg<'a>(mut bcx: &'a Block<'a>,
     let _icx = push_ctxt("match::store_arg");
 
     match simple_identifier(&*pat) {
-        Some(path) => {
+        Some(ident) => {
             // Generate nicer LLVM for the common case of fn a pattern
             // like `x: T`
             let arg_ty = node_id_type(bcx, pat.id);
@@ -1601,7 +1599,7 @@ pub fn store_arg<'a>(mut bcx: &'a Block<'a>,
                 bcx
             } else {
                 mk_binding_alloca(
-                    bcx, pat.id, path, BindArgument, arg_scope, arg,
+                    bcx, pat.id, ident, BindArgument, arg_scope, arg,
                     |arg, bcx, llval, _| arg.store_to(bcx, llval))
             }
         }
@@ -1619,17 +1617,16 @@ pub fn store_arg<'a>(mut bcx: &'a Block<'a>,
 
 fn mk_binding_alloca<'a,A>(bcx: &'a Block<'a>,
                            p_id: ast::NodeId,
-                           path: &ast::Path,
+                           ident: &ast::Ident,
                            binding_mode: IrrefutablePatternBindingMode,
                            cleanup_scope: cleanup::ScopeId,
                            arg: A,
                            populate: |A, &'a Block<'a>, ValueRef, ty::t| -> &'a Block<'a>)
                          -> &'a Block<'a> {
     let var_ty = node_id_type(bcx, p_id);
-    let ident = ast_util::path_to_ident(path);
 
     // Allocate memory on stack for the binding.
-    let llval = alloc_ty(bcx, var_ty, bcx.ident(ident).as_slice());
+    let llval = alloc_ty(bcx, var_ty, bcx.ident(*ident).as_slice());
 
     // Subtle: be sure that we *populate* the memory *before*
     // we schedule the cleanup.
@@ -1687,13 +1684,13 @@ fn bind_irrefutable_pat<'a>(
     let tcx = bcx.tcx();
     let ccx = bcx.ccx();
     match pat.node {
-        ast::PatIdent(pat_binding_mode, ref path, inner) => {
+        ast::PatIdent(pat_binding_mode, ref path1, inner) => {
             if pat_is_binding(&tcx.def_map, &*pat) {
                 // Allocate the stack slot where the value of this
                 // binding will live and place it into the appropriate
                 // map.
                 bcx = mk_binding_alloca(
-                    bcx, pat.id, path, binding_mode, cleanup_scope, (),
+                    bcx, pat.id, &path1.node, binding_mode, cleanup_scope, (),
                     |(), bcx, llval, ty| {
                         match pat_binding_mode {
                             ast::BindByValue(_) => {
index 1c48d66f9b81e78cfc409824cdd582050a9e91ac..b3c7c0d0fac46e19c278ed001880bf935842e695 100644 (file)
@@ -842,8 +842,8 @@ pub fn create_local_var_metadata(bcx: &Block, local: &ast::Local) {
     let cx = bcx.ccx();
     let def_map = &cx.tcx.def_map;
 
-    pat_util::pat_bindings(def_map, &*local.pat, |_, node_id, span, path_ref| {
-        let var_ident = ast_util::path_to_ident(path_ref);
+    pat_util::pat_bindings(def_map, &*local.pat, |_, node_id, span, path1| {
+        let var_ident = path1.node;
 
         let datum = match bcx.fcx.lllocals.borrow().find_copy(&node_id) {
             Some(datum) => datum,
@@ -890,8 +890,8 @@ pub fn create_captured_var_metadata(bcx: &Block,
         }
         Some(ast_map::NodeLocal(pat)) | Some(ast_map::NodeArg(pat)) => {
             match pat.node {
-                ast::PatIdent(_, ref path, _) => {
-                    ast_util::path_to_ident(path)
+                ast::PatIdent(_, ref path1, _) => {
+                    path1.node
                 }
                 _ => {
                     cx.sess()
@@ -1007,7 +1007,7 @@ pub fn create_argument_metadata(bcx: &Block, arg: &ast::Arg) {
     let def_map = &cx.tcx.def_map;
     let scope_metadata = bcx.fcx.debug_context.get_ref(cx, arg.pat.span).fn_metadata;
 
-    pat_util::pat_bindings(def_map, &*arg.pat, |_, node_id, span, path_ref| {
+    pat_util::pat_bindings(def_map, &*arg.pat, |_, node_id, span, path1| {
         let llarg = match bcx.fcx.llargs.borrow().find_copy(&node_id) {
             Some(v) => v,
             None => {
@@ -1022,8 +1022,6 @@ pub fn create_argument_metadata(bcx: &Block, arg: &ast::Arg) {
                                     Referenced variable location is not an alloca!");
         }
 
-        let argument_ident = ast_util::path_to_ident(path_ref);
-
         let argument_index = {
             let counter = &fcx.debug_context.get_ref(cx, span).argument_counter;
             let argument_index = counter.get();
@@ -1032,7 +1030,7 @@ pub fn create_argument_metadata(bcx: &Block, arg: &ast::Arg) {
         };
 
         declare_local(bcx,
-                      argument_ident,
+                      path1.node,
                       llarg.ty,
                       scope_metadata,
                       DirectVariable { alloca: llarg.val },
@@ -3237,10 +3235,9 @@ struct ScopeStackEntry {
     // Push argument identifiers onto the stack so arguments integrate nicely
     // with variable shadowing.
     for &arg_pat in arg_pats.iter() {
-        pat_util::pat_bindings(def_map, &*arg_pat, |_, _, _, path_ref| {
-            let ident = ast_util::path_to_ident(path_ref);
+        pat_util::pat_bindings(def_map, &*arg_pat, |_, _, _, path1| {
             scope_stack.push(ScopeStackEntry { scope_metadata: fn_metadata,
-                                               ident: Some(ident) });
+                                               ident: Some(path1.node) });
         })
     }
 
@@ -3348,13 +3345,13 @@ fn walk_pattern(cx: &CrateContext,
         // ast_util::walk_pat() here because we have to visit *all* nodes in
         // order to put them into the scope map. The above functions don't do that.
         match pat.node {
-            ast::PatIdent(_, ref path_ref, ref sub_pat_opt) => {
+            ast::PatIdent(_, ref path1, ref sub_pat_opt) => {
 
                 // Check if this is a binding. If so we need to put it on the
                 // scope stack and maybe introduce an artificial scope
                 if pat_util::pat_is_binding(def_map, &*pat) {
 
-                    let ident = ast_util::path_to_ident(path_ref);
+                    let ident = path1.node;
 
                     // LLVM does not properly generate 'DW_AT_start_scope' fields
                     // for variable DIEs. For this reason we have to introduce
index 79630be7c5e0840c21dfdf99228ed5bbede7f7ac..9629fb38af80fb62cf58726d520725b139aba143 100644 (file)
@@ -2771,8 +2771,8 @@ pub fn local_var_name_str(cx: &ctxt, id: NodeId) -> InternedString {
     match cx.map.find(id) {
         Some(ast_map::NodeLocal(pat)) => {
             match pat.node {
-                ast::PatIdent(_, ref path, _) => {
-                    token::get_ident(ast_util::path_to_ident(path))
+                ast::PatIdent(_, ref path1, _) => {
+                    token::get_ident(path1.node)
                 }
                 _ => {
                     cx.sess.bug(
index 60ce9508dc46b3422eb7dc34e4c5def15d0b4297..697c5d367ee5a51ab3a65cd2a6945de0d3ae5db6 100644 (file)
@@ -485,7 +485,7 @@ pub fn check_pat(pcx: &pat_ctxt, pat: &ast::Pat, expected: ty::t) {
         demand::suptype(fcx, pat.span, expected, const_pty.ty);
         fcx.write_ty(pat.id, const_pty.ty);
       }
-      ast::PatIdent(bm, ref name, sub) if pat_is_binding(&tcx.def_map, pat) => {
+      ast::PatIdent(bm, ref path1, sub) if pat_is_binding(&tcx.def_map, pat) => {
         let typ = fcx.local_ty(pat.span, pat.id);
 
         match bm {
@@ -507,7 +507,7 @@ pub fn check_pat(pcx: &pat_ctxt, pat: &ast::Pat, expected: ty::t) {
           }
         }
 
-        let canon_id = *pcx.map.get(&ast_util::path_to_ident(name));
+        let canon_id = *pcx.map.get(&path1.node);
         if canon_id != pat.id {
             let ct = fcx.local_ty(pat.span, canon_id);
             demand::eqtype(fcx, pat.span, ct, typ);
@@ -521,8 +521,10 @@ pub fn check_pat(pcx: &pat_ctxt, pat: &ast::Pat, expected: ty::t) {
           _ => ()
         }
       }
-      ast::PatIdent(_, ref path, _) => {
-        check_pat_variant(pcx, pat, path, &Some(Vec::new()), expected);
+      // it's not a binding, it's an enum in disguise:
+      ast::PatIdent(_, ref path1, _) => {
+        let path = ast_util::ident_to_path(path1.span,path1.node);
+        check_pat_variant(pcx, pat, &path, &Some(Vec::new()), expected);
       }
       ast::PatEnum(ref path, ref subpats) => {
         check_pat_variant(pcx, pat, path, subpats, expected);
index f5e34e9307764944b73ff9457acb678b2970fa36..b68991aed70963c53c341788689c4f11e1652a7a 100644 (file)
@@ -406,11 +406,11 @@ fn visit_local(&mut self, local: &ast::Local, _: ()) {
     // Add pattern bindings.
     fn visit_pat(&mut self, p: &ast::Pat, _: ()) {
             match p.node {
-              ast::PatIdent(_, ref path, _)
+              ast::PatIdent(_, ref path1, _)
                   if pat_util::pat_is_binding(&self.fcx.ccx.tcx.def_map, p) => {
                 self.assign(p.id, None);
                 debug!("Pattern binding {} is assigned to {}",
-                       token::get_ident(path.segments.get(0).identifier),
+                       token::get_ident(path1.node),
                        self.fcx.infcx().ty_to_str(
                            self.fcx.inh.locals.borrow().get_copy(&p.id)));
               }
index 33e0d0331be6c23d3e0725e161b083f8a74a877a..bda47d99ed7146d0ec7b12ab9dd292a8d19df9ae 100644 (file)
@@ -398,6 +398,9 @@ fn search_for_vtable(vcx: &VtableContext,
         // Resolve any sub bounds. Note that there still may be free
         // type variables in substs. This might still be OK: the
         // process of looking up bounds might constrain some of them.
+        //
+        // This does not check built-in traits because those are handled
+        // later in the kind checking pass.
         let im_generics =
             ty::lookup_item_type(tcx, impl_did).generics;
         let subres = lookup_vtables(vcx,
index f106ce18a4adb579bbed9edf275acd10b430d746..44afc04d3f0efc3984c432dbe6d077e2e835148e 100644 (file)
@@ -93,7 +93,7 @@ pub struct UnificationTable<K,V> {
 
 /**
  * At any time, users may snapshot a unification table.  The changes
- * made during the snapshot may either be *commited* or *rolled back*.
+ * made during the snapshot may either be *committed* or *rolled back*.
  */
 pub struct Snapshot<K> {
     // Ensure that this snapshot is keyed to the table type.
@@ -152,7 +152,7 @@ pub fn in_snapshot(&self) -> bool {
 
     /**
      * Starts a new snapshot. Each snapshot must be either
-     * rolled back or commited in a "LIFO" (stack) order.
+     * rolled back or committed in a "LIFO" (stack) order.
      */
     pub fn snapshot(&mut self) -> Snapshot<K> {
         let length = self.undo_log.len();
@@ -188,12 +188,12 @@ pub fn rollback_to(&mut self, tcx: &ty::ctxt, snapshot: Snapshot<K>) {
             match self.undo_log.pop().unwrap() {
                 OpenSnapshot => {
                     // This indicates a failure to obey the stack discipline.
-                    tcx.sess.bug("Cannot rollback an uncommited snapshot");
+                    tcx.sess.bug("Cannot rollback an uncommitted snapshot");
                 }
 
                 CommittedSnapshot => {
                     // This occurs when there are nested snapshots and
-                    // the inner is commited but outer is rolled back.
+                    // the inner is committed but outer is rolled back.
                 }
 
                 NewVar(i) => {
index e159d0d00c82caa624073cc8d32a69cd518d63a0..7b6935df42079a561fd0e8a12006937679511f71 100644 (file)
@@ -216,9 +216,9 @@ pub fn autoderef(expr_id: ast::NodeId, autoderef: uint) -> MethodCall {
 #[deriving(Clone)]
 pub enum vtable_origin {
     /*
-      Statically known vtable. def_id gives the class or impl item
+      Statically known vtable. def_id gives the impl item
       from whence comes the vtable, and tys are the type substs.
-      vtable_res is the vtable itself
+      vtable_res is the vtable itself.
      */
     vtable_static(ast::DefId, subst::Substs, vtable_res),
 
index 87151708812e54a5f106291d5a04fd851bf6a0dc..d0873d4c66afc9ac9310355b71d55fd506717fe9 100644 (file)
@@ -1583,8 +1583,6 @@ fn clean(&self) -> PathSegment {
 }
 
 fn path_to_str(p: &ast::Path) -> String {
-    use syntax::parse::token;
-
     let mut s = String::new();
     let mut first = true;
     for i in p.segments.iter().map(|x| token::get_ident(x.identifier)) {
@@ -1739,7 +1737,7 @@ pub struct ViewItem {
 
 impl Clean<Vec<Item>> for ast::ViewItem {
     fn clean(&self) -> Vec<Item> {
-        // We consider inlining the documentation of `pub use` statments, but we
+        // We consider inlining the documentation of `pub use` statements, but we
         // forcefully don't inline if this is not public or if the
         // #[doc(no_inline)] attribute is present.
         let denied = self.vis != ast::Public || self.attrs.iter().any(|a| {
@@ -1953,7 +1951,7 @@ fn name_from_pat(p: &ast::Pat) -> String {
     match p.node {
         PatWild => "_".to_string(),
         PatWildMulti => "..".to_string(),
-        PatIdent(_, ref p, _) => path_to_str(p),
+        PatIdent(_, ref p, _) => token::get_ident(p.node).get().to_string(),
         PatEnum(ref p, _) => path_to_str(p),
         PatStruct(..) => fail!("tried to get argument name from pat_struct, \
                                 which is not allowed in function arguments"),
index 9734ba2d7518ef90995726a20ab5b8cd906037e9..161d3ed5e65e1cf70b259481e2321f7b2ebbb754 100644 (file)
@@ -376,7 +376,7 @@ unsafe fn with_c_str_unchecked<T>(&self, f: |*const libc::c_char| -> T) -> T {
 // (without forcing an additional & around &str). So we are instead
 // temporarily adding an instance for ~str and String, so that we can
 // take ToCStr as owned. When DST lands, the string instances should
-// be revisted, and arguments bound by ToCStr should be passed by
+// be revisited, and arguments bound by ToCStr should be passed by
 // reference.
 
 impl<'a> ToCStr for &'a str {
index 6811a62c74f523f7cda3ed8943f2c20accc833e6..f018b3fc16b3b63a8b26145731084f6df32af474 100644 (file)
@@ -97,7 +97,7 @@ pub enum _Unwind_Context {}
 
 extern "C" {
     // iOS on armv7 uses SjLj exceptions and requires to link
-    // agains corresponding routine (..._SjLj_...)
+    // against corresponding routine (..._SjLj_...)
     #[cfg(not(target_os = "ios", target_arch = "arm"))]
     pub fn _Unwind_RaiseException(exception: *mut _Unwind_Exception)
                                   -> _Unwind_Reason_Code;
index 891d0d5a8e3592053b8c4ff14c08079a71b6abbb..59401a8b66604f0568c80a293bf0421e9ed1ecee 100644 (file)
@@ -170,7 +170,7 @@ pub fn new() -> Task {
     /// This function can be used as an emulated "try/catch" to interoperate
     /// with the rust runtime at the outermost boundary. It is not possible to
     /// use this function in a nested fashion (a try/catch inside of another
-    /// try/catch). Invoking this funciton is quite cheap.
+    /// try/catch). Invoking this function is quite cheap.
     ///
     /// If the closure `f` succeeds, then the returned task can be used again
     /// for another invocation of `run`. If the closure `f` fails then `self`
@@ -276,7 +276,7 @@ fn cleanup(~self, result: Result) -> Box<Task> {
         // 1. If TLD destruction fails, heap destruction will be attempted.
         //    There is a test for this at fail-during-tld-destroy.rs. Sadly the
         //    other way can't be tested due to point 2 above. Note that we must
-        //    immortalize the heap first becuase if any deallocations are
+        //    immortalize the heap first because if any deallocations are
         //    attempted while TLD is being dropped it will attempt to free the
         //    allocation from the wrong heap (because the current one has been
         //    replaced).
index 9908e87e86a4727a0230eba1c77c66265bf8c9fd..59784328cdb50c02448a3893b1a4776e947415e3 100644 (file)
@@ -243,7 +243,7 @@ pub unsafe fn create(stack: uint, p: Box<proc():Send>) -> rust_thread {
                 // EINVAL means |stack_size| is either too small or not a
                 // multiple of the system page size.  Because it's definitely
                 // >= PTHREAD_STACK_MIN, it must be an alignment issue.
-                // Round up to the neareast page and try again.
+                // Round up to the nearest page and try again.
                 let page_size = libc::sysconf(libc::_SC_PAGESIZE) as uint;
                 let stack_size = (stack_size + page_size - 1) &
                                  (-(page_size as int - 1) as uint - 1);
index 968a283995bef2fef78775b9594ac7a9cf47d018..a1712394634b8c2d52d7e0cf50ab48c41661228d 100644 (file)
@@ -234,7 +234,7 @@ fn new(s: &'static str) -> ForbidUnwind {
 impl Drop for ForbidUnwind {
     fn drop(&mut self) {
         assert!(self.failing_before == task::failing(),
-                "didnt want an unwind during: {}", self.msg);
+                "didn't want an unwind during: {}", self.msg);
     }
 }
 
index f6b9226588ca34572a7ac8e87172f7c77569d989..875c2dee46b4f874f9cf84a8d293c594558f563b 100644 (file)
@@ -87,7 +87,7 @@ pub fn read(&mut self, buf: &mut [u8]) -> Result<uint, UvError> {
         // immediately as part of the call to alloc_cb. What this means is that
         // we must be ready for this to happen (by setting the data in the uv
         // handle). In theory this otherwise doesn't need to happen until after
-        // the read is succesfully started.
+        // the read is successfully started.
         unsafe { uvll::set_data_for_uv_handle(self.handle, &mut rcx) }
 
         // Send off the read request, but don't block until we're sure that the
index 9d0a56b3c851d69d82f15e3cdf4ab10a0278739b..f6c1cdd2977549f9a5ca7ebd36092fa85872b4cf 100644 (file)
@@ -77,7 +77,7 @@ impl RtioTimer for TimerWatcher {
     fn sleep(&mut self, msecs: u64) {
         // As with all of the below functions, we must be extra careful when
         // destroying the previous action. If the previous action was a channel,
-        // destroying it could invoke a context switch. For these situtations,
+        // destroying it could invoke a context switch. For these situations,
         // we must temporarily un-home ourselves, then destroy the action, and
         // then re-home again.
         let missile = self.fire_homing_missile();
index 2c54bd895e952f59a635bf2041f0cd8d7cb324de..ca59849202b08677e03943747fb2617d6eb6a687 100644 (file)
@@ -410,7 +410,7 @@ fn test_from_str_ipv4_in_ipv6() {
         // colon after v4
         let none: Option<IpAddr> = FromStr::from_str("::127.0.0.1:");
         assert_eq!(None, none);
-        // not enought groups
+        // not enough groups
         let none: Option<IpAddr> = FromStr::from_str("1.2.3.4.5:127.0.0.1");
         assert_eq!(None, none);
         // too many groups
index cd78898d46bb82c22c73b54f39f8d3a3bfc3e516..21903eb26439cc30c79b60d90acdd8ff29bf51a9 100644 (file)
@@ -165,7 +165,7 @@ pub fn set_ttl(&mut self, ttl: int) -> IoResult<()> {
 
     /// Sets the broadcast flag on or off
     #[experimental]
-    pub fn set_broadast(&mut self, broadcast: bool) -> IoResult<()> {
+    pub fn set_broadcast(&mut self, broadcast: bool) -> IoResult<()> {
         if broadcast {
             self.obj.hear_broadcasts()
         } else {
@@ -173,6 +173,12 @@ pub fn set_broadast(&mut self, broadcast: bool) -> IoResult<()> {
         }.map_err(IoError::from_rtio_error)
     }
 
+    /// Sets the broadcast flag on or off
+    #[deprecated="renamed to `set_broadcast`"]
+    pub fn set_broadast(&mut self, broadcast: bool) -> IoResult<()> {
+        self.set_broadcast(broadcast)
+    }
+
     /// Sets the read/write timeout for this socket.
     ///
     /// For more information, see `TcpStream::set_timeout`
index 6674dd532aeb0b5f76d924b3e8c5a5555a863a00..b3f25914c8f568768c22fd62c6523e837895e9c0 100644 (file)
@@ -45,7 +45,7 @@
 use ptr::RawPtr;
 use ptr;
 use result::{Err, Ok, Result};
-use slice::{Vector, ImmutableVector, MutableVector};
+use slice::{Vector, ImmutableVector, MutableVector, ImmutableEqVector};
 use str::{Str, StrSlice, StrAllocating};
 use str;
 use string::String;
@@ -398,9 +398,9 @@ pub fn getenv_as_bytes(n: &str) -> Option<Vec<u8>> {
 ///     None => println!("{} is not defined in the environment.", key)
 /// }
 /// ```
-pub fn setenv(n: &str, v: &str) {
+pub fn setenv<T: BytesContainer>(n: &str, v: T) {
     #[cfg(unix)]
-    fn _setenv(n: &str, v: &str) {
+    fn _setenv(n: &str, v: &[u8]) {
         unsafe {
             with_env_lock(|| {
                 n.with_c_str(|nbuf| {
@@ -413,18 +413,20 @@ fn _setenv(n: &str, v: &str) {
     }
 
     #[cfg(windows)]
-    fn _setenv(n: &str, v: &str) {
+    fn _setenv(n: &str, v: &[u8]) {
         let n: Vec<u16> = n.utf16_units().collect();
         let n = n.append_one(0);
-        let v: Vec<u16> = v.utf16_units().collect();
+        let v: Vec<u16> = str::from_utf8(v).unwrap().utf16_units().collect();
         let v = v.append_one(0);
+
         unsafe {
             with_env_lock(|| {
                 libc::SetEnvironmentVariableW(n.as_ptr(), v.as_ptr());
             })
         }
     }
-    _setenv(n, v)
+
+    _setenv(n, v.container_as_bytes())
 }
 
 /// Remove a variable from the environment entirely.
@@ -453,77 +455,130 @@ fn _unsetenv(n: &str) {
     _unsetenv(n);
 }
 
-#[cfg(unix)]
-/// Parse a string or vector according to the platform's conventions
-/// for the `PATH` environment variable and return a Vec<Path>.
-/// Drops empty paths.
+/// Parses input according to platform conventions for the `PATH`
+/// environment variable.
 ///
 /// # Example
 /// ```rust
 /// use std::os;
 ///
 /// let key = "PATH";
-/// match os::getenv(key) {
+/// match os::getenv_as_bytes(key) {
 ///     Some(paths) => {
 ///         for path in os::split_paths(paths).iter() {
 ///             println!("'{}'", path.display());
 ///         }
 ///     }
-///     None => println!("{} is not defined in the environnement.", key)
+///     None => println!("{} is not defined in the environment.", key)
 /// }
 /// ```
 pub fn split_paths<T: BytesContainer>(unparsed: T) -> Vec<Path> {
-    unparsed.container_as_bytes()
-            .split(|b| *b == ':' as u8)
-            .filter(|s| s.len() > 0)
-            .map(Path::new)
-            .collect()
-}
+    #[cfg(unix)]
+    fn _split_paths<T: BytesContainer>(unparsed: T) -> Vec<Path> {
+        unparsed.container_as_bytes()
+                .split(|b| *b == b':')
+                .map(Path::new)
+                .collect()
+    }
 
-#[cfg(windows)]
-/// Parse a string or vector according to the platform's conventions
-/// for the `PATH` environment variable. Drops empty paths.
-pub fn split_paths<T: BytesContainer>(unparsed: T) -> Vec<Path> {
-    // On Windows, the PATH environment variable is semicolon separated.  Double
-    // quotes are used as a way of introducing literal semicolons (since
-    // c:\some;dir is a valid Windows path). Double quotes are not themselves
-    // permitted in path names, so there is no way to escape a double quote.
-    // Quoted regions can appear in arbitrary locations, so
-    //
-    //   c:\foo;c:\som"e;di"r;c:\bar
-    //
-    // Should parse as [c:\foo, c:\some;dir, c:\bar].
-    //
-    // (The above is based on testing; there is no clear reference available
-    // for the grammar.)
-
-    let mut parsed = Vec::new();
-    let mut in_progress = Vec::new();
-    let mut in_quote = false;
-
-    for b in unparsed.container_as_bytes().iter() {
-        match *b as char {
-            ';' if !in_quote => {
-                // ignore zero-length path strings
-                if in_progress.len() > 0 {
+    #[cfg(windows)]
+    fn _split_paths<T: BytesContainer>(unparsed: T) -> Vec<Path> {
+        // On Windows, the PATH environment variable is semicolon separated.  Double
+        // quotes are used as a way of introducing literal semicolons (since
+        // c:\some;dir is a valid Windows path). Double quotes are not themselves
+        // permitted in path names, so there is no way to escape a double quote.
+        // Quoted regions can appear in arbitrary locations, so
+        //
+        //   c:\foo;c:\som"e;di"r;c:\bar
+        //
+        // Should parse as [c:\foo, c:\some;dir, c:\bar].
+        //
+        // (The above is based on testing; there is no clear reference available
+        // for the grammar.)
+
+        let mut parsed = Vec::new();
+        let mut in_progress = Vec::new();
+        let mut in_quote = false;
+
+        for b in unparsed.container_as_bytes().iter() {
+            match *b {
+                b';' if !in_quote => {
                     parsed.push(Path::new(in_progress.as_slice()));
+                    in_progress.truncate(0)
+                }
+                b'"' => {
+                    in_quote = !in_quote;
+                }
+                _  => {
+                    in_progress.push(*b);
                 }
-                in_progress.truncate(0)
-            }
-            '\"' => {
-                in_quote = !in_quote;
             }
-            _  => {
-                in_progress.push(*b);
+        }
+        parsed.push(Path::new(in_progress));
+        parsed
+    }
+
+    _split_paths(unparsed)
+}
+
+/// Joins a collection of `Path`s appropriately for the `PATH`
+/// environment variable.
+///
+/// Returns a `Vec<u8>` on success, since `Path`s are not utf-8
+/// encoded on all platforms.
+///
+/// Returns an `Err` (containing an error message) if one of the input
+/// `Path`s contains an invalid character for constructing the `PATH`
+/// variable (a double quote on Windows or a colon on Unix).
+///
+/// # Example
+///
+/// ```rust
+/// use std::os;
+/// use std::path::Path;
+///
+/// let key = "PATH";
+/// let mut paths = os::getenv_as_bytes(key).map_or(Vec::new(), os::split_paths);
+/// paths.push(Path::new("/home/xyz/bin"));
+/// os::setenv(key, os::join_paths(paths.as_slice()).unwrap());
+/// ```
+pub fn join_paths<T: BytesContainer>(paths: &[T]) -> Result<Vec<u8>, &'static str> {
+    #[cfg(windows)]
+    fn _join_paths<T: BytesContainer>(paths: &[T]) -> Result<Vec<u8>, &'static str> {
+        let mut joined = Vec::new();
+        let sep = b';';
+
+        for (i, path) in paths.iter().map(|p| p.container_as_bytes()).enumerate() {
+            if i > 0 { joined.push(sep) }
+            if path.contains(&b'"') {
+                return Err("path segment contains `\"`");
+            } else if path.contains(&sep) {
+                joined.push(b'"');
+                joined.push_all(path);
+                joined.push(b'"');
+            } else {
+                joined.push_all(path);
             }
         }
+
+        Ok(joined)
     }
 
-    if in_progress.len() > 0 {
-        parsed.push(Path::new(in_progress));
+    #[cfg(unix)]
+    fn _join_paths<T: BytesContainer>(paths: &[T]) -> Result<Vec<u8>, &'static str> {
+        let mut joined = Vec::new();
+        let sep = b':';
+
+        for (i, path) in paths.iter().map(|p| p.container_as_bytes()).enumerate() {
+            if i > 0 { joined.push(sep) }
+            if path.contains(&sep) { return Err("path segment contains separator `:`") }
+            joined.push_all(path);
+        }
+
+        Ok(joined)
     }
 
-    parsed
+    _join_paths(paths)
 }
 
 /// A low-level OS in-memory pipe.
@@ -1767,7 +1822,7 @@ mod tests {
     use c_str::ToCStr;
     use option;
     use os::{env, getcwd, getenv, make_absolute};
-    use os::{split_paths, setenv, unsetenv};
+    use os::{split_paths, join_paths, setenv, unsetenv};
     use os;
     use rand::Rng;
     use rand;
@@ -2032,11 +2087,11 @@ fn check_parse(unparsed: &str, parsed: &[&str]) -> bool {
                 parsed.iter().map(|s| Path::new(*s)).collect()
         }
 
-        assert!(check_parse("", []));
-        assert!(check_parse(r#""""#, []));
-        assert!(check_parse(";;", []));
+        assert!(check_parse("", [""]));
+        assert!(check_parse(r#""""#, [""]));
+        assert!(check_parse(";;", ["", "", ""]));
         assert!(check_parse(r"c:\", [r"c:\"]));
-        assert!(check_parse(r"c:\;", [r"c:\"]));
+        assert!(check_parse(r"c:\;", [r"c:\", ""]));
         assert!(check_parse(r"c:\;c:\Program Files\",
                             [r"c:\", r"c:\Program Files\"]));
         assert!(check_parse(r#"c:\;c:\"foo"\"#, [r"c:\", r"c:\foo\"]));
@@ -2052,12 +2107,44 @@ fn check_parse(unparsed: &str, parsed: &[&str]) -> bool {
                 parsed.iter().map(|s| Path::new(*s)).collect()
         }
 
-        assert!(check_parse("", []));
-        assert!(check_parse("::", []));
+        assert!(check_parse("", [""]));
+        assert!(check_parse("::", ["", "", ""]));
         assert!(check_parse("/", ["/"]));
-        assert!(check_parse("/:", ["/"]));
+        assert!(check_parse("/:", ["/", ""]));
         assert!(check_parse("/:/usr/local", ["/", "/usr/local"]));
     }
 
+    #[test]
+    #[cfg(unix)]
+    fn join_paths_unix() {
+        fn test_eq(input: &[&str], output: &str) -> bool {
+            join_paths(input).unwrap().as_slice() == output.as_bytes()
+        }
+
+        assert!(test_eq([], ""));
+        assert!(test_eq(["/bin", "/usr/bin", "/usr/local/bin"],
+                        "/bin:/usr/bin:/usr/local/bin"));
+        assert!(test_eq(["", "/bin", "", "", "/usr/bin", ""],
+                        ":/bin:::/usr/bin:"));
+        assert!(join_paths(["/te:st"]).is_err());
+    }
+
+    #[test]
+    #[cfg(windows)]
+    fn join_paths_windows() {
+        fn test_eq(input: &[&str], output: &str) -> bool {
+            join_paths(input).unwrap().as_slice() == output.as_bytes()
+        }
+
+        assert!(test_eq([], ""));
+        assert!(test_eq([r"c:\windows", r"c:\"],
+                        r"c:\windows;c:\"));
+        assert!(test_eq(["", r"c:\windows", "", "", r"c:\", ""],
+                        r";c:\windows;;;c:\;"));
+        assert!(test_eq([r"c:\te;st", r"c:\"],
+                        r#""c:\te;st";c:\"#));
+        assert!(join_paths([r#"c:\te"st"#]).is_err());
+    }
+
     // More recursive_mkdir tests are in extra::tempfile
 }
index 8f51e834c6a024ec0d67b9319908fb0db88cf45d..2e0dcdd8eb69f83588a353615eba5a3cb8f7e344 100644 (file)
@@ -266,7 +266,7 @@ fn backtrace(buf: *mut *const libc::c_void,
         }
 
         // while it doesn't requires lock for work as everything is
-        // local, it still displays much nicier backtraces when a
+        // local, it still displays much nicer backtraces when a
         // couple of tasks fail simultaneously
         static mut LOCK: StaticNativeMutex = NATIVE_MUTEX_INIT;
         let _g = unsafe { LOCK.lock() };
index bf2d9aa52fd24bd9bfd9a8f1272c94a569746e5a..742686069e283531461e68cd7852e9f6d88bbc58 100644 (file)
@@ -354,7 +354,7 @@ pub fn abort_selection(&mut self) -> Result<bool, Receiver<T>> {
             }
 
             // We woke ourselves up from select. Assert that the task should be
-            // trashed and returne that we don't have any data.
+            // trashed and returned that we don't have any data.
             n => {
                 let t = unsafe { BlockedTask::cast_from_uint(n) };
                 t.trash();
index a50a6bbc8d31fcd6d4ee09c9db00347ff58f7294..5ad4dea5d2a89bc52df8a319d19cdecb1703ca94 100644 (file)
@@ -81,7 +81,7 @@ pub fn new() -> Packet<T> {
 
     // This function should be used after newly created Packet
     // was wrapped with an Arc
-    // In other case mutex data will be duplicated while clonning
+    // In other case mutex data will be duplicated while cloning
     // and that could cause problems on platforms where it is
     // represented by opaque data structure
     pub fn postinit_lock(&mut self) {
@@ -140,7 +140,7 @@ pub fn send(&mut self, t: T) -> Result<(), T> {
         // See Port::drop for what's going on
         if self.port_dropped.load(atomics::SeqCst) { return Err(t) }
 
-        // Note that the multiple sender case is a little tricker
+        // Note that the multiple sender case is a little trickier
         // semantically than the single sender case. The logic for
         // incrementing is "add and if disconnected store disconnected".
         // This could end up leading some senders to believe that there
index ef558d3f9241bb0d04f6259cd0aa425fea457c00..a10ec7458690abcbf20e68bd12c2e4730dea4f76 100644 (file)
@@ -215,7 +215,7 @@ pub fn lock<'a>(&'a self) -> Guard<'a> {
             None => {}
         }
 
-        // After we've failed the fast path, then we delegate to the differnet
+        // After we've failed the fast path, then we delegate to the different
         // locking protocols for green/native tasks. This will select two tasks
         // to continue further (one native, one green).
         let t: Box<Task> = Local::take();
index 529b460adcd34d862bcb951e8ee00a8f27358d40..237d0660a41dcca5edb5f15875cd41bdc5fd2f5a 100644 (file)
@@ -293,8 +293,8 @@ pub enum Pat_ {
     // In the nullary enum case, the parser can't determine
     // which it is. The resolver determines this, and
     // records this pattern's NodeId in an auxiliary
-    // set (of "pat_idents that refer to nullary enums")
-    PatIdent(BindingMode, Path, Option<Gc<Pat>>),
+    // set (of "PatIdents that refer to nullary enums")
+    PatIdent(BindingMode, SpannedIdent, Option<Gc<Pat>>),
     PatEnum(Path, Option<Vec<Gc<Pat>>>), /* "none" means a * pattern where
                                      * we don't bind the fields to names */
     PatStruct(Path, Vec<FieldPat>, bool),
@@ -818,7 +818,7 @@ pub struct Arg {
 
 impl Arg {
     pub fn new_self(span: Span, mutability: Mutability) -> Arg {
-        let path = ast_util::ident_to_path(span, special_idents::self_);
+        let path = Spanned{span:span,node:special_idents::self_};
         Arg {
             // HACK(eddyb) fake type for the self argument.
             ty: P(Ty {
index 2a6f7bdb87e35eec4730e2d143a873b61a9fe539..036d6b4b43adc62d537c8c0f9dfc745964d6bca3 100644 (file)
@@ -33,12 +33,6 @@ pub fn path_name_i(idents: &[Ident]) -> String {
     }).collect::<Vec<String>>().connect("::")
 }
 
-// totally scary function: ignores all but the last element, should have
-// a different name
-pub fn path_to_ident(path: &Path) -> Ident {
-    path.segments.last().unwrap().identifier
-}
-
 pub fn local_def(id: NodeId) -> DefId {
     ast::DefId { krate: LOCAL_CRATE, node: id }
 }
@@ -186,6 +180,8 @@ pub fn block_from_expr(e: Gc<Expr>) -> P<Block> {
     })
 }
 
+// convert a span and an identifier to the corresponding
+// 1-segment path
 pub fn ident_to_path(s: Span, identifier: Ident) -> Path {
     ast::Path {
         span: s,
@@ -202,7 +198,7 @@ pub fn ident_to_path(s: Span, identifier: Ident) -> Path {
 
 pub fn ident_to_pat(id: NodeId, s: Span, i: Ident) -> Gc<Pat> {
     box(GC) ast::Pat { id: id,
-                node: PatIdent(BindByValue(MutImmutable), ident_to_path(s, i), None),
+                node: PatIdent(BindByValue(MutImmutable), codemap::Spanned{span:s, node:i}, None),
                 span: s }
 }
 
index 50b1639484d9415385357240cc69d669db1a3179..f0494e181201375096c9e0417a84bce1ba43fb07 100644 (file)
@@ -16,7 +16,6 @@
 use codemap::Span;
 use ext::base;
 use ext::base::*;
-use parse;
 use parse::token::InternedString;
 use parse::token;
 
@@ -48,12 +47,7 @@ fn next(&self) -> State {
 
 pub fn expand_asm(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree])
                   -> Box<base::MacResult> {
-    let mut p = parse::new_parser_from_tts(cx.parse_sess(),
-                                           cx.cfg(),
-                                           tts.iter()
-                                              .map(|x| (*x).clone())
-                                              .collect());
-
+    let mut p = cx.new_parser_from_tts(tts);
     let mut asm = InternedString::new("");
     let mut asm_str_style = None;
     let mut outputs = Vec::new();
index 0d8373eac3c7f5109f7b5a9c23c3231731dad924..d2e69204d333cb5cb0374857bdf9c456a0d22492 100644 (file)
@@ -15,6 +15,7 @@
 use ext;
 use ext::expand;
 use parse;
+use parse::parser;
 use parse::token;
 use parse::token::{InternedString, intern, str_to_ident};
 use util::small_vector::SmallVector;
@@ -433,6 +434,11 @@ pub fn expand_expr(&mut self, mut e: Gc<ast::Expr>) -> Gc<ast::Expr> {
         }
     }
 
+    pub fn new_parser_from_tts(&self, tts: &[ast::TokenTree])
+        -> parser::Parser<'a> {
+        parse::tts_to_parser(self.parse_sess, Vec::from_slice(tts), self.cfg())
+    }
+
     pub fn codemap(&self) -> &'a CodeMap { &self.parse_sess.span_diagnostic.cm }
     pub fn parse_sess(&self) -> &'a parse::ParseSess { self.parse_sess }
     pub fn cfg(&self) -> ast::CrateConfig { self.cfg.clone() }
@@ -472,7 +478,7 @@ pub fn bt_pop(&mut self) {
     }
     /// Emit `msg` attached to `sp`, and stop compilation immediately.
     ///
-    /// `span_err` should be strongly prefered where-ever possible:
+    /// `span_err` should be strongly preferred where-ever possible:
     /// this should *only* be used when
     /// - continuing has a high risk of flow-on errors (e.g. errors in
     ///   declaring a macro would cause all uses of that macro to
@@ -586,11 +592,7 @@ pub fn get_single_str_from_tts(cx: &ExtCtxt,
 pub fn get_exprs_from_tts(cx: &mut ExtCtxt,
                           sp: Span,
                           tts: &[ast::TokenTree]) -> Option<Vec<Gc<ast::Expr>>> {
-    let mut p = parse::new_parser_from_tts(cx.parse_sess(),
-                                           cx.cfg(),
-                                           tts.iter()
-                                              .map(|x| (*x).clone())
-                                              .collect());
+    let mut p = cx.new_parser_from_tts(tts);
     let mut es = Vec::new();
     while p.token != token::EOF {
         es.push(cx.expand_expr(p.parse_expr()));
index 8d48401f9c2a45ec077fcc2cdb8d43d86826fa09..46bc4ec11ce4f044ac14b35d1f603042558bf089 100644 (file)
@@ -759,8 +759,7 @@ fn pat_ident_binding_mode(&self,
                               span: Span,
                               ident: ast::Ident,
                               bm: ast::BindingMode) -> Gc<ast::Pat> {
-        let path = self.path_ident(span, ident);
-        let pat = ast::PatIdent(bm, path, None);
+        let pat = ast::PatIdent(bm, Spanned{span: span, node: ident}, None);
         self.pat(span, pat)
     }
     fn pat_enum(&self, span: Span, path: ast::Path, subpats: Vec<Gc<ast::Pat>> ) -> Gc<ast::Pat> {
index 3e74b2680e060444117922a830cc6d38d03ffc6b..c2930662bc459a31bbb370875ae5a2088dd1171e 100644 (file)
 use parse::attr::ParserAttr;
 use parse::token::InternedString;
 use parse::token;
-use parse;
 
 
 pub fn expand_cfg(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree])
                   -> Box<base::MacResult> {
-    let mut p = parse::new_parser_from_tts(cx.parse_sess(),
-                                           cx.cfg(),
-                                           tts.iter()
-                                              .map(|x| (*x).clone())
-                                              .collect());
-
+    let mut p = cx.new_parser_from_tts(tts);
     let mut cfgs = Vec::new();
     // parse `cfg!(meta_item, meta_item(x,y), meta_item="foo", ...)`
     while p.token != token::EOF {
index 2b97687dbf8c99e5d19704f3c957758165d41ade..157b64fb47c0a7fa3d699681bb0d223d7a718f46 100644 (file)
@@ -834,7 +834,7 @@ fn build_enum_match(&self,
                                 generic `deriving`");
             }
 
-            // `ref` inside let matches is buggy. Causes havoc wih rusc.
+            // `ref` inside let matches is buggy. Causes havoc with rusc.
             // let (variant_index, ref self_vec) = matches_so_far[0];
             let (variant, self_vec) = match matches_so_far.get(0) {
                 &(_, v, ref s) => (v, s)
@@ -1049,7 +1049,7 @@ fn summarise_struct(&self,
 
     fn create_subpatterns(&self,
                           cx: &mut ExtCtxt,
-                          field_paths: Vec<ast::Path> ,
+                          field_paths: Vec<ast::SpannedIdent> ,
                           mutbl: ast::Mutability)
                           -> Vec<Gc<ast::Pat>> {
         field_paths.iter().map(|path| {
@@ -1095,15 +1095,10 @@ fn create_struct_pattern(&self,
                     cx.span_bug(sp, "a struct with named and unnamed fields in `deriving`");
                 }
             };
-            let path =
-                cx.path_ident(sp,
-                              cx.ident_of(format!("{}_{}",
-                                                  prefix,
-                                                  i).as_slice()));
-            paths.push(path.clone());
+            let ident = cx.ident_of(format!("{}_{}", prefix, i).as_slice());
+            paths.push(codemap::Spanned{span: sp, node: ident});
             let val = cx.expr(
-                sp, ast::ExprParen(
-                    cx.expr_deref(sp, cx.expr_path(path))));
+                sp, ast::ExprParen(cx.expr_deref(sp, cx.expr_path(cx.path_ident(sp,ident)))));
             ident_expr.push((sp, opt_id, val));
         }
 
@@ -1145,15 +1140,11 @@ fn create_enum_variant_pattern(&self,
                 let mut ident_expr = Vec::new();
                 for (i, va) in variant_args.iter().enumerate() {
                     let sp = self.set_expn_info(cx, va.ty.span);
-                    let path =
-                        cx.path_ident(sp,
-                                      cx.ident_of(format!("{}_{}",
-                                                          prefix,
-                                                          i).as_slice()));
-
-                    paths.push(path.clone());
-                    let val = cx.expr(
-                        sp, ast::ExprParen(cx.expr_deref(sp, cx.expr_path(path))));
+                    let ident = cx.ident_of(format!("{}_{}", prefix, i).as_slice());
+                    let path1 = codemap::Spanned{span: sp, node: ident};
+                    paths.push(path1);
+                    let expr_path = cx.expr_path(cx.path_ident(sp, ident));
+                    let val = cx.expr(sp, ast::ExprParen(cx.expr_deref(sp, expr_path)));
                     ident_expr.push((sp, None, val));
                 }
 
index b9cedb7a7797a065a9b32a34e137ef12b1310972..c3413293e52ae4b1ac664de13b7246ccffdd5070 100644 (file)
@@ -705,22 +705,10 @@ fn visit_pat(&mut self, pattern: &ast::Pat, _: ()) {
             // we found a pat_ident!
             ast::Pat {
                 id: _,
-                node: ast::PatIdent(_, ref path, ref inner),
+                node: ast::PatIdent(_, ref path1, ref inner),
                 span: _
             } => {
-                match path {
-                    // a path of length one:
-                    &ast::Path {
-                        global: false,
-                        span: _,
-                        segments: ref segments
-                    } if segments.len() == 1 => {
-                        self.ident_accumulator.push(segments.get(0)
-                                                            .identifier)
-                    }
-                    // I believe these must be enums...
-                    _ => ()
-                }
+                self.ident_accumulator.push(path1.node);
                 // visit optional subpattern of pat_ident:
                 for subpat in inner.iter() {
                     self.visit_pat(&**subpat, ())
@@ -1307,7 +1295,7 @@ macro_rules! outer ( ($e:pat ) => (inner!($e)))
     }
 
     // create a really evil test case where a $x appears inside a binding of $x
-    // but *shouldnt* bind because it was inserted by a different macro....
+    // but *shouldn't* bind because it was inserted by a different macro....
     // can't write this test case until we have macro-generating macros.
 
     // FIXME #9383 : lambda var hygiene
index 857eadfe57cc40ea9081dbf35136eb20baa47547..f39e50ad1313f63501394e1a31da42b528c2a396 100644 (file)
@@ -16,7 +16,6 @@
 use ext::build::AstBuilder;
 use parse::token::InternedString;
 use parse::token;
-use rsparse = parse;
 
 use parse = fmt_macros;
 use std::collections::HashMap;
@@ -81,11 +80,7 @@ fn parse_args(ecx: &mut ExtCtxt, sp: Span, allow_method: bool,
     let mut names = HashMap::<String, Gc<ast::Expr>>::new();
     let mut order = Vec::new();
 
-    let mut p = rsparse::new_parser_from_tts(ecx.parse_sess(),
-                                             ecx.cfg(),
-                                             tts.iter()
-                                                .map(|x| (*x).clone())
-                                                .collect());
+    let mut p = ecx.new_parser_from_tts(tts);
     // Parse the leading function expression (maybe a block, maybe a path)
     let invocation = if allow_method {
         let e = p.parse_expr();
index 35702b1b3cd46d6dbbc9f714d96ffa30bb78c3f3..7b24b97d5da4dd6be7557657bb8019f0ba816103 100644 (file)
@@ -15,7 +15,6 @@
 use ext::build::AstBuilder;
 use parse::token::*;
 use parse::token;
-use parse;
 
 use std::gc::Gc;
 
@@ -583,11 +582,7 @@ fn expand_tts(cx: &ExtCtxt, sp: Span, tts: &[ast::TokenTree])
     // it has to do with transition away from supporting old-style macros, so
     // try removing it when enough of them are gone.
 
-    let mut p = parse::new_parser_from_tts(cx.parse_sess(),
-                                           cx.cfg(),
-                                           tts.iter()
-                                              .map(|x| (*x).clone())
-                                              .collect());
+    let mut p = cx.new_parser_from_tts(tts);
     p.quote_depth += 1u;
 
     let cx_expr = p.parse_expr();
index c6177ce31f5f874a8282020d717a6ca2f1c792bf..f9d7078da3dcbe4377132259c3c5699ae66fca36 100644 (file)
@@ -791,9 +791,10 @@ pub fn noop_fold_pat<T: Folder>(p: Gc<Pat>, folder: &mut T) -> Gc<Pat> {
     let node = match p.node {
         PatWild => PatWild,
         PatWildMulti => PatWildMulti,
-        PatIdent(binding_mode, ref pth, ref sub) => {
+        PatIdent(binding_mode, ref pth1, ref sub) => {
             PatIdent(binding_mode,
-                     folder.fold_path(pth),
+                     Spanned{span: folder.new_span(pth1.span),
+                                       node: folder.fold_ident(pth1.node)},
                      sub.map(|x| folder.fold_pat(x)))
         }
         PatLit(e) => PatLit(folder.fold_expr(e)),
index 331a49c83beacbeac006dc3a5666cc0e40c475de..4b5252bfba3118eb081d8a1783d18631a265b9bc 100644 (file)
@@ -594,23 +594,15 @@ fn parser_done(p: Parser){
     #[test] fn parse_ident_pat () {
         let sess = new_parse_sess();
         let mut parser = string_to_parser(&sess, "b".to_string());
-        assert!(parser.parse_pat() ==
-                   box(GC) ast::Pat{id: ast::DUMMY_NODE_ID,
-                             node: ast::PatIdent(
-                                ast::BindByValue(ast::MutImmutable),
-                                ast::Path {
-                                    span:sp(0,1),
-                                    global:false,
-                                    segments: vec!(
-                                        ast::PathSegment {
-                                            identifier: str_to_ident("b"),
-                                            lifetimes: Vec::new(),
-                                            types: OwnedSlice::empty(),
-                                        }
-                                    ),
-                                },
-                                None /* no idea */),
-                             span: sp(0,1)});
+        assert!(parser.parse_pat()
+                == box(GC) ast::Pat{
+                id: ast::DUMMY_NODE_ID,
+                node: ast::PatIdent(ast::BindByValue(ast::MutImmutable),
+                                    Spanned{ span:sp(0, 1),
+                                             node: str_to_ident("b")
+                    },
+                                    None),
+                span: sp(0,1)});
         parser_done(parser);
     }
 
@@ -643,24 +635,15 @@ fn parser_done(p: Parser){
                                         id: ast::DUMMY_NODE_ID,
                                         node: ast::PatIdent(
                                             ast::BindByValue(ast::MutImmutable),
-                                            ast::Path {
-                                                span:sp(6,7),
-                                                global:false,
-                                                segments: vec!(
-                                                    ast::PathSegment {
-                                                        identifier:
-                                                            str_to_ident("b"),
-                                                        lifetimes: Vec::new(),
-                                                        types: OwnedSlice::empty(),
-                                                    }
-                                                ),
-                                            },
-                                            None // no idea
-                                        ),
-                                        span: sp(6,7)
-                                    },
-                                    id: ast::DUMMY_NODE_ID
-                                }),
+                                                Spanned{
+                                                    span: sp(6,7),
+                                                    node: str_to_ident("b")},
+                                                None
+                                                    ),
+                                            span: sp(6,7)
+                                        },
+                                        id: ast::DUMMY_NODE_ID
+                                    }),
                                 output: ast::P(ast::Ty{id: ast::DUMMY_NODE_ID,
                                                        node: ast::TyNil,
                                                        span:sp(15,15)}), // not sure
index 0fd5a7086b78c897507508137b3d7c410242a6a5..f3789e25bc8a7e5e39bc1e1ded000561e43c4578 100644 (file)
@@ -58,7 +58,7 @@
 use ast::{ViewPath, ViewPathGlob, ViewPathList, ViewPathSimple};
 use ast::Visibility;
 use ast;
-use ast_util::{as_prec, lit_is_str, operator_prec};
+use ast_util::{as_prec, ident_to_path, lit_is_str, operator_prec};
 use ast_util;
 use codemap::{Span, BytePos, Spanned, spanned, mk_sp};
 use codemap;
@@ -2854,8 +2854,7 @@ fn parse_pat_fields(&mut self) -> (Vec<ast::FieldPat> , bool) {
                 self.bump();
                 self.parse_pat()
             } else {
-                let fieldpath = ast_util::ident_to_path(self.last_span,
-                                                        fieldname);
+                let fieldpath = codemap::Spanned{span:self.last_span, node: fieldname};
                 box(GC) ast::Pat {
                     id: ast::DUMMY_NODE_ID,
                     node: PatIdent(bind_type, fieldpath, None),
@@ -2961,6 +2960,7 @@ pub fn parse_pat(&mut self) -> Gc<Pat> {
           }
           _ => {}
         }
+        // at this point, token != _, ~, &, &&, (, [
 
         if (!is_ident_or_path(&self.token) && self.token != token::MOD_SEP)
                 || self.is_keyword(keywords::True)
@@ -3017,7 +3017,9 @@ pub fn parse_pat(&mut self) -> Gc<Pat> {
                 let end = self.parse_expr_res(RESTRICT_NO_BAR_OP);
                 pat = PatRange(start, end);
             } else if is_plain_ident(&self.token) && !can_be_enum_or_struct {
-                let name = self.parse_path(NoTypesAllowed).path;
+                let id = self.parse_ident();
+                let id_span = self.last_span;
+                let pth1 = codemap::Spanned{span:id_span, node: id};
                 if self.eat(&token::NOT) {
                     // macro invocation
                     let ket = token::close_delimiter_for(&self.token)
@@ -3028,7 +3030,7 @@ pub fn parse_pat(&mut self) -> Gc<Pat> {
                                                     seq_sep_none(),
                                                     |p| p.parse_token_tree());
 
-                    let mac = MacInvocTT(name, tts, EMPTY_CTXT);
+                    let mac = MacInvocTT(ident_to_path(id_span,id), tts, EMPTY_CTXT);
                     pat = ast::PatMac(codemap::Spanned {node: mac, span: self.span});
                 } else {
                     let sub = if self.eat(&token::AT) {
@@ -3038,7 +3040,7 @@ pub fn parse_pat(&mut self) -> Gc<Pat> {
                         // or just foo
                         None
                     };
-                    pat = PatIdent(BindByValue(MutImmutable), name, sub);
+                    pat = PatIdent(BindByValue(MutImmutable), pth1, sub);
                 }
             } else {
                 // parse an enum pat
@@ -3084,8 +3086,11 @@ pub fn parse_pat(&mut self) -> Gc<Pat> {
                                   // or an identifier pattern, resolve
                                   // will sort it out:
                                   pat = PatIdent(BindByValue(MutImmutable),
-                                                  enum_path,
-                                                  None);
+                                                 codemap::Spanned{
+                                                    span: enum_path.span,
+                                                    node: enum_path.segments.get(0)
+                                                           .identifier},
+                                                 None);
                               } else {
                                   pat = PatEnum(enum_path, Some(args));
                               }
@@ -3115,7 +3120,7 @@ fn parse_pat_ident(&mut self,
                             "expected identifier, found path");
         }
         // why a path here, and not just an identifier?
-        let name = self.parse_path(NoTypesAllowed).path;
+        let name = codemap::Spanned{span: self.last_span, node: self.parse_ident()};
         let sub = if self.eat(&token::AT) {
             Some(self.parse_pat())
         } else {
@@ -3243,7 +3248,7 @@ fn check_expected_item(p: &mut Parser, found_attrs: bool) {
                 None      => {
                     // we only expect an ident if we didn't parse one
                     // above.
-                    let ident_str = if id == token::special_idents::invalid {
+                    let ident_str = if id.name == token::special_idents::invalid.name {
                         "identifier, "
                     } else {
                         ""
@@ -3263,7 +3268,7 @@ fn check_expected_item(p: &mut Parser, found_attrs: bool) {
             );
             let hi = self.span.hi;
 
-            if id == token::special_idents::invalid {
+            if id.name == token::special_idents::invalid.name {
                 return box(GC) spanned(lo, hi, StmtMac(
                     spanned(lo, hi, MacInvocTT(pth, tts, EMPTY_CTXT)), false));
             } else {
index a9cf4fbd9f0f130855ce8c67d9bc5f0ab6f58a56..4660bb337ab23e1d46c4d8ad2fb608a214d5804c 100644 (file)
@@ -196,6 +196,10 @@ pub fn path_to_str(p: &ast::Path) -> String {
     to_str(|s| s.print_path(p, false))
 }
 
+pub fn ident_to_str(id: &ast::Ident) -> String {
+    to_str(|s| s.print_ident(*id))
+}
+
 pub fn fun_to_str(decl: &ast::FnDecl, fn_style: ast::FnStyle, name: ast::Ident,
                   opt_explicit_self: Option<ast::ExplicitSelf_>,
                   generics: &ast::Generics) -> String {
@@ -1705,7 +1709,7 @@ pub fn print_pat(&mut self, pat: &ast::Pat) -> IoResult<()> {
         match pat.node {
             ast::PatWild => try!(word(&mut self.s, "_")),
             ast::PatWildMulti => try!(word(&mut self.s, "..")),
-            ast::PatIdent(binding_mode, ref path, sub) => {
+            ast::PatIdent(binding_mode, ref path1, sub) => {
                 match binding_mode {
                     ast::BindByRef(mutbl) => {
                         try!(self.word_nbsp("ref"));
@@ -1716,7 +1720,7 @@ pub fn print_pat(&mut self, pat: &ast::Pat) -> IoResult<()> {
                         try!(self.word_nbsp("mut"));
                     }
                 }
-                try!(self.print_path(path, true));
+                try!(self.print_ident(path1.node));
                 match sub {
                     Some(ref p) => {
                         try!(word(&mut self.s, "@"));
@@ -2148,9 +2152,8 @@ pub fn print_arg(&mut self, input: &ast::Arg) -> IoResult<()> {
             ast::TyInfer => try!(self.print_pat(&*input.pat)),
             _ => {
                 match input.pat.node {
-                    ast::PatIdent(_, ref path, _) if
-                        path.segments.len() == 1 &&
-                        path.segments.get(0).identifier.name ==
+                    ast::PatIdent(_, ref path1, _) if
+                        path1.node.name ==
                             parse::token::special_idents::invalid.name => {
                         // Do nothing.
                     }
index 6f0fc217533fc5070b25007d2bad6cfaa9aa9175..4ab064a88b7950d3ede7d4ab57d8c05591666205 100644 (file)
@@ -454,8 +454,8 @@ pub fn walk_pat<E: Clone, V: Visitor<E>>(visitor: &mut V, pattern: &Pat, env: E)
         PatRegion(ref subpattern) => {
             visitor.visit_pat(&**subpattern, env)
         }
-        PatIdent(_, ref path, ref optional_subpattern) => {
-            visitor.visit_path(path, pattern.id, env.clone());
+        PatIdent(_, ref pth1, ref optional_subpattern) => {
+            visitor.visit_ident(pth1.span, pth1.node, env.clone());
             match *optional_subpattern {
                 None => {}
                 Some(ref subpattern) => visitor.visit_pat(&**subpattern, env),
index f52a032961dd96a568628259f8d785e43ff21fbd..98544a1218aad705ae5348d0cc32f137c9aa19eb 100644 (file)
@@ -330,7 +330,7 @@ pub fn strftime(&self, format: &str) -> String {
      * Returns a time string formatted according to RFC 822.
      *
      * local: "Thu, 22 Mar 2012 07:53:18 PST"
-     * utc:   "Thu, 22 Mar 2012 14:53:18 UTC"
+     * utc:   "Thu, 22 Mar 2012 14:53:18 GMT"
      */
     pub fn rfc822(&self) -> String {
         if self.tm_gmtoff == 0_i32 {
@@ -351,7 +351,8 @@ pub fn rfc822z(&self) -> String {
     }
 
     /**
-     * Returns a time string formatted according to ISO 8601.
+     * Returns a time string formatted according to RFC 3999. RFC 3999 is
+     * compatible with ISO 8601.
      *
      * local: "2012-02-22T07:53:18-07:00"
      * utc:   "2012-02-22T14:53:18Z"
diff --git a/src/test/compile-fail/issue-10536.rs b/src/test/compile-fail/issue-10536.rs
new file mode 100644 (file)
index 0000000..36afc72
--- /dev/null
@@ -0,0 +1,34 @@
+// 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.
+
+// We only want to assert that this doesn't ICE, we don't particularly care
+// about whether it nor it fails to compile.
+
+// error-pattern:
+
+#![feature(macro_rules)]
+
+macro_rules! foo{
+    () => {{
+        macro_rules! bar{() => (())}
+        1
+    }}
+}
+
+pub fn main() {
+    foo!();
+
+    assert!({one! two()});
+
+    // regardless of whether nested macro_rules works, the following should at
+    // least throw a conventional error.
+    assert!({one! two});
+}
+
diff --git a/src/test/compile-fail/kindck-impl-type-params.rs b/src/test/compile-fail/kindck-impl-type-params.rs
new file mode 100644 (file)
index 0000000..48e1bdd
--- /dev/null
@@ -0,0 +1,39 @@
+// 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.
+
+// Issue #14061: tests the interaction between generic implementation
+// parameter bounds and trait objects.
+
+struct S<T>;
+
+trait Gettable<T> {}
+
+impl<T: Send + Copy> Gettable<T> for S<T> {}
+
+fn f<T>(val: T) {
+    let t: S<T> = S;
+    let a = &t as &Gettable<T>;
+    //~^ ERROR instantiating a type parameter with an incompatible type `T`
+    let a: &Gettable<T> = &t;
+    //~^ ERROR instantiating a type parameter with an incompatible type `T`
+}
+
+fn main() {
+    let t: S<&int> = S;
+    let a = &t as &Gettable<&int>;
+    //~^ ERROR instantiating a type parameter with an incompatible type `&int`
+    let t: Box<S<String>> = box S;
+    let a = t as Box<Gettable<String>>;
+    //~^ ERROR instantiating a type parameter with an incompatible type
+    let t: Box<S<String>> = box S;
+    let a: Box<Gettable<String>> = t;
+    //~^ ERROR instantiating a type parameter with an incompatible type
+}
+