]> git.lizzy.rs Git - rust.git/commitdiff
Auto merge of #28957 - GuillaumeGomez:patch-5, r=Manishearth
authorbors <bors@rust-lang.org>
Fri, 16 Oct 2015 09:49:50 +0000 (09:49 +0000)
committerbors <bors@rust-lang.org>
Fri, 16 Oct 2015 09:49:50 +0000 (09:49 +0000)
cc @nagisa

193 files changed:
COMPILER_TESTS.md
src/doc/complement-lang-faq.md
src/doc/nomicon/casts.md
src/doc/nomicon/dropck.md
src/doc/nomicon/exotic-sizes.md
src/doc/nomicon/leaking.md
src/doc/nomicon/meet-safe-and-unsafe.md
src/doc/nomicon/races.md
src/doc/nomicon/safe-unsafe-meaning.md
src/doc/nomicon/send-and-sync.md
src/doc/nomicon/transmutes.md
src/doc/nomicon/unbounded-lifetimes.md
src/doc/nomicon/unchecked-uninit.md
src/doc/nomicon/uninitialized.md
src/doc/nomicon/unwinding.md
src/doc/nomicon/vec-layout.md
src/doc/nomicon/vec-push-pop.md
src/doc/nomicon/vec-zsts.md
src/doc/reference.md
src/doc/style/SUMMARY.md
src/doc/style/changing/README.md [deleted file]
src/doc/style/changing/post-1-0.md [deleted file]
src/doc/style/changing/pre-1-0.md [deleted file]
src/doc/style/changing/unclear.md [deleted file]
src/doc/style/features/modules.md
src/doc/style/features/traits/reuse.md
src/doc/trpl/concurrency.md
src/doc/trpl/dining-philosophers.md
src/doc/trpl/error-handling.md
src/doc/trpl/if-let.md
src/doc/trpl/iterators.md
src/doc/trpl/lifetimes.md
src/doc/trpl/references-and-borrowing.md
src/doc/trpl/rust-inside-other-languages.md
src/doc/trpl/syntax-index.md
src/doc/trpl/testing.md
src/doc/trpl/variable-bindings.md
src/driver/driver.rs
src/error-index-generator/main.rs
src/liballoc/arc.rs
src/liballoc/boxed.rs
src/liballoc/raw_vec.rs
src/liballoc/rc.rs
src/liballoc_jemalloc/lib.rs
src/liballoc_system/lib.rs
src/libarena/lib.rs
src/libcollections/btree/map.rs
src/libcollections/btree/node.rs
src/libcollections/string.rs
src/libcore/fmt/mod.rs
src/libcore/intrinsics.rs
src/libcore/iter.rs
src/libcore/macros.rs
src/libcore/marker.rs
src/libcore/mem.rs
src/libcore/nonzero.rs
src/libcore/num/dec2flt/parse.rs
src/libcore/num/mod.rs
src/libcore/ptr.rs
src/libcore/raw.rs
src/libcore/str/mod.rs
src/libcoretest/num/dec2flt/mod.rs
src/libcoretest/num/mod.rs
src/libflate/lib.rs
src/libfmt_macros/lib.rs
src/libgraphviz/lib.rs
src/liblog/directive.rs
src/liblog/lib.rs
src/librand/distributions/gamma.rs
src/librand/distributions/normal.rs
src/librustc/front/map/collector.rs
src/librustc/front/map/mod.rs
src/librustc/lint/context.rs
src/librustc/lint/mod.rs
src/librustc/metadata/encoder.rs
src/librustc/middle/astencode.rs
src/librustc/middle/check_match.rs
src/librustc/middle/check_static_recursion.rs
src/librustc/middle/const_eval.rs
src/librustc/middle/dead.rs
src/librustc/middle/def.rs
src/librustc/middle/stability.rs
src/librustc/middle/ty/mod.rs
src/librustc_back/svh.rs
src/librustc_bitflags/lib.rs
src/librustc_front/fold.rs
src/librustc_front/hir.rs
src/librustc_front/lowering.rs
src/librustc_front/print/pprust.rs
src/librustc_front/util.rs
src/librustc_front/visit.rs
src/librustc_lint/bad_style.rs
src/librustc_lint/builtin.rs
src/librustc_privacy/lib.rs
src/librustc_resolve/build_reduced_graph.rs
src/librustc_resolve/lib.rs
src/librustc_trans/diagnostics.rs
src/librustc_trans/save/dump_csv.rs
src/librustc_trans/save/recorder.rs
src/librustc_trans/trans/base.rs
src/librustc_trans/trans/cabi_x86_64.rs
src/librustc_trans/trans/cabi_x86_win64.rs
src/librustc_trans/trans/callee.rs
src/librustc_trans/trans/consts.rs
src/librustc_trans/trans/debuginfo/metadata.rs
src/librustc_trans/trans/foreign.rs
src/librustc_trans/trans/inline.rs
src/librustc_trans/trans/monomorphize.rs
src/librustc_typeck/check/_match.rs
src/librustc_typeck/check/mod.rs
src/librustc_typeck/check/regionck.rs
src/librustc_typeck/check/wf.rs
src/librustc_typeck/check/wfcheck.rs
src/librustc_typeck/check/writeback.rs
src/librustc_typeck/collect.rs
src/librustdoc/clean/mod.rs
src/librustdoc/doctree.rs
src/librustdoc/visit_ast.rs
src/libstd/collections/hash/map.rs
src/libstd/env.rs
src/libstd/fs.rs
src/libstd/io/error.rs
src/libstd/io/impls.rs
src/libstd/lib.rs
src/libstd/net/tcp.rs
src/libstd/os/android/raw.rs
src/libstd/os/bitrig/raw.rs
src/libstd/os/dragonfly/raw.rs
src/libstd/os/freebsd/raw.rs
src/libstd/os/ios/raw.rs
src/libstd/os/linux/raw.rs
src/libstd/os/macos/raw.rs
src/libstd/os/nacl/raw.rs
src/libstd/os/netbsd/raw.rs
src/libstd/os/openbsd/raw.rs
src/libstd/prelude/mod.rs
src/libstd/process.rs
src/libstd/sync/mutex.rs
src/libstd/sync/rwlock.rs
src/libstd/sys/unix/fs.rs
src/libstd/sys/unix/os.rs
src/libstd/sys/windows/c.rs
src/libstd/sys/windows/fs.rs
src/libsyntax/ast.rs
src/libsyntax/ast_util.rs
src/libsyntax/config.rs
src/libsyntax/ext/base.rs
src/libsyntax/ext/build.rs
src/libsyntax/ext/deriving/generic/mod.rs
src/libsyntax/ext/deriving/primitive.rs
src/libsyntax/ext/pushpop_safe.rs [deleted file]
src/libsyntax/feature_gate.rs
src/libsyntax/fold.rs
src/libsyntax/lib.rs
src/libsyntax/parse/parser.rs
src/libsyntax/print/pprust.rs
src/libsyntax/visit.rs
src/rt/rust_test_helpers.c
src/rustllvm/PassWrapper.cpp
src/test/bench/shootout-nbody.rs
src/test/compile-fail/augmented-assignments-feature-gate-cross.rs
src/test/compile-fail/augmented-assignments-feature-gate.rs
src/test/compile-fail/deriving-primitive.rs
src/test/compile-fail/empty-struct-braces-expr.rs [new file with mode: 0644]
src/test/compile-fail/empty-struct-braces-gate-1.rs [new file with mode: 0644]
src/test/compile-fail/empty-struct-braces-gate-2.rs [new file with mode: 0644]
src/test/compile-fail/empty-struct-braces-pat-1.rs [new file with mode: 0644]
src/test/compile-fail/empty-struct-braces-pat-2.rs [new file with mode: 0644]
src/test/compile-fail/empty-struct-unit-expr.rs [new file with mode: 0644]
src/test/compile-fail/empty-struct-unit-pat.rs [new file with mode: 0644]
src/test/compile-fail/empty-struct-with-braces-1.rs [deleted file]
src/test/compile-fail/empty-struct-with-braces-2.rs [deleted file]
src/test/compile-fail/empty-struct-with-braces-3.rs [deleted file]
src/test/compile-fail/feature-gate-pushpop-unsafe.rs [deleted file]
src/test/compile-fail/issue-16819.rs [new file with mode: 0644]
src/test/compile-fail/issue-27831.rs
src/test/compile-fail/pushpop-unsafe-rejects.rs [deleted file]
src/test/compile-fail/struct-no-fields-enumlike.rs [new file with mode: 0644]
src/test/compile-fail/unsafe-const-fn.rs [new file with mode: 0644]
src/test/parse-fail/struct-no-fields-enumlike.rs [deleted file]
src/test/parse-fail/struct-variant-no-fields.rs [deleted file]
src/test/run-make/extern-fn-struct-passing-abi/Makefile [new file with mode: 0644]
src/test/run-make/extern-fn-struct-passing-abi/test.c [new file with mode: 0644]
src/test/run-make/extern-fn-struct-passing-abi/test.rs [new file with mode: 0644]
src/test/run-pass/empty-struct-braces.rs [new file with mode: 0644]
src/test/run-pass/empty-struct-with-braces.rs [deleted file]
src/test/run-pass/issue-17336.rs [new file with mode: 0644]
src/test/run-pass/issue-22814.rs [new file with mode: 0644]
src/test/run-pass/issue-28676.rs [new file with mode: 0644]
src/test/run-pass/issue-28983.rs [new file with mode: 0644]
src/test/run-pass/issue-28999.rs [new file with mode: 0644]
src/test/run-pass/pushpop-unsafe-okay.rs [deleted file]
src/test/run-pass/unsafe-const-fn.rs [new file with mode: 0644]

index 0606686fcfb10c71c9d260f4341ac3bd7b663a3b..e2a957e396191150bda46f9610b0a9a44d8f9714 100644 (file)
@@ -1,6 +1,6 @@
 # Compiler Test Documentation
 
-In the Rust project, we use a special set of comands embedded in
+In the Rust project, we use a special set of commands embedded in
 comments to test the Rust compiler. There are two groups of commands:
 
 1. Header commands
index 8b9467589c6541da4a0b34aceaba02c9cffb69ab..05c17606ce0342f705cfe52c36dd24d7cfa075f8 100644 (file)
@@ -76,7 +76,7 @@ Cleanup through RAII-style destructors is more likely to work than in catch bloc
 
 ## Why aren't modules type-parametric?
 
-We want to maintain the option to parametrize at runtime. We may eventually change this limitation, but initially this is how type parameters were implemented.
+We want to maintain the option to parameterize at runtime. We may eventually change this limitation, but initially this is how type parameters were implemented.
 
 ## Why aren't values type-parametric? Why only items?
 
index 5f07709cf4542efbd6a46bb3ce16eac783fd3b52..6cc41bd9533c76f6ed51157a57b57c484daa106c 100644 (file)
@@ -52,7 +52,7 @@ For numeric casts, there are quite a few cases to consider:
     * zero-extend if the source is unsigned
     * sign-extend if the source is signed
 * casting from a float to an integer will round the float towards zero
-    * **[NOTE: currently this will cause Undefined Behaviour if the rounded
+    * **[NOTE: currently this will cause Undefined Behavior if the rounded
       value cannot be represented by the target integer type][float-int]**.
       This includes Inf and NaN. This is a bug and will be fixed.
 * casting from an integer to float will produce the floating point
@@ -61,7 +61,7 @@ For numeric casts, there are quite a few cases to consider:
 * casting from an f32 to an f64 is perfect and lossless
 * casting from an f64 to an f32 will produce the closest possible value
   (rounding strategy unspecified)
-    * **[NOTE: currently this will cause Undefined Behaviour if the value
+    * **[NOTE: currently this will cause Undefined Behavior if the value
       is finite but larger or smaller than the largest or smallest finite
       value representable by f32][float-float]**. This is a bug and will
       be fixed.
index 7c097c9126679515e49ee24bb61c3ccad4b212c5..95bcdc02ba0292da5b0522e09efb66657bfb2b0f 100644 (file)
@@ -6,7 +6,7 @@ interacted with the *outlives* relationship in an inclusive manner. That is,
 when we talked about `'a: 'b`, it was ok for `'a` to live *exactly* as long as
 `'b`. At first glance, this seems to be a meaningless distinction. Nothing ever
 gets dropped at the same time as another, right? This is why we used the
-following desugarring of `let` statements:
+following desugaring of `let` statements:
 
 ```rust,ignore
 let x;
index e8637e38ac7d5f7d3230a5dbca95dc854a5352f1..052e3c5fddc551ac81be5791c049ea302fff5d58 100644 (file)
@@ -20,7 +20,7 @@ information that "completes" them (more on this below).
 There are two major DSTs exposed by the language: trait objects, and slices.
 
 A trait object represents some type that implements the traits it specifies.
-The exact original type is *erased* in favour of runtime reflection
+The exact original type is *erased* in favor of runtime reflection
 with a vtable containing all the information necessary to use the type.
 This is the information that completes a trait object: a pointer to its vtable.
 
@@ -128,7 +128,7 @@ But neither of these tricks work today, so all Void types get you is
 the ability to be confident that certain situations are statically impossible.
 
 One final subtle detail about empty types is that raw pointers to them are
-actually valid to construct, but dereferencing them is Undefined Behaviour
+actually valid to construct, but dereferencing them is Undefined Behavior
 because that doesn't actually make sense. That is, you could model C's `void *`
 type with `*const Void`, but this doesn't necessarily gain anything over using
 e.g. `*const ()`, which *is* safe to randomly dereference.
index 445349b406593681f90e40bd4f24e514a0a50487..1f72a4c17247057e92ce65e1512cdafda3d87004 100644 (file)
@@ -90,7 +90,7 @@ let mut vec = vec![Box::new(0); 4];
 println!("{}", vec[0]);
 ```
 
-This is pretty clearly Not Good. Unfortunately, we're kind've stuck between a
+This is pretty clearly Not Good. Unfortunately, we're kind of stuck between a
 rock and a hard place: maintaining consistent state at every step has an
 enormous cost (and would negate any benefits of the API). Failing to maintain
 consistent state gives us Undefined Behavior in safe code (making the API
@@ -248,4 +248,4 @@ let mut data = Box::new(0);
 ```
 
 Dang. Here the destructor running was pretty fundamental to the API, and it had
-to be scrapped in favour of a completely different design.
+to be scrapped in favor of a completely different design.
index 52582e8750b4690daa82520ba8a3f3066bda496d..978d0518729ea5705e37c19834a41b6337fb0e42 100644 (file)
@@ -26,7 +26,7 @@ do some really crazy unsafe things.
 
 Safe Rust is the *true* Rust programming language. If all you do is write Safe
 Rust, you will never have to worry about type-safety or memory-safety. You will
-never endure a null or dangling pointer, or any of that Undefined Behaviour
+never endure a null or dangling pointer, or any of that Undefined Behavior
 nonsense.
 
 *That's totally awesome.*
@@ -52,11 +52,11 @@ The only things that are different in Unsafe Rust are that you can:
 * Mutate statics
 
 That's it. The reason these operations are relegated to Unsafe is that misusing
-any of these things will cause the ever dreaded Undefined Behaviour. Invoking
-Undefined Behaviour gives the compiler full rights to do arbitrarily bad things
-to your program. You definitely *should not* invoke Undefined Behaviour.
+any of these things will cause the ever dreaded Undefined Behavior. Invoking
+Undefined Behavior gives the compiler full rights to do arbitrarily bad things
+to your program. You definitely *should not* invoke Undefined Behavior.
 
-Unlike C, Undefined Behaviour is pretty limited in scope in Rust. All the core
+Unlike C, Undefined Behavior is pretty limited in scope in Rust. All the core
 language cares about is preventing the following things:
 
 * Dereferencing null or dangling pointers
@@ -71,9 +71,9 @@ language cares about is preventing the following things:
 * Unwinding into another language
 * Causing a [data race][race]
 
-That's it. That's all the causes of Undefined Behaviour baked into Rust. Of
+That's it. That's all the causes of Undefined Behavior baked into Rust. Of
 course, unsafe functions and traits are free to declare arbitrary other
-constraints that a program must maintain to avoid Undefined Behaviour. However,
+constraints that a program must maintain to avoid Undefined Behavior. However,
 generally violations of these constraints will just transitively lead to one of
 the above problems. Some additional constraints may also derive from compiler
 intrinsics that make special assumptions about how code can be optimized.
index 3b47502ebfe790a9f6ce55454eef864bb6591fd2..f0732cf26562cf21459a5fc8bcffa574fc5d8386 100644 (file)
@@ -6,7 +6,7 @@ Safe Rust guarantees an absence of data races, which are defined as:
 * one of them is a write
 * one of them is unsynchronized
 
-A data race has Undefined Behaviour, and is therefore impossible to perform
+A data race has Undefined Behavior, and is therefore impossible to perform
 in Safe Rust. Data races are *mostly* prevented through rust's ownership system:
 it's impossible to alias a mutable reference, so it's impossible to perform a
 data race. Interior mutability makes this more complicated, which is largely why
@@ -53,7 +53,7 @@ thread::spawn(move || {
 // bounds checked, and there's no chance of the value getting changed
 // in the middle. However our program may panic if the thread we spawned
 // managed to increment before this ran. A race condition because correct
-// program execution (panicing is rarely correct) depends on order of
+// program execution (panicking is rarely correct) depends on order of
 // thread execution.
 println!("{}", data[idx.load(Ordering::SeqCst)]);
 ```
index 3cb02d31b175f5b526cefaea78c0413783fc9a5e..f5d7023fad5de366e58844e0c5b579276f22baeb 100644 (file)
@@ -41,7 +41,7 @@ Some examples of unsafe functions:
 
 * `slice::get_unchecked` will perform unchecked indexing, allowing memory
   safety to be freely violated.
-* `ptr::offset` is an intrinsic that invokes Undefined Behaviour if it is
+* `ptr::offset` is an intrinsic that invokes Undefined Behavior if it is
   not "in bounds" as defined by LLVM.
 * `mem::transmute` reinterprets some value as having the given type,
   bypassing type safety in arbitrary ways. (see [conversions] for details)
@@ -59,9 +59,9 @@ As of Rust 1.0 there are exactly two unsafe traits:
 The need for unsafe traits boils down to the fundamental property of safe code:
 
 **No matter how completely awful Safe code is, it can't cause Undefined
-Behaviour.**
+Behavior.**
 
-This means that Unsafe Rust, **the royal vanguard of Undefined Behaviour**, has to be
+This means that Unsafe Rust, **the royal vanguard of Undefined Behavior**, has to be
 *super paranoid* about generic safe code. To be clear, Unsafe Rust is totally free to trust
 specific safe code. Anything else would degenerate into infinite spirals of
 paranoid despair. In particular it's generally regarded as ok to trust the standard library
index 9ab60d03fca7e41a6b1555f67683f207a8ed899b..134e47f18dcf0ccebf041854e4fa1af54460b1aa 100644 (file)
@@ -15,7 +15,7 @@ implement, and other unsafe code can assume that they are correctly
 implemented. Since they're *marker traits* (they have no associated items like
 methods), correctly implemented simply means that they have the intrinsic
 properties an implementor should have. Incorrectly implementing Send or Sync can
-cause Undefined Behaviour.
+cause Undefined Behavior.
 
 Send and Sync are also automatically derived traits. This means that, unlike
 every other trait, if a type is composed entirely of Send or Sync types, then it
index 2b34ad0a9fad164baf630f7bde97df6bbd1e84b1..f1478b7f668d33e67cd035d0e557d1d991a92431 100644 (file)
@@ -8,7 +8,7 @@ horribly unsafe thing you can do in Rust. The railguards here are dental floss.
 
 `mem::transmute<T, U>` takes a value of type `T` and reinterprets it to have
 type `U`. The only restriction is that the `T` and `U` are verified to have the
-same size. The ways to cause Undefined Behaviour with this are mind boggling.
+same size. The ways to cause Undefined Behavior with this are mind boggling.
 
 * First and foremost, creating an instance of *any* type with an invalid state
   is going to cause arbitrary chaos that can't really be predicted.
@@ -26,7 +26,7 @@ same size. The ways to cause Undefined Behaviour with this are mind boggling.
 `mem::transmute_copy<T, U>` somehow manages to be *even more* wildly unsafe than
 this. It copies `size_of<U>` bytes out of an `&T` and interprets them as a `U`.
 The size check that `mem::transmute` has is gone (as it may be valid to copy
-out a prefix), though it is Undefined Behaviour for `U` to be larger than `T`.
+out a prefix), though it is Undefined Behavior for `U` to be larger than `T`.
 
 Also of course you can get most of the functionality of these functions using
 pointer casts.
index b540ab4ed5d999d5c70c972fc207bd3df7c76415..2c5ba79a5078f1820daba439f613085725df0896 100644 (file)
@@ -2,7 +2,7 @@
 
 Unsafe code can often end up producing references or lifetimes out of thin air.
 Such lifetimes come into the world as *unbounded*. The most common source of this
-is derefencing a raw pointer, which produces a reference with an unbounded lifetime.
+is dereferencing a raw pointer, which produces a reference with an unbounded lifetime.
 Such a lifetime becomes as big as context demands. This is in fact more powerful
 than simply becoming `'static`, because for instance `&'static &'a T`
 will fail to typecheck, but the unbound lifetime will perfectly mold into
@@ -10,7 +10,7 @@ will fail to typecheck, but the unbound lifetime will perfectly mold into
 lifetime can be regarded as `'static`.
 
 Almost no reference is `'static`, so this is probably wrong. `transmute` and
-`transmute_copy` are the two other primary offenders. One should endeavour to
+`transmute_copy` are the two other primary offenders. One should endeavor to
 bound an unbounded lifetime as quick as possible, especially across function
 boundaries.
 
index 5ae1818dc630690de2a99a811c7c950f3c03460c..c72ed8a76329982b2582202dbf4d4d1c5b83771f 100644 (file)
@@ -38,7 +38,7 @@ dropping the old value: `write`, `copy`, and `copy_nonoverlapping`.
   (this is equivalent to memcpy -- note that the argument order is reversed!)
 
 It should go without saying that these functions, if misused, will cause serious
-havoc or just straight up Undefined Behaviour. The only things that these
+havoc or just straight up Undefined Behavior. The only things that these
 functions *themselves* require is that the locations you want to read and write
 are allocated. However the ways writing arbitrary bits to arbitrary
 locations of memory can break things are basically uncountable!
index 915ea8602918e6133e419b041f5128eb9b620b17..05615d89bec77a530522a4e227bb0ea5309d92ee 100644 (file)
@@ -4,7 +4,7 @@ All runtime-allocated memory in a Rust program begins its life as
 *uninitialized*. In this state the value of the memory is an indeterminate pile
 of bits that may or may not even reflect a valid state for the type that is
 supposed to inhabit that location of memory. Attempting to interpret this memory
-as a value of *any* type will cause Undefined Behaviour. Do Not Do This.
+as a value of *any* type will cause Undefined Behavior. Do Not Do This.
 
 Rust provides mechanisms to work with uninitialized memory in checked (safe) and
-unchecked (unsafe) ways.
\ No newline at end of file
+unchecked (unsafe) ways.
index 3ad95dde39deda47fc61395384af3915a6221097..e81f06b83b2496d61b7238a15758e4c8f240b8ce 100644 (file)
@@ -42,7 +42,7 @@ should only panic for programming errors or *extreme* problems.
 
 Rust's unwinding strategy is not specified to be fundamentally compatible
 with any other language's unwinding. As such, unwinding into Rust from another
-language, or unwinding into another language from Rust is Undefined Behaviour.
+language, or unwinding into another language from Rust is Undefined Behavior.
 You must *absolutely* catch any panics at the FFI boundary! What you do at that
 point is up to you, but *something* must be done. If you fail to do this,
 at best, your application will crash and burn. At worst, your application *won't*
index 3df63d5249c55efbe4fd3b2724e5dd208d5c3e18..7ca369da0b886be266de71952bc08704f4bb6a49 100644 (file)
@@ -93,7 +93,7 @@ pub struct Vec<T> {
 If you don't care about the null-pointer optimization, then you can use the
 stable code. However we will be designing the rest of the code around enabling
 the optimization. In particular, `Unique::new` is unsafe to call, because
-putting `null` inside of it is Undefined Behaviour. Our stable Unique doesn't
+putting `null` inside of it is Undefined Behavior. Our stable Unique doesn't
 need `new` to be unsafe because it doesn't make any interesting guarantees about
 its contents.
 
index b518e8aa48ffb1beb82b0b796cce45d60e6192f3..5e747a8c71d41bd38daf0377bbe9a41df51d0d59 100644 (file)
@@ -34,7 +34,7 @@ Easy! How about `pop`? Although this time the index we want to access is
 initialized, Rust won't just let us dereference the location of memory to move
 the value out, because that would leave the memory uninitialized! For this we
 need `ptr::read`, which just copies out the bits from the target address and
-intrprets it as a value of type T. This will leave the memory at this address
+interprets it as a value of type T. This will leave the memory at this address
 logically uninitialized, even though there is in fact a perfectly good instance
 of T there.
 
index 9b1abf383f7175003f2997cda1d11713355e5669..fb337a891a8d42ddb50ac5ed224d931b2fee71ae 100644 (file)
@@ -1,6 +1,6 @@
 % Handling Zero-Sized Types
 
-It's time. We're going to fight the spectre that is zero-sized types. Safe Rust
+It's time. We're going to fight the specter that is zero-sized types. Safe Rust
 *never* needs to care about this, but Vec is very intensive on raw pointers and
 raw allocations, which are exactly the two things that care about
 zero-sized types. We need to be careful of two things:
index 9ce191ee5897f1b2567294b744a9cd03560c910a..a9e12833906db57caaf8d9bd3cfe902e001eed9a 100644 (file)
@@ -419,10 +419,13 @@ The two values of the boolean type are written `true` and `false`.
 ### Symbols
 
 Symbols are a general class of printable [tokens](#tokens) that play structural
-roles in a variety of grammar productions. They are cataloged here for
-completeness as the set of remaining miscellaneous printable tokens that do not
+roles in a variety of grammar productions. They are a
+set of remaining miscellaneous printable tokens that do not
 otherwise appear as [unary operators](#unary-operator-expressions), [binary
 operators](#binary-operator-expressions), or [keywords][keywords].
+They are catalogued in [the Symbols section][symbols] of the Grammar document.
+
+[symbols]: grammar.html#symbols
 
 
 ## Paths
@@ -1073,7 +1076,7 @@ let p: Point = (41, 68);
 
 ### Structs
 
-A _structure_ is a nominal [structure type](#structure-types) defined with the
+A _struct_ is a nominal [struct type](#struct-types) defined with the
 keyword `struct`.
 
 An example of a `struct` item and its use:
@@ -1084,7 +1087,7 @@ let p = Point {x: 10, y: 11};
 let px: i32 = p.x;
 ```
 
-A _tuple structure_ is a nominal [tuple type](#tuple-types), also defined with
+A _tuple struct_ is a nominal [tuple type](#tuple-types), also defined with
 the keyword `struct`. For example:
 
 ```
@@ -1093,8 +1096,8 @@ let p = Point(10, 11);
 let px: i32 = match p { Point(x, _) => x };
 ```
 
-A _unit-like struct_ is a structure without any fields, defined by leaving off
-the list of fields entirely. Such a structure implicitly defines a constant of
+A _unit-like struct_ is a struct without any fields, defined by leaving off
+the list of fields entirely. Such a struct implicitly defines a constant of
 its type with the same name. For example:
 
 ```
@@ -1112,7 +1115,7 @@ const Cookie: Cookie = Cookie {};
 let c = [Cookie, Cookie {}, Cookie, Cookie {}];
 ```
 
-The precise memory layout of a structure is not specified. One can specify a
+The precise memory layout of a struct is not specified. One can specify a
 particular layout using the [`repr` attribute](#ffi-attributes).
 
 ### Enumerations
@@ -1435,11 +1438,11 @@ struct Foo;
 
 trait Shape { fn area(&self) -> f64; }
 trait Circle : Shape { fn radius(&self) -> f64; }
-impl Shape for Foo {
-    fn area(&self) -> f64 {
-        0.0
-    }
-}
+impl Shape for Foo {
+    fn area(&self) -> f64 {
+        0.0
+    }
+}
 impl Circle for Foo {
     fn radius(&self) -> f64 {
         println!("calling area: {}", self.area());
@@ -2357,7 +2360,7 @@ The currently implemented features of the reference compiler are:
                               terms of encapsulation).
 * - `default_type_parameter_fallback` - Allows type parameter defaults to
                                         influence type inference.
-* - `braced_empty_structs` - Allows use of empty structs with braces.
+* - `braced_empty_structs` - Allows use of empty structs and enum variants with braces.
 
 If a feature is promoted to a language feature, then all existing programs will
 start to receive compilation warnings about `#![feature]` directives which enabled
@@ -2401,7 +2404,7 @@ items.
 
 An _item declaration statement_ has a syntactic form identical to an
 [item](#items) declaration within a module. Declaring an item &mdash; a
-function, enumeration, structure, type, static, trait, implementation or module
+function, enumeration, struct, type, static, trait, implementation or module
 &mdash; locally within a statement block is simply a way of restricting its
 scope to a narrow region containing all of its uses; it is otherwise identical
 in meaning to declaring the item outside the statement block.
@@ -2546,26 +2549,26 @@ comma:
 (0); // zero in parentheses
 ```
 
-### Structure expressions
+### Struct expressions
 
-There are several forms of structure expressions. A _structure expression_
-consists of the [path](#paths) of a [structure item](#structs), followed by
+There are several forms of struct expressions. A _struct expression_
+consists of the [path](#paths) of a [struct item](#structs), followed by
 a brace-enclosed list of one or more comma-separated name-value pairs,
-providing the field values of a new instance of the structure. A field name
+providing the field values of a new instance of the struct. A field name
 can be any identifier, and is separated from its value expression by a colon.
-The location denoted by a structure field is mutable if and only if the
-enclosing structure is mutable.
+The location denoted by a struct field is mutable if and only if the
+enclosing struct is mutable.
 
-A _tuple structure expression_ consists of the [path](#paths) of a [structure
+A _tuple struct expression_ consists of the [path](#paths) of a [struct
 item](#structs), followed by a parenthesized list of one or more
-comma-separated expressions (in other words, the path of a structure item
-followed by a tuple expression). The structure item must be a tuple structure
+comma-separated expressions (in other words, the path of a struct item
+followed by a tuple expression). The struct item must be a tuple struct
 item.
 
-A _unit-like structure expression_ consists only of the [path](#paths) of a
-[structure item](#structs).
+A _unit-like struct expression_ consists only of the [path](#paths) of a
+[struct item](#structs).
 
-The following are examples of structure expressions:
+The following are examples of struct expressions:
 
 ```
 # struct Point { x: f64, y: f64 }
@@ -2578,14 +2581,14 @@ let u = game::User {name: "Joe", age: 35, score: 100_000};
 some_fn::<Cookie>(Cookie);
 ```
 
-A structure expression forms a new value of the named structure type. Note
-that for a given *unit-like* structure type, this will always be the same
+A struct expression forms a new value of the named struct type. Note
+that for a given *unit-like* struct type, this will always be the same
 value.
 
-A structure expression can terminate with the syntax `..` followed by an
+A struct expression can terminate with the syntax `..` followed by an
 expression to denote a functional update. The expression following `..` (the
-base) must have the same structure type as the new structure type being formed.
-The entire expression denotes the result of constructing a new structure (with
+base) must have the same struct type as the new struct type being formed.
+The entire expression denotes the result of constructing a new struct (with
 the same type as the base expression) with the given values for the fields that
 were explicitly specified and the values in the base expression for all other
 fields.
@@ -2631,7 +2634,7 @@ the left-hand-side expression is an indirect [trait object](#trait-objects).
 A _field expression_ consists of an expression followed by a single dot and an
 identifier, when not immediately followed by a parenthesized expression-list
 (the latter is a [method call expression](#method-call-expressions)). A field
-expression denotes a field of a [structure](#structure-types).
+expression denotes a field of a [struct](#struct-types).
 
 ```{.ignore .field}
 mystruct.myfield;
@@ -3350,17 +3353,17 @@ As you can see, the `vec!` macro allows you to create a `Vec<T>` easily. The
 All in-bounds elements of arrays and slices are always initialized, and access
 to an array or slice is always bounds-checked.
 
-### Structure types
+### Struct types
 
 A `struct` *type* is a heterogeneous product of other types, called the
 *fields* of the type.[^structtype]
 
 [^structtype]: `struct` types are analogous to `struct` types in C,
     the *record* types of the ML family,
-    or the *structure* types of the Lisp family.
+    or the *struct* types of the Lisp family.
 
 New instances of a `struct` can be constructed with a [struct
-expression](#structure-expressions).
+expression](#struct-expressions).
 
 The memory layout of a `struct` is undefined by default to allow for compiler
 optimizations like field reordering, but it can be fixed with the
@@ -3370,14 +3373,14 @@ have the same memory layout.
 
 The fields of a `struct` may be qualified by [visibility
 modifiers](#visibility-and-privacy), to allow access to data in a
-structure outside a module.
+struct outside a module.
 
-A _tuple struct_ type is just like a structure type, except that the fields are
+A _tuple struct_ type is just like a struct type, except that the fields are
 anonymous.
 
-A _unit-like struct_ type is like a structure type, except that it has no
-fields. The one value constructed by the associated [structure
-expression](#structure-expressions) is the only value that inhabits such a
+A _unit-like struct_ type is like a struct type, except that it has no
+fields. The one value constructed by the associated [struct
+expression](#struct-expressions) is the only value that inhabits such a
 type.
 
 ### Enumerated types
@@ -3404,7 +3407,7 @@ named reference to an [`enum` item](#enumerations).
 ### Recursive types
 
 Nominal types &mdash; [enumerations](#enumerated-types) and
-[structs](#structure-types) &mdash; may be recursive. That is, each `enum`
+[structs](#struct-types) &mdash; may be recursive. That is, each `enum`
 constructor or `struct` field may refer, directly or indirectly, to the
 enclosing `enum` or `struct` type itself. Such recursion has restrictions:
 
@@ -3706,7 +3709,7 @@ repeated sub-expression is a coercion site for coercion to type `U`.
 Each sub-expression is a coercion site to the respective type, e.g. the
 zeroth sub-expression is a coercion site to type `U_0`.
 
-* Parenthesised sub-expressions (`(e)`): if the expression has type `U`, then
+* Parenthesized sub-expressions (`(e)`): if the expression has type `U`, then
 the sub-expression is a coercion site to `U`.
 
 * Blocks: if a block has type `U`, then the last expression in the block (if
@@ -4072,7 +4075,7 @@ that have since been removed):
 
 * SML, OCaml: algebraic data types, pattern matching, type inference,
   semicolon statement separation
-* C++: references, RAII, smart pointers, move semantics, monomorphisation,
+* C++: references, RAII, smart pointers, move semantics, monomorphization,
   memory model
 * ML Kit, Cyclone: region based memory management
 * Haskell (GHC): typeclasses, type families
index 41bc08f229e7c9f65f5120d82507ca216da21c8e..508ede6c4a0ac5b768022f5b746f97f7570912d4 100644 (file)
@@ -48,7 +48,3 @@
 * [Testing](testing/README.md)
     * [Unit testing](testing/unit.md)
 * [FFI, platform-specific code](platform.md)
-* [APIs for a changing Rust](changing/README.md)
-    * [Pre-1.0 changes](changing/pre-1-0.md)
-    * [Post-1.0 changes](changing/post-1-0.md)
-    * [Timing unclear](changing/unclear.md)
diff --git a/src/doc/style/changing/README.md b/src/doc/style/changing/README.md
deleted file mode 100644 (file)
index 38e76f6..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-% API design for a changing Rust
-
-A number of planned Rust features will drastically affect the API design
-story. This section collects some of the biggest features with concrete examples
-of how the API will change.
diff --git a/src/doc/style/changing/post-1-0.md b/src/doc/style/changing/post-1-0.md
deleted file mode 100644 (file)
index 7ac1c83..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-% Post-1.0 changes
-
-### Higher-kinded types
-
-* A trait encompassing both `Iterable<T>` for some fixed `T` and
-  `FromIterator<U>` for _all_ `U` (where HKT comes in).  The train
-  could provide e.g. a default `map` method producing the same kind of
-  the container, but with a new type parameter.
-
-* **Monadic-generic programming**? Can we add this without deprecating
-  huge swaths of the API (including `Option::map`, `option::collect`,
-  `result::collect`, `try!` etc.
diff --git a/src/doc/style/changing/pre-1-0.md b/src/doc/style/changing/pre-1-0.md
deleted file mode 100644 (file)
index adadfe3..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-% Pre-1.0 changes
-
-### `std` facade
-
-We should revisit some APIs in `libstd` now that the facade effort is complete.
-
-For example, the treatment of environment variables in the new
-`Command` API is waiting on access to hashtables before being
-approved.
-
-### Trait reform
-
-Potential for standard conversion traits (`to`, `into`, `as`).
-
-Probably many other opportunities here.
-
-### Unboxed closures
diff --git a/src/doc/style/changing/unclear.md b/src/doc/style/changing/unclear.md
deleted file mode 100644 (file)
index e4b8a98..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-% Changes with unclear timing
-
-### Associated items
-
-* Many traits that currently take type parameters should instead use associated
-  types; this will _drastically_ simplify signatures in some cases.
-
-* Associated constants would be useful in a few places, e.g. traits for
-  numerics, traits for paths.
-
-### Anonymous, unboxed return types (aka `impl Trait` types)
-
-* See https://github.com/rust-lang/rfcs/pull/105
-
-* Could affect API design in several places, e.g. the `Iterator` trait.
-
-### Default type parameters
-
-We are already using this in a few places (e.g. `HashMap`), but it's
-feature-gated.
-
-### Compile-time function evaluation (CTFE)
-
-https://github.com/mozilla/rust/issues/11621
-
-### Improved constant folding
-
-https://github.com/rust-lang/rust/issues/7834
index 23d8760f571f6cecca166e4d81d251e77169e335..c55b38b915b3d1d9e6241d324cee7fec6a003271 100644 (file)
@@ -17,12 +17,12 @@ Organize module headers as follows:
 Avoid using `#[path="..."]` directives; make the file system and
 module hierarchy match, instead.
 
-### Use the module hirearchy to organize APIs into coherent sections. [FIXME]
+### Use the module hierarchy to organize APIs into coherent sections. [FIXME]
 
 > **[FIXME]** Flesh this out with examples; explain what a "coherent
 > section" is with examples.
 >
-> The module hirearchy defines both the public and internal API of your module.
+> The module hierarchy defines both the public and internal API of your module.
 > Breaking related functionality into submodules makes it understandable to both
 > users and contributors to the module.
 
@@ -82,7 +82,7 @@ io/mod.rs
 ```
 
 While it is possible to define all of `io` within a single directory,
-mirroring the module hirearchy in the directory structure makes
+mirroring the module hierarchy in the directory structure makes
 submodules of `io::net` easier to find.
 
 ### Consider top-level definitions or reexports. [FIXME: needs RFC]
@@ -104,13 +104,13 @@ while
 [`TcpStream`](https://doc.rust-lang.org/std/io/net/tcp/struct.TcpStream.html)
 is defined in `io/net/tcp.rs` and reexported in the `io` module.
 
-### Use internal module hirearchies for organization. [FIXME: needs RFC]
+### Use internal module hierarchies for organization. [FIXME: needs RFC]
 
 > **[FIXME]**
 > - Referencing internal modules from the standard library is subject to
 >   becoming outdated.
 
-Internal module hirearchies (i.e., private submodules) may be used to
+Internal module hierarchies (i.e., private submodules) may be used to
 hide implementation details that are not part of the module's API.
 
 For example, in [`std::io`](https://doc.rust-lang.org/std/io/), `mod mem`
index 61f8db87cde8983fc068c154614f24fef95324e4..feedd3937fc9dcac67e804cff5ced6af966c177e 100644 (file)
@@ -5,7 +5,7 @@
 > **[FIXME]** We probably want to discourage this, at least when used in a way
 > that is publicly exposed.
 
-Traits that provide default implmentations for function can provide code reuse
+Traits that provide default implementations for function can provide code reuse
 across types. For example, a `print` method can be defined across multiple
 types as follows:
 
index d62a96f7308794cb3be5f7cdfcc1dd64b0bfcbaa..53afa0e905ac6eb226f439f4ed812fe7f236ebc0 100644 (file)
@@ -35,10 +35,12 @@ channel connecting two threads, we would want to be able to send some data
 down the channel and to the other thread. Therefore, we'd ensure that `Send` was
 implemented for that type.
 
-In the opposite way, if we were wrapping a library with FFI that isn't
+In the opposite way, if we were wrapping a library with [FFI][ffi] that isn't
 threadsafe, we wouldn't want to implement `Send`, and so the compiler will help
 us enforce that it can't leave the current thread.
 
+[ffi]: ffi.html
+
 ### `Sync`
 
 The second of these traits is called [`Sync`](../std/marker/trait.Sync.html).
index 5c4e6c0b9dc2aeb866da46123de1ed1542e6cba3..28702d95b60a7ab06fbdccf3b31ca14d6d0723b3 100644 (file)
@@ -13,7 +13,7 @@ Hoare in 1985.
 > dining room, furnished with a circular table, surrounded by five chairs, each
 > labelled by the name of the philosopher who was to sit in it. They sat
 > anticlockwise around the table. To the left of each philosopher there was
-> laid a golden fork, and in the centre stood a large bowl of spaghetti, which
+> laid a golden fork, and in the center stood a large bowl of spaghetti, which
 > was constantly replenished. A philosopher was expected to spend most of
 > their time thinking; but when they felt hungry, they went to the dining
 > room, sat down in their own chair, picked up their own fork on their left,
index e538a40415dfdd523c9a4b28db9ec0c44b773712..d839e1820920ae6b8faa6cbc19e0e5a1b59f68ee 100644 (file)
@@ -1898,7 +1898,7 @@ for pop in search(&data_file, &city) {
 
 In this piece of code, we take `file` (which has the type
 `Option<String>`), and convert it to a type that `search` can use, in
-this case, `&Option<AsRef<Path>>`. Do do this, we take a reference of
+this case, `&Option<AsRef<Path>>`. To do this, we take a reference of
 file, and map `Path::new` onto it. In this case, `as_ref()` converts
 the `Option<String>` into an `Option<&str>`, and from there, we can
 execute `Path::new` to the content of the optional, and return the
index 4872ed6a773472a8412e115fd4c1302dd2f7e5e8..faa922acb3de282805cb17f898d2c08f92f6d72d 100644 (file)
@@ -41,7 +41,7 @@ If a [pattern][patterns] matches successfully, it binds any appropriate parts of
 the value to the identifiers in the pattern, then evaluates the expression. If
 the pattern doesn’t match, nothing happens.
 
-If you’d rather to do something else when the pattern does not match, you can
+If you want to do something else when the pattern does not match, you can
 use `else`:
 
 ```rust
@@ -65,7 +65,7 @@ loop as long as a value matches a certain pattern. It turns code like this:
 loop {
     match option {
         Some(x) => println!("{}", x),
-        _ => break,
+        None => break,
     }
 }
 ```
index 6cd0d9f8352fcfab532e0e56ceb8b002f53fc14d..c444f9f2fe53d420e5cbae1bbb63007e2c51d965 100644 (file)
@@ -44,7 +44,7 @@ own iterator involves implementing the `Iterator` trait. While doing that is
 outside of the scope of this guide, Rust provides a number of useful iterators
 to accomplish various tasks. But first, a few notes about limitations of ranges.
 
-Ranges are very primitive, and we often can use better alternatives. Consider
+Ranges are very primitive, and we often can use better alternatives. Consider the
 following Rust anti-pattern: using ranges to emulate a C-style `for` loop. Let’s
 suppose you needed to iterate over the contents of a vector. You may be tempted
 to write this:
@@ -101,10 +101,10 @@ So, now that we've established that ranges are often not what you want, let's
 talk about what you do want instead.
 
 There are three broad classes of things that are relevant here: iterators,
-*iterator adapters*, and *consumers*. Here's some definitions:
+*iterator adaptors*, and *consumers*. Here's some definitions:
 
 * *iterators* give you a sequence of values.
-* *iterator adapters* operate on an iterator, producing a new iterator with a
+* *iterator adaptors* operate on an iterator, producing a new iterator with a
   different output sequence.
 * *consumers* operate on an iterator, producing some final set of values.
 
@@ -246,12 +246,12 @@ for num in nums.iter() {
 These two basic iterators should serve you well. There are some more
 advanced iterators, including ones that are infinite.
 
-That's enough about iterators. Iterator adapters are the last concept
+That's enough about iterators. Iterator adaptors are the last concept
 we need to talk about with regards to iterators. Let's get to it!
 
-## Iterator adapters
+## Iterator adaptors
 
-*Iterator adapters* take an iterator and modify it somehow, producing
+*Iterator adaptors* take an iterator and modify it somehow, producing
 a new iterator. The simplest one is called `map`:
 
 ```rust,ignore
@@ -280,7 +280,7 @@ doesn't print any numbers:
 If you are trying to execute a closure on an iterator for its side effects,
 just use `for` instead.
 
-There are tons of interesting iterator adapters. `take(n)` will return an
+There are tons of interesting iterator adaptors. `take(n)` will return an
 iterator over the next `n` elements of the original iterator. Let's try it out
 with an infinite iterator:
 
@@ -329,7 +329,7 @@ a few times, and then consume the result. Check it out:
 
 This will give you a vector containing `6`, `12`, `18`, `24`, and `30`.
 
-This is just a small taste of what iterators, iterator adapters, and consumers
+This is just a small taste of what iterators, iterator adaptors, and consumers
 can help you with. There are a number of really useful iterators, and you can
 write your own as well. Iterators provide a safe, efficient way to manipulate
 all kinds of lists. They're a little unusual at first, but if you play with
index 23569dd1b917e776461f8473aa01f55bb72a1e6d..13265ab1eba12f1444e7382865021ddf027d9fdf 100644 (file)
@@ -1,6 +1,6 @@
 % Lifetimes
 
-This guide is one of three presenting Rust’s ownership system. This is one of
+This guide is three of three presenting Rust’s ownership system. This is one of
 Rust’s most unique and compelling features, with which Rust developers should
 become quite acquainted. Ownership is how Rust achieves its largest goal,
 memory safety. There are a few distinct concepts, each with its own chapter:
@@ -74,7 +74,7 @@ associated with it, but the compiler lets you elide (i.e. omit, see
 ["Lifetime Elision"][lifetime-elision] below) them in common cases.
 Before we get to that, though, let’s break the explicit example down:
 
-[lifetime-elision]: #user-content-lifetime-elision
+[lifetime-elision]: #lifetime-elision
 
 ```rust,ignore
 fn bar<'a>(...)
index 8f39f0a122cd3be66bd96b87842c80e62b58a093..3027f10aca59ea3622aac56c5c23a86fe368b090 100644 (file)
@@ -1,6 +1,6 @@
 % References and Borrowing
 
-This guide is one of three presenting Rust’s ownership system. This is one of
+This guide is two of three presenting Rust’s ownership system. This is one of
 Rust’s most unique and compelling features, with which Rust developers should
 become quite acquainted. Ownership is how Rust achieves its largest goal,
 memory safety. There are a few distinct concepts, each with its own
index 47e1df37dffb71fc28a8e14454c0290915067a02..5c0bde02f960591f98fb3fe7e7f3dacf827acd93 100644 (file)
@@ -108,7 +108,7 @@ fn process() {
     let handles: Vec<_> = (0..10).map(|_| {
         thread::spawn(|| {
             let mut x = 0;
-            for _ in (0..5_000_000) {
+            for _ in 0..5_000_000 {
                 x += 1
             }
             x
index fd8086efde0ad88bc75ac5809a6be4646024c354..7e03bb72cad598e5b7972e850ba33a8f393d131b 100644 (file)
@@ -25,7 +25,7 @@
 * `pub`: denotes public visibility in `struct` fields, `impl` blocks, and modules.  See [Crates and Modules (Exporting a Public Interface)].
 * `ref`: by-reference binding.  See [Patterns (`ref` and `ref mut`)].
 * `return`: return from function.  See [Functions (Early Returns)].
-* `Self`: implementer type alias.  See [Traits].
+* `Self`: implementor type alias.  See [Traits].
 * `self`: method subject.  See [Method Syntax (Method Calls)].
 * `static`: global variable.  See [`const` and `static` (`static`)].
 * `struct`: structure definition.  See [Structs].
@@ -68,7 +68,7 @@
 * `/` (`expr / expr`): arithmetic division.  Overloadable (`Div`).
 * `/=` (`var /= expr`): arithmetic division & assignment.
 * `:` (`pat: type`, `ident: type`): constraints.  See [Variable Bindings], [Functions], [Structs], [Traits].
-* `:` (`ident: expr`): struct field initialiser.  See [Structs].
+* `:` (`ident: expr`): struct field initializer.  See [Structs].
 * `:` (`'a: loop {…}`): loop label.  See [Loops (Loops Labels)].
 * `;`: statement and item terminator.
 * `;` (`[…; len]`): part of fixed-size array syntax.  See [Primitive Types (Arrays)].
 <!-- Various things involving parens and tuples -->
 
 * `()`: empty tuple (*a.k.a.* unit), both literal and type.
-* `(expr)`: parenthesised expression.
+* `(expr)`: parenthesized expression.
 * `(expr,)`: single-element tuple expression.  See [Primitive Types (Tuples)].
 * `(type,)`: single-element tuple type.  See [Primitive Types (Tuples)].
 * `(expr, …)`: tuple expression.  See [Primitive Types (Tuples)].
 * `(type, …)`: tuple type.  See [Primitive Types (Tuples)].
-* `expr(expr, …)`: function call expression.  Also used to initialise tuple `struct`s and tuple `enum` variants.  See [Functions].
+* `expr(expr, …)`: function call expression.  Also used to initialize tuple `struct`s and tuple `enum` variants.  See [Functions].
 * `ident!(…)`, `ident!{…}`, `ident![…]`: macro invocation.  See [Macros].
 * `expr.0`, `expr.1`, …: tuple indexing.  See [Primitive Types (Tuple Indexing)].
 
index 452dc13c6968dbb3fbf3db2e84b2623fe5ff0a6e..b278ea0127686a3f687fa792134e4ab496f04c88 100644 (file)
@@ -82,7 +82,7 @@ fn it_works() {
 ```
 
 `assert!` is a macro provided by Rust which takes one argument: if the argument
-is `true`, nothing happens. If the argument is false, it `panic!`s. Let's run
+is `true`, nothing happens. If the argument is `false`, it `panic!`s. Let's run
 our tests again:
 
 ```bash
@@ -289,7 +289,7 @@ running 0 tests
 test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured
 ```
 
-The `--ignored` argument is an argument to the test binary, and not to cargo,
+The `--ignored` argument is an argument to the test binary, and not to Cargo,
 which is why the command is `cargo test -- --ignored`.
 
 # The `tests` module
@@ -367,7 +367,7 @@ It works!
 The current convention is to use the `tests` module to hold your "unit-style"
 tests. Anything that just tests one small bit of functionality makes sense to
 go here. But what about "integration-style" tests instead? For that, we have
-the `tests` directory
+the `tests` directory.
 
 # The `tests` directory
 
index 3521c970e72c8f3b76f35835504b14dcb7b1291f..f3a5d1dd886c82b86538372b525f35da1c8ebff7 100644 (file)
@@ -221,7 +221,7 @@ Could not compile `hello`.
 To learn more, run the command again with --verbose.
 ```
 
-Additionaly, variable bindings can be shadowed. This means that a later
+Additionally, variable bindings can be shadowed. This means that a later
 variable binding with the same name as another binding, that's currently in
 scope, will override the previous binding.
 
index c5c58bb49ac361f34df30451b9badd02450acab9..e74652d85d788accd12f4e09660da3a9ea33cad8 100644 (file)
@@ -17,4 +17,6 @@
 #[cfg(rustc)]
 extern crate rustc_driver as this;
 
-fn main() { this::main() }
+fn main() {
+    this::main()
+}
index cbb67014e276025f4e3e3eb1473cbf642ff8a67f..4b10b02f2d40725df318604d6cf1c0ba90daf28e 100644 (file)
@@ -34,10 +34,7 @@ fn load_all_errors(metadata_dir: &Path) -> Result<ErrorMetadataMap, Box<Error>>
         let path = try!(entry).path();
 
         let mut metadata_str = String::new();
-        try!(
-            File::open(&path).and_then(|mut f|
-            f.read_to_string(&mut metadata_str))
-        );
+        try!(File::open(&path).and_then(|mut f| f.read_to_string(&mut metadata_str)));
 
         let some_errors: ErrorMetadataMap = try!(json::decode(&metadata_str));
 
@@ -78,24 +75,23 @@ fn render_error_page(err_map: &ErrorMetadataMap, output_path: &Path) -> Result<(
         // Enclose each error in a div so they can be shown/hidden en masse.
         let desc_desc = match info.description {
             Some(_) => "error-described",
-            None => "error-undescribed"
+            None => "error-undescribed",
         };
         let use_desc = match info.use_site {
             Some(_) => "error-used",
-            None => "error-unused"
+            None => "error-unused",
         };
         try!(write!(&mut output_file, "<div class=\"{} {}\">", desc_desc, use_desc));
 
         // Error title (with self-link).
         try!(write!(&mut output_file,
-            "<h2 id=\"{0}\" class=\"section-header\"><a href=\"#{0}\">{0}</a></h2>\n",
-            err_code
-        ));
+                    "<h2 id=\"{0}\" class=\"section-header\"><a href=\"#{0}\">{0}</a></h2>\n",
+                    err_code));
 
         // Description rendered as markdown.
         match info.description {
             Some(ref desc) => try!(write!(&mut output_file, "{}", Markdown(desc))),
-            None => try!(write!(&mut output_file, "<p>No description.</p>\n"))
+            None => try!(write!(&mut output_file, "<p>No description.</p>\n")),
         }
 
         try!(write!(&mut output_file, "</div>\n"));
index 36989c2daad21807aef847f46ca4b4d45626a1ed..d8f10e6780f88b8dcfb982280c864509703f0bbe 100644 (file)
@@ -93,7 +93,7 @@
 ///
 /// # Examples
 ///
-/// In this example, a large vector of floats is shared between several threads.
+/// In this example, a large vector is shared between several threads.
 /// With simple pipes, without `Arc`, a copy would have to be made for each
 /// thread.
 ///
@@ -307,9 +307,7 @@ unsafe fn drop_slow(&mut self) {
 
         if self.inner().weak.fetch_sub(1, Release) == 1 {
             atomic::fence(Acquire);
-            deallocate(ptr as *mut u8,
-                       size_of_val(&*ptr),
-                       align_of_val(&*ptr))
+            deallocate(ptr as *mut u8, size_of_val(&*ptr), align_of_val(&*ptr))
         }
     }
 }
@@ -722,11 +720,7 @@ fn drop(&mut self) {
         // ref, which can only happen after the lock is released.
         if self.inner().weak.fetch_sub(1, Release) == 1 {
             atomic::fence(Acquire);
-            unsafe {
-                deallocate(ptr as *mut u8,
-                           size_of_val(&*ptr),
-                           align_of_val(&*ptr))
-            }
+            unsafe { deallocate(ptr as *mut u8, size_of_val(&*ptr), align_of_val(&*ptr)) }
         }
     }
 }
@@ -1152,5 +1146,7 @@ fn borrow(&self) -> &T {
 
 #[stable(since = "1.5.0", feature = "smart_ptr_as_ref")]
 impl<T: ?Sized> AsRef<T> for Arc<T> {
-    fn as_ref(&self) -> &T { &**self }
+    fn as_ref(&self) -> &T {
+        &**self
+    }
 }
index 629adf4649d38c8147650d97e58ab1a6959c7cf0..e85b7d2d4969fa6ee7ca8c8336289d0a9acb26aa 100644 (file)
@@ -161,7 +161,12 @@ fn make_place<T>() -> IntermediateBox<T> {
         p
     };
 
-    IntermediateBox { ptr: p, size: size, align: align, marker: marker::PhantomData }
+    IntermediateBox {
+        ptr: p,
+        size: size,
+        align: align,
+        marker: marker::PhantomData,
+    }
 }
 
 impl<T> BoxPlace<T> for IntermediateBox<T> {
@@ -538,7 +543,10 @@ impl<T: ?Sized+Unsize<U>, U: ?Sized> CoerceUnsized<Box<U>> for Box<T> {}
 #[stable(feature = "box_slice_clone", since = "1.3.0")]
 impl<T: Clone> Clone for Box<[T]> {
     fn clone(&self) -> Self {
-        let mut new = BoxBuilder { data: RawVec::with_capacity(self.len()), len: 0 };
+        let mut new = BoxBuilder {
+            data: RawVec::with_capacity(self.len()),
+            len: 0,
+        };
 
         let mut target = new.data.ptr();
 
@@ -597,10 +605,14 @@ fn borrow_mut(&mut self) -> &mut T {
 
 #[stable(since = "1.5.0", feature = "smart_ptr_as_ref")]
 impl<T: ?Sized> AsRef<T> for Box<T> {
-    fn as_ref(&self) -> &T { &**self }
+    fn as_ref(&self) -> &T {
+        &**self
+    }
 }
 
 #[stable(since = "1.5.0", feature = "smart_ptr_as_ref")]
 impl<T: ?Sized> AsMut<T> for Box<T> {
-    fn as_mut(&mut self) -> &mut T { &mut **self }
+    fn as_mut(&mut self) -> &mut T {
+        &mut **self
+    }
 }
index 49d37698154fd1bd14b4b9516ec711630fb7f5fc..996a590043a47c04b997bab097dfc0ee9cf02130 100644 (file)
@@ -65,7 +65,10 @@ pub fn new() -> Self {
             };
 
             // heap::EMPTY doubles as "unallocated" and "zero-sized allocation"
-            RawVec { ptr: Unique::new(heap::EMPTY as *mut T), cap: cap }
+            RawVec {
+                ptr: Unique::new(heap::EMPTY as *mut T),
+                cap: cap,
+            }
         }
     }
 
@@ -102,19 +105,25 @@ pub fn with_capacity(cap: usize) -> Self {
                 ptr
             };
 
-            RawVec { ptr: Unique::new(ptr as *mut _), cap: cap }
+            RawVec {
+                ptr: Unique::new(ptr as *mut _),
+                cap: cap,
+            }
         }
     }
 
     /// Reconstitutes a RawVec from a pointer and capacity.
     ///
-    /// # Undefined Behaviour
+    /// # Undefined Behavior
     ///
     /// The ptr must be allocated, and with the given capacity. The
     /// capacity cannot exceed `isize::MAX` (only a concern on 32-bit systems).
     /// If the ptr and capacity come from a RawVec, then this is guaranteed.
     pub unsafe fn from_raw_parts(ptr: *mut T, cap: usize) -> Self {
-        RawVec { ptr: Unique::new(ptr), cap: cap }
+        RawVec {
+            ptr: Unique::new(ptr),
+            cap: cap,
+        }
     }
 
     /// Converts a `Box<[T]>` into a `RawVec<T>`.
@@ -239,7 +248,7 @@ pub fn double(&mut self) {
     ///
     /// If `used_cap` exceeds `self.cap()`, this may fail to actually allocate
     /// the requested space. This is not really unsafe, but the unsafe
-    /// code *you* write that relies on the behaviour of this function may break.
+    /// code *you* write that relies on the behavior of this function may break.
     ///
     /// # Panics
     ///
@@ -293,12 +302,12 @@ pub fn reserve_exact(&mut self, used_cap: usize, needed_extra_cap: usize) {
     /// Ensures that the buffer contains at least enough space to hold
     /// `used_cap + needed_extra_cap` elements. If it doesn't already have
     /// enough capacity, will reallocate enough space plus comfortable slack
-    /// space to get amortized `O(1)` behaviour. Will limit this behaviour
+    /// space to get amortized `O(1)` behavior. Will limit this behavior
     /// if it would needlessly cause itself to panic.
     ///
     /// If `used_cap` exceeds `self.cap()`, this may fail to actually allocate
     /// the requested space. This is not really unsafe, but the unsafe
-    /// code *you* write that relies on the behaviour of this function may break.
+    /// code *you* write that relies on the behavior of this function may break.
     ///
     /// This is ideal for implementing a bulk-push operation like `extend`.
     ///
@@ -398,8 +407,7 @@ pub fn shrink_to_fit(&mut self, amount: usize) {
         }
 
         // This check is my waterloo; it's the only thing Vec wouldn't have to do.
-        assert!(self.cap >= amount,
-                "Tried to shrink to a larger capacity");
+        assert!(self.cap >= amount, "Tried to shrink to a larger capacity");
 
         if amount == 0 {
             mem::replace(self, RawVec::new());
@@ -422,7 +430,7 @@ pub fn shrink_to_fit(&mut self, amount: usize) {
 
     /// Converts the entire buffer into `Box<[T]>`.
     ///
-    /// While it is not *strictly* Undefined Behaviour to call
+    /// While it is not *strictly* Undefined Behavior to call
     /// this procedure while some of the RawVec is unintialized,
     /// it cetainly makes it trivial to trigger it.
     ///
index 06d03161ca1c5219b66c6f7e8eefde5c04278a26..4753bb2379ac52ace04b93dcafde8c5602e05afe 100644 (file)
@@ -467,9 +467,7 @@ fn drop(&mut self) {
                     self.dec_weak();
 
                     if self.weak() == 0 {
-                        deallocate(ptr as *mut u8,
-                                   size_of_val(&*ptr),
-                                   align_of_val(&*ptr))
+                        deallocate(ptr as *mut u8, size_of_val(&*ptr), align_of_val(&*ptr))
                     }
                 }
             }
@@ -788,9 +786,7 @@ fn drop(&mut self) {
                 // the weak count starts at 1, and will only go to zero if all
                 // the strong pointers have disappeared.
                 if self.weak() == 0 {
-                    deallocate(ptr as *mut u8,
-                               size_of_val(&*ptr),
-                               align_of_val(&*ptr))
+                    deallocate(ptr as *mut u8, size_of_val(&*ptr), align_of_val(&*ptr))
                 }
             }
         }
@@ -1121,5 +1117,7 @@ fn borrow(&self) -> &T {
 
 #[stable(since = "1.5.0", feature = "smart_ptr_as_ref")]
 impl<T: ?Sized> AsRef<T> for Rc<T> {
-    fn as_ref(&self) -> &T { &**self }
+    fn as_ref(&self) -> &T {
+        &**self
+    }
 }
index 80a831fd207757ebac725058c103bae2ee83ae4c..f46b12e80c56ada9cae738e5b6934bd2e4b4b85f 100644 (file)
@@ -43,8 +43,7 @@
 extern {
     fn je_mallocx(size: size_t, flags: c_int) -> *mut c_void;
     fn je_rallocx(ptr: *mut c_void, size: size_t, flags: c_int) -> *mut c_void;
-    fn je_xallocx(ptr: *mut c_void, size: size_t, extra: size_t,
-                  flags: c_int) -> size_t;
+    fn je_xallocx(ptr: *mut c_void, size: size_t, extra: size_t, flags: c_int) -> size_t;
     fn je_sdallocx(ptr: *mut c_void, size: size_t, flags: c_int);
     fn je_nallocx(size: size_t, flags: c_int) -> size_t;
 }
@@ -63,40 +62,52 @@ fn je_xallocx(ptr: *mut c_void, size: size_t, extra: size_t,
 const MIN_ALIGN: usize = 16;
 
 // MALLOCX_ALIGN(a) macro
-fn mallocx_align(a: usize) -> c_int { a.trailing_zeros() as c_int }
+fn mallocx_align(a: usize) -> c_int {
+    a.trailing_zeros() as c_int
+}
 
 fn align_to_flags(align: usize) -> c_int {
-    if align <= MIN_ALIGN { 0 } else { mallocx_align(align) }
+    if align <= MIN_ALIGN {
+        0
+    } else {
+        mallocx_align(align)
+    }
 }
 
 #[no_mangle]
-pub extern fn __rust_allocate(size: usize, align: usize) -> *mut u8 {
+pub extern "C" fn __rust_allocate(size: usize, align: usize) -> *mut u8 {
     let flags = align_to_flags(align);
     unsafe { je_mallocx(size as size_t, flags) as *mut u8 }
 }
 
 #[no_mangle]
-pub extern fn __rust_reallocate(ptr: *mut u8, _old_size: usize, size: usize,
-                                align: usize) -> *mut u8 {
+pub extern "C" fn __rust_reallocate(ptr: *mut u8,
+                                    _old_size: usize,
+                                    size: usize,
+                                    align: usize)
+                                    -> *mut u8 {
     let flags = align_to_flags(align);
     unsafe { je_rallocx(ptr as *mut c_void, size as size_t, flags) as *mut u8 }
 }
 
 #[no_mangle]
-pub extern fn __rust_reallocate_inplace(ptr: *mut u8, _old_size: usize,
-                                        size: usize, align: usize) -> usize {
+pub extern "C" fn __rust_reallocate_inplace(ptr: *mut u8,
+                                            _old_size: usize,
+                                            size: usize,
+                                            align: usize)
+                                            -> usize {
     let flags = align_to_flags(align);
     unsafe { je_xallocx(ptr as *mut c_void, size as size_t, 0, flags) as usize }
 }
 
 #[no_mangle]
-pub extern fn __rust_deallocate(ptr: *mut u8, old_size: usize, align: usize) {
+pub extern "C" fn __rust_deallocate(ptr: *mut u8, old_size: usize, align: usize) {
     let flags = align_to_flags(align);
     unsafe { je_sdallocx(ptr as *mut c_void, old_size as size_t, flags) }
 }
 
 #[no_mangle]
-pub extern fn __rust_usable_size(size: usize, align: usize) -> usize {
+pub extern "C" fn __rust_usable_size(size: usize, align: usize) -> usize {
     let flags = align_to_flags(align);
     unsafe { je_nallocx(size as size_t, flags) as usize }
 }
index aff4bea19e0f306636d3622df74bc1962bcc1648..c447dfbec4440b75995adc50880e75b75ac65d50 100644 (file)
 const MIN_ALIGN: usize = 16;
 
 #[no_mangle]
-pub extern fn __rust_allocate(size: usize, align: usize) -> *mut u8 {
+pub extern "C" fn __rust_allocate(size: usize, align: usize) -> *mut u8 {
     unsafe { imp::allocate(size, align) }
 }
 
 #[no_mangle]
-pub extern fn __rust_deallocate(ptr: *mut u8, old_size: usize, align: usize) {
+pub extern "C" fn __rust_deallocate(ptr: *mut u8, old_size: usize, align: usize) {
     unsafe { imp::deallocate(ptr, old_size, align) }
 }
 
 #[no_mangle]
-pub extern fn __rust_reallocate(ptr: *mut u8, old_size: usize, size: usize,
-                                align: usize) -> *mut u8 {
+pub extern "C" fn __rust_reallocate(ptr: *mut u8,
+                                    old_size: usize,
+                                    size: usize,
+                                    align: usize)
+                                    -> *mut u8 {
     unsafe { imp::reallocate(ptr, old_size, size, align) }
 }
 
 #[no_mangle]
-pub extern fn __rust_reallocate_inplace(ptr: *mut u8, old_size: usize,
-                                        size: usize, align: usize) -> usize {
+pub extern "C" fn __rust_reallocate_inplace(ptr: *mut u8,
+                                            old_size: usize,
+                                            size: usize,
+                                            align: usize)
+                                            -> usize {
     unsafe { imp::reallocate_inplace(ptr, old_size, size, align) }
 }
 
 #[no_mangle]
-pub extern fn __rust_usable_size(size: usize, align: usize) -> usize {
+pub extern "C" fn __rust_usable_size(size: usize, align: usize) -> usize {
     imp::usable_size(size, align)
 }
 
@@ -80,7 +86,8 @@ mod imp {
         #[cfg(not(target_os = "android"))]
         fn posix_memalign(memptr: *mut *mut libc::c_void,
                           align: libc::size_t,
-                          size: libc::size_t) -> libc::c_int;
+                          size: libc::size_t)
+                          -> libc::c_int;
     }
 
     pub unsafe fn allocate(size: usize, align: usize) -> *mut u8 {
@@ -94,9 +101,7 @@ unsafe fn more_aligned_malloc(size: usize, align: usize) -> *mut u8 {
             #[cfg(not(target_os = "android"))]
             unsafe fn more_aligned_malloc(size: usize, align: usize) -> *mut u8 {
                 let mut out = ptr::null_mut();
-                let ret = posix_memalign(&mut out,
-                                         align as libc::size_t,
-                                         size as libc::size_t);
+                let ret = posix_memalign(&mut out, align as libc::size_t, size as libc::size_t);
                 if ret != 0 {
                     ptr::null_mut()
                 } else {
@@ -107,8 +112,7 @@ unsafe fn more_aligned_malloc(size: usize, align: usize) -> *mut u8 {
         }
     }
 
-    pub unsafe fn reallocate(ptr: *mut u8, old_size: usize, size: usize,
-                             align: usize) -> *mut u8 {
+    pub unsafe fn reallocate(ptr: *mut u8, old_size: usize, size: usize, align: usize) -> *mut u8 {
         if align <= MIN_ALIGN {
             libc::realloc(ptr as *mut libc::c_void, size as libc::size_t) as *mut u8
         } else {
@@ -119,8 +123,11 @@ pub unsafe fn reallocate(ptr: *mut u8, old_size: usize, size: usize,
         }
     }
 
-    pub unsafe fn reallocate_inplace(_ptr: *mut u8, old_size: usize, _size: usize,
-                                     _align: usize) -> usize {
+    pub unsafe fn reallocate_inplace(_ptr: *mut u8,
+                                     old_size: usize,
+                                     _size: usize,
+                                     _align: usize)
+                                     -> usize {
         old_size
     }
 
@@ -141,8 +148,7 @@ mod imp {
     extern "system" {
         fn GetProcessHeap() -> HANDLE;
         fn HeapAlloc(hHeap: HANDLE, dwFlags: DWORD, dwBytes: SIZE_T) -> LPVOID;
-        fn HeapReAlloc(hHeap: HANDLE, dwFlags: DWORD, lpMem: LPVOID,
-                       dwBytes: SIZE_T) -> LPVOID;
+        fn HeapReAlloc(hHeap: HANDLE, dwFlags: DWORD, lpMem: LPVOID, dwBytes: SIZE_T) -> LPVOID;
         fn HeapFree(hHeap: HANDLE, dwFlags: DWORD, lpMem: LPVOID) -> BOOL;
     }
 
@@ -165,32 +171,45 @@ pub unsafe fn allocate(size: usize, align: usize) -> *mut u8 {
         if align <= MIN_ALIGN {
             HeapAlloc(GetProcessHeap(), 0, size as SIZE_T) as *mut u8
         } else {
-            let ptr = HeapAlloc(GetProcessHeap(), 0,
-                                (size + align) as SIZE_T) as *mut u8;
-            if ptr.is_null() { return ptr }
+            let ptr = HeapAlloc(GetProcessHeap(), 0, (size + align) as SIZE_T) as *mut u8;
+            if ptr.is_null() {
+                return ptr
+            }
             align_ptr(ptr, align)
         }
     }
 
-    pub unsafe fn reallocate(ptr: *mut u8, _old_size: usize, size: usize,
-                             align: usize) -> *mut u8 {
+    pub unsafe fn reallocate(ptr: *mut u8, _old_size: usize, size: usize, align: usize) -> *mut u8 {
         if align <= MIN_ALIGN {
             HeapReAlloc(GetProcessHeap(), 0, ptr as LPVOID, size as SIZE_T) as *mut u8
         } else {
             let header = get_header(ptr);
-            let new = HeapReAlloc(GetProcessHeap(), 0, header.0 as LPVOID,
+            let new = HeapReAlloc(GetProcessHeap(),
+                                  0,
+                                  header.0 as LPVOID,
                                   (size + align) as SIZE_T) as *mut u8;
-            if new.is_null() { return new }
+            if new.is_null() {
+                return new
+            }
             align_ptr(new, align)
         }
     }
 
-    pub unsafe fn reallocate_inplace(ptr: *mut u8, old_size: usize, size: usize,
-                                     align: usize) -> usize {
+    pub unsafe fn reallocate_inplace(ptr: *mut u8,
+                                     old_size: usize,
+                                     size: usize,
+                                     align: usize)
+                                     -> usize {
         if align <= MIN_ALIGN {
-            let new = HeapReAlloc(GetProcessHeap(), HEAP_REALLOC_IN_PLACE_ONLY,
-                                  ptr as LPVOID, size as SIZE_T) as *mut u8;
-            if new.is_null() { old_size } else { size }
+            let new = HeapReAlloc(GetProcessHeap(),
+                                  HEAP_REALLOC_IN_PLACE_ONLY,
+                                  ptr as LPVOID,
+                                  size as SIZE_T) as *mut u8;
+            if new.is_null() {
+                old_size
+            } else {
+                size
+            }
         } else {
             old_size
         }
index 62463ecabbf5539d7a650b03c641540e5b950dae..97621a2ac89d4f2f28d9d83323c8af5832e49c06 100644 (file)
@@ -105,7 +105,7 @@ pub struct Arena<'longer_than_self> {
     head: RefCell<Chunk>,
     copy_head: RefCell<Chunk>,
     chunks: RefCell<Vec<Chunk>>,
-    _marker: marker::PhantomData<*mut &'longer_than_self()>,
+    _marker: marker::PhantomData<*mut &'longer_than_self ()>,
 }
 
 impl<'a> Arena<'a> {
@@ -197,7 +197,7 @@ fn un_bitpack_tydesc_ptr(p: usize) -> (*const TyDesc, bool) {
 struct TyDesc {
     drop_glue: fn(*const i8),
     size: usize,
-    align: usize
+    align: usize,
 }
 
 trait AllTypes { fn dummy(&self) { } }
@@ -224,8 +224,7 @@ fn alloc_copy_grow(&self, n_bytes: usize, align: usize) -> *const u8 {
         let new_min_chunk_size = cmp::max(n_bytes, self.chunk_size());
         self.chunks.borrow_mut().push(self.copy_head.borrow().clone());
 
-        *self.copy_head.borrow_mut() =
-            chunk((new_min_chunk_size + 1).next_power_of_two(), true);
+        *self.copy_head.borrow_mut() = chunk((new_min_chunk_size + 1).next_power_of_two(), true);
 
         self.alloc_copy_inner(n_bytes, align)
     }
@@ -242,16 +241,13 @@ fn alloc_copy_inner(&self, n_bytes: usize, align: usize) -> *const u8 {
         let copy_head = self.copy_head.borrow();
         copy_head.fill.set(end);
 
-        unsafe {
-            copy_head.as_ptr().offset(start as isize)
-        }
+        unsafe { copy_head.as_ptr().offset(start as isize) }
     }
 
     #[inline]
     fn alloc_copy<T, F>(&self, op: F) -> &mut T where F: FnOnce() -> T {
         unsafe {
-            let ptr = self.alloc_copy_inner(mem::size_of::<T>(),
-                                            mem::align_of::<T>());
+            let ptr = self.alloc_copy_inner(mem::size_of::<T>(), mem::align_of::<T>());
             let ptr = ptr as *mut T;
             ptr::write(&mut (*ptr), op());
             &mut *ptr
@@ -259,21 +255,18 @@ fn alloc_copy<T, F>(&self, op: F) -> &mut T where F: FnOnce() -> T {
     }
 
     // Functions for the non-POD part of the arena
-    fn alloc_noncopy_grow(&self, n_bytes: usize,
-                          align: usize) -> (*const u8, *const u8) {
+    fn alloc_noncopy_grow(&self, n_bytes: usize, align: usize) -> (*const u8, *const u8) {
         // Allocate a new chunk.
         let new_min_chunk_size = cmp::max(n_bytes, self.chunk_size());
         self.chunks.borrow_mut().push(self.head.borrow().clone());
 
-        *self.head.borrow_mut() =
-            chunk((new_min_chunk_size + 1).next_power_of_two(), false);
+        *self.head.borrow_mut() = chunk((new_min_chunk_size + 1).next_power_of_two(), false);
 
         self.alloc_noncopy_inner(n_bytes, align)
     }
 
     #[inline]
-    fn alloc_noncopy_inner(&self, n_bytes: usize,
-                           align: usize) -> (*const u8, *const u8) {
+    fn alloc_noncopy_inner(&self, n_bytes: usize, align: usize) -> (*const u8, *const u8) {
         // Be careful to not maintain any `head` borrows active, because
         // `alloc_noncopy_grow` borrows it mutably.
         let (start, end, tydesc_start, head_capacity) = {
@@ -297,7 +290,8 @@ fn alloc_noncopy_inner(&self, n_bytes: usize,
 
         unsafe {
             let buf = head.as_ptr();
-            (buf.offset(tydesc_start as isize), buf.offset(start as isize))
+            (buf.offset(tydesc_start as isize),
+             buf.offset(start as isize))
         }
     }
 
@@ -305,16 +299,14 @@ fn alloc_noncopy_inner(&self, n_bytes: usize,
     fn alloc_noncopy<T, F>(&self, op: F) -> &mut T where F: FnOnce() -> T {
         unsafe {
             let tydesc = get_tydesc::<T>();
-            let (ty_ptr, ptr) =
-                self.alloc_noncopy_inner(mem::size_of::<T>(),
-                                         mem::align_of::<T>());
+            let (ty_ptr, ptr) = self.alloc_noncopy_inner(mem::size_of::<T>(), mem::align_of::<T>());
             let ty_ptr = ty_ptr as *mut usize;
             let ptr = ptr as *mut T;
             // Write in our tydesc along with a bit indicating that it
             // has *not* been initialized yet.
             *ty_ptr = bitpack_tydesc_ptr(tydesc, false);
             // Actually initialize it
-            ptr::write(&mut(*ptr), op());
+            ptr::write(&mut (*ptr), op());
             // Now that we are done, update the tydesc to indicate that
             // the object is there.
             *ty_ptr = bitpack_tydesc_ptr(tydesc, true);
@@ -358,10 +350,10 @@ fn test_arena_destructors_fail() {
     for i in 0..10 {
         // Arena allocate something with drop glue to make sure it
         // doesn't leak.
-        arena.alloc(|| { Rc::new(i) });
+        arena.alloc(|| Rc::new(i));
         // Allocate something with funny size and alignment, to keep
         // things interesting.
-        arena.alloc(|| { [0u8, 1, 2] });
+        arena.alloc(|| [0u8, 1, 2]);
     }
     // Now, panic while allocating
     arena.alloc::<Rc<i32>, _>(|| {
@@ -409,12 +401,13 @@ fn calculate_size<T>(capacity: usize) -> usize {
 
 impl<T> TypedArenaChunk<T> {
     #[inline]
-    unsafe fn new(next: *mut TypedArenaChunk<T>, capacity: usize)
-           -> *mut TypedArenaChunk<T> {
+    unsafe fn new(next: *mut TypedArenaChunk<T>, capacity: usize) -> *mut TypedArenaChunk<T> {
         let size = calculate_size::<T>(capacity);
-        let chunk = allocate(size, mem::align_of::<TypedArenaChunk<T>>())
-                    as *mut TypedArenaChunk<T>;
-        if chunk.is_null() { alloc::oom() }
+        let chunk =
+            allocate(size, mem::align_of::<TypedArenaChunk<T>>()) as *mut TypedArenaChunk<T>;
+        if chunk.is_null() {
+            alloc::oom()
+        }
         (*chunk).next = next;
         (*chunk).capacity = capacity;
         chunk
@@ -437,7 +430,8 @@ unsafe fn destroy(&mut self, len: usize) {
         let next = self.next;
         let size = calculate_size::<T>(self.capacity);
         let self_ptr: *mut TypedArenaChunk<T> = self;
-        deallocate(self_ptr as *mut u8, size,
+        deallocate(self_ptr as *mut u8,
+                   size,
                    mem::align_of::<TypedArenaChunk<T>>());
         if !next.is_null() {
             let capacity = (*next).capacity;
@@ -449,9 +443,7 @@ unsafe fn destroy(&mut self, len: usize) {
     #[inline]
     fn start(&self) -> *const u8 {
         let this: *const TypedArenaChunk<T> = self;
-        unsafe {
-            round_up(this.offset(1) as usize, mem::align_of::<T>()) as *const u8
-        }
+        unsafe { round_up(this.offset(1) as usize, mem::align_of::<T>()) as *const u8 }
     }
 
     // Returns a pointer to the end of the allocated space.
@@ -545,14 +537,21 @@ struct Point {
 
     #[test]
     fn test_arena_alloc_nested() {
-        struct Inner { value: u8 }
-        struct Outer<'a> { inner: &'a Inner }
-        enum EI<'e> { I(Inner), O(Outer<'e>) }
+        struct Inner {
+            value: u8,
+        }
+        struct Outer<'a> {
+            inner: &'a Inner,
+        }
+        enum EI<'e> {
+            I(Inner),
+            O(Outer<'e>),
+        }
 
         struct Wrap<'a>(TypedArena<EI<'a>>);
 
         impl<'a> Wrap<'a> {
-            fn alloc_inner<F:Fn() -> Inner>(&self, f: F) -> &Inner {
+            fn alloc_inner<F: Fn() -> Inner>(&self, f: F) -> &Inner {
                 let r: &EI = self.0.alloc(EI::I(f()));
                 if let &EI::I(ref i) = r {
                     i
@@ -560,7 +559,7 @@ fn alloc_inner<F:Fn() -> Inner>(&self, f: F) -> &Inner {
                     panic!("mismatch");
                 }
             }
-            fn alloc_outer<F:Fn() -> Outer<'a>>(&self, f: F) -> &Outer {
+            fn alloc_outer<F: Fn() -> Outer<'a>>(&self, f: F) -> &Outer {
                 let r: &EI = self.0.alloc(EI::O(f()));
                 if let &EI::O(ref o) = r {
                     o
@@ -572,8 +571,9 @@ fn alloc_outer<F:Fn() -> Outer<'a>>(&self, f: F) -> &Outer {
 
         let arena = Wrap(TypedArena::new());
 
-        let result = arena.alloc_outer(|| Outer {
-            inner: arena.alloc_inner(|| Inner { value: 10 }) });
+        let result = arena.alloc_outer(|| {
+            Outer { inner: arena.alloc_inner(|| Inner { value: 10 }) }
+        });
 
         assert_eq!(result.inner.value, 10);
     }
@@ -582,49 +582,27 @@ fn alloc_outer<F:Fn() -> Outer<'a>>(&self, f: F) -> &Outer {
     pub fn test_copy() {
         let arena = TypedArena::new();
         for _ in 0..100000 {
-            arena.alloc(Point {
-                x: 1,
-                y: 2,
-                z: 3,
-            });
+            arena.alloc(Point { x: 1, y: 2, z: 3 });
         }
     }
 
     #[bench]
     pub fn bench_copy(b: &mut Bencher) {
         let arena = TypedArena::new();
-        b.iter(|| {
-            arena.alloc(Point {
-                x: 1,
-                y: 2,
-                z: 3,
-            })
-        })
+        b.iter(|| arena.alloc(Point { x: 1, y: 2, z: 3 }))
     }
 
     #[bench]
     pub fn bench_copy_nonarena(b: &mut Bencher) {
         b.iter(|| {
-            let _: Box<_> = box Point {
-                x: 1,
-                y: 2,
-                z: 3,
-            };
+            let _: Box<_> = box Point { x: 1, y: 2, z: 3 };
         })
     }
 
     #[bench]
     pub fn bench_copy_old_arena(b: &mut Bencher) {
         let arena = Arena::new();
-        b.iter(|| {
-            arena.alloc(|| {
-                Point {
-                    x: 1,
-                    y: 2,
-                    z: 3,
-                }
-            })
-        })
+        b.iter(|| arena.alloc(|| Point { x: 1, y: 2, z: 3 }))
     }
 
     #[allow(dead_code)]
@@ -639,7 +617,7 @@ pub fn test_noncopy() {
         for _ in 0..100000 {
             arena.alloc(Noncopy {
                 string: "hello world".to_string(),
-                array: vec!( 1, 2, 3, 4, 5 ),
+                array: vec!(1, 2, 3, 4, 5),
             });
         }
     }
@@ -650,7 +628,7 @@ pub fn bench_noncopy(b: &mut Bencher) {
         b.iter(|| {
             arena.alloc(Noncopy {
                 string: "hello world".to_string(),
-                array: vec!( 1, 2, 3, 4, 5 ),
+                array: vec!(1, 2, 3, 4, 5),
             })
         })
     }
@@ -660,7 +638,7 @@ pub fn bench_noncopy_nonarena(b: &mut Bencher) {
         b.iter(|| {
             let _: Box<_> = box Noncopy {
                 string: "hello world".to_string(),
-                array: vec!( 1, 2, 3, 4, 5 ),
+                array: vec!(1, 2, 3, 4, 5),
             };
         })
     }
@@ -669,9 +647,11 @@ pub fn bench_noncopy_nonarena(b: &mut Bencher) {
     pub fn bench_noncopy_old_arena(b: &mut Bencher) {
         let arena = Arena::new();
         b.iter(|| {
-            arena.alloc(|| Noncopy {
-                string: "hello world".to_string(),
-                array: vec!( 1, 2, 3, 4, 5 ),
+            arena.alloc(|| {
+                Noncopy {
+                    string: "hello world".to_string(),
+                    array: vec!(1, 2, 3, 4, 5),
+                }
             })
         })
     }
index 96d29c7da4abea11514e6b5acbc6eb6f79ab4172..59ffc1bd36f821474deb3fb834371f20ece5f009 100644 (file)
@@ -949,7 +949,7 @@ fn index(&self, key: &Q) -> &V {
     }
 }
 
-/// Genericises over how to get the correct type of iterator from the correct type
+/// Genericizes over how to get the correct type of iterator from the correct type
 /// of Node ownership.
 trait Traverse<N> {
     fn traverse(node: N) -> Self;
index bde0d0e6b5f81438ea1330a255765349f94e6724..4380f315ee7f12de54ae460c131e0c43f8c43e6c 100644 (file)
@@ -818,7 +818,7 @@ pub fn insert_as_internal(mut self, key: K, value: V, right: Node<K, V>)
         }
     }
 
-    /// Handle an underflow in this node's child. We favour handling "to the left" because we know
+    /// Handle an underflow in this node's child. We favor handling "to the left" because we know
     /// we're empty, but our neighbour can be full. Handling to the left means when we choose to
     /// steal, we pop off the end of our neighbour (always fast) and "unshift" ourselves
     /// (always slow, but at least faster since we know we're half-empty).
index 271dbffcc2e41217342112f0d12cb6109730a109..0815a2c4de9cfe876b5e14108ed6b21d35c8d24f 100644 (file)
@@ -381,7 +381,7 @@ pub unsafe fn from_raw_parts(buf: *mut u8, length: usize, capacity: usize) -> St
     /// Converts a vector of bytes to a `String` without checking that the
     /// string contains valid UTF-8.
     ///
-    /// See the safe version, [`from_utrf8()`][fromutf8], for more.
+    /// See the safe version, [`from_utf8()`][fromutf8], for more.
     ///
     /// [fromutf8]: struct.String.html#method.from_utf8
     ///
index f6053a75f1f90cb924c7bd78b8117e197a9d6d2d..eea21988aa36021a9201eb4697083bc241756892 100644 (file)
@@ -94,7 +94,7 @@ fn write_char(&mut self, c: char) -> Result {
         self.write_str(unsafe { str::from_utf8_unchecked(&utf_8[..bytes_written]) })
     }
 
-    /// Glue for usage of the `write!` macro with implementers of this trait.
+    /// Glue for usage of the `write!` macro with implementors of this trait.
     ///
     /// This method should generally not be invoked manually, but rather through
     /// the `write!` macro itself.
@@ -523,7 +523,7 @@ pub trait Binary {
 
 /// Format trait for the `x` character.
 ///
-/// The `LowerHex` trait should format its output as a number in hexidecimal, with `a` through `f`
+/// The `LowerHex` trait should format its output as a number in hexadecimal, with `a` through `f`
 /// in lower case.
 ///
 /// The alternate flag, `#`, adds a `0x` in front of the output.
@@ -571,7 +571,7 @@ pub trait LowerHex {
 
 /// Format trait for the `X` character.
 ///
-/// The `UpperHex` trait should format its output as a number in hexidecimal, with `A` through `F`
+/// The `UpperHex` trait should format its output as a number in hexadecimal, with `A` through `F`
 /// in upper case.
 ///
 /// The alternate flag, `#`, adds a `0x` in front of the output.
@@ -620,7 +620,7 @@ pub trait UpperHex {
 /// Format trait for the `p` character.
 ///
 /// The `Pointer` trait should format its output as a memory location. This is commonly presented
-/// as hexidecimal.
+/// as hexadecimal.
 ///
 /// For more information on formatters, see [the module-level documentation][module].
 ///
index 08c017841e3c893581a073d001d23e916e1f6ad7..45b1c8a3599ca34c4b8aa88f40e389fa4cff1a4c 100644 (file)
     /// # Safety
     ///
     /// Beyond requiring that the program must be allowed to access both regions
-    /// of memory, it is Undefined Behaviour for source and destination to
+    /// of memory, it is Undefined Behavior for source and destination to
     /// overlap. Care must also be taken with the ownership of `src` and
     /// `dst`. This method semantically moves the values of `src` into `dst`.
     /// However it does not drop the contents of `dst`, or prevent the contents
index 3554325d0dbfc94c7701f37f4efd8b79db9d018a..afd399bc5d627a8f13ce7a01d7fdc33ca615ac51 100644 (file)
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-//! Composable external iterators
+//! Composable external iteration
 //!
-//! # The `Iterator` trait
+//! If you've found yourself with a collection of some kind, and needed to
+//! perform an operation on the elements of said collection, you'll quickly run
+//! into 'iterators'. Iterators are heavily used in idiomatic Rust code, so
+//! it's worth becoming familiar with them.
 //!
-//! This module defines Rust's core iteration trait. The `Iterator` trait has
-//! one unimplemented method, `next`. All other methods are derived through
-//! default methods to perform operations such as `zip`, `chain`, `enumerate`,
-//! and `fold`.
+//! Before explaining more, let's talk about how this module is structured:
 //!
-//! The goal of this module is to unify iteration across all containers in Rust.
-//! An iterator can be considered as a state machine which is used to track
-//! which element will be yielded next.
+//! # Organization
 //!
-//! There are various extensions also defined in this module to assist with
-//! various types of iteration, such as the `DoubleEndedIterator` for iterating
-//! in reverse, the `FromIterator` trait for creating a container from an
-//! iterator, and much more.
+//! This module is largely organized by type:
 //!
-//! # Rust's `for` loop
+//! * [Traits] are the core portion: these traits define what kind of iterators
+//!   exist and what you can do with them. The methods of these traits are worth
+//!   putting some extra study time into.
+//! * [Functions] provide some helpful ways to create some basic iterators.
+//! * [Structs] are often the return types of the various methods on this
+//!   module's traits. You'll usually want to look at the method that creates
+//!   the `struct`, rather than the `struct` itself. For more detail about why,
+//!   see '[Implementing Iterator](#implementing-iterator)'.
 //!
-//! The special syntax used by rust's `for` loop is based around the
-//! `IntoIterator` trait defined in this module. `for` loops can be viewed as a
-//! syntactical expansion into a `loop`, for example, the `for` loop in this
-//! example is essentially translated to the `loop` below.
+//! [Traits]: #traits
+//! [Functions]: #functions
+//! [Structs]: #structs
 //!
+//! That's it! Let's dig into iterators.
+//!
+//! # Iterator
+//!
+//! The heart and soul of this module is the [`Iterator`] trait. The core of
+//! [`Iterator`] looks like this:
+//!
+//! ```
+//! trait Iterator {
+//!     type Item;
+//!     fn next(&mut self) -> Option<Self::Item>;
+//! }
+//! ```
+//!
+//! An iterator has a method, [`next()`], which when called, returns an
+//! [`Option`]`<Item>`. [`next()`] will return `Some(Item)` as long as there
+//! are elements, and once they've all been exhausted, will return `None` to
+//! indicate that iteration is finished. Individual iterators may choose to
+//! resume iteration, and so calling [`next()`] again may or may not eventually
+//! start returning `Some(Item)` again at some point.
+//!
+//! [`Iterator`]'s full definition includes a number of other methods as well,
+//! but they are default methods, built on top of [`next()`], and so you get
+//! them for free.
+//!
+//! Iterators are also composable, and it's common to chain them together to do
+//! more complex forms of processing. See the [Adapters](#adapters) section
+//! below for more details.
+//!
+//! [`Iterator`]: trait.Iterator.html
+//! [`next()`]: trait.Iterator.html#tymethod.next
+//! [`Option`]: ../option/enum.Option.html
+//!
+//! # The three forms of iteration
+//!
+//! There are three common methods which can create iterators from a collection:
+//!
+//! * `iter()`, which iterates over `&T`.
+//! * `iter_mut()`, which iterates over `&mut T`.
+//! * `into_iter()`, which iterates over `T`.
+//!
+//! Various things in the standard library may implement one or more of the
+//! three, where appropriate.
+//!
+//! # Implementing Iterator
+//!
+//! Creating an iterator of your own involves two steps: creating a `struct` to
+//! hold the iterator's state, and then `impl`ementing [`Iterator`] for that
+//! `struct`. This is why there are so many `struct`s in this module: there is
+//! one for each iterator and iterator adapter.
+//!
+//! Let's make an iterator named `Counter` which counts from `1` to `5`:
+//!
+//! ```
+//! // First, the struct:
+//!
+//! /// An iterator which counts from one to five
+//! struct Counter {
+//!     count: i32,
+//! }
+//!
+//! // we want our count to start at one, so let's add a new() method to help.
+//! // This isn't strictly necessary, but is convenient. Note that we start
+//! // `count` at zero, we'll see why in `next()`'s implementation below.
+//! impl Counter {
+//!     fn new() -> Counter {
+//!         Counter { count: 0 }
+//!     }
+//! }
+//!
+//! // Then, we implement `Iterator` for our `Counter`:
+//!
+//! impl Iterator for Counter {
+//!     // we will be counting with i32
+//!     type Item = i32;
+//!
+//!     // next() is the only required method
+//!     fn next(&mut self) -> Option<i32> {
+//!         // increment our count. This is why we started at zero.
+//!         self.count += 1;
+//!
+//!         // check to see if we've finished counting or not.
+//!         if self.count < 6 {
+//!             Some(self.count)
+//!         } else {
+//!             None
+//!         }
+//!     }
+//! }
+//!
+//! // And now we can use it!
+//!
+//! let mut counter = Counter::new();
+//!
+//! let x = counter.next().unwrap();
+//! println!("{}", x);
+//!
+//! let x = counter.next().unwrap();
+//! println!("{}", x);
+//!
+//! let x = counter.next().unwrap();
+//! println!("{}", x);
+//!
+//! let x = counter.next().unwrap();
+//! println!("{}", x);
+//!
+//! let x = counter.next().unwrap();
+//! println!("{}", x);
 //! ```
-//! let values = vec![1, 2, 3];
+//!
+//! This will print `1` through `5`, each on their own line.
+//!
+//! Calling `next()` this way gets repetitive. Rust has a construct which can
+//! call `next()` on your iterator, until it reaches `None`. Let's go over that
+//! next.
+//!
+//! # for Loops and IntoIterator
+//!
+//! Rust's `for` loop syntax is actually sugar for iterators. Here's a basic
+//! example of `for`:
+//!
+//! ```
+//! let values = vec![1, 2, 3, 4, 5];
 //!
 //! for x in values {
 //!     println!("{}", x);
 //! }
+//! ```
 //!
-//! // Rough translation of the iteration without a `for` iterator.
-//! # let values = vec![1, 2, 3];
-//! let mut it = values.into_iter();
-//! loop {
-//!     match it.next() {
-//!         Some(x) => println!("{}", x),
-//!         None => break,
-//!     }
+//! This will print the numbers one through five, each on their own line. But
+//! you'll notice something here: we never called anything on our vector to
+//! produce an iterator. What gives?
+//!
+//! There's a trait in the standard library for converting something into an
+//! iterator: [`IntoIterator`]. This trait has one method, [`into_iter()`],
+//! which converts the thing implementing [`IntoIterator`] into an iterator.
+//! Let's take a look at that `for` loop again, and what the compiler converts
+//! it into:
+//!
+//! [`IntoIterator`]: trait.IntoIterator.html
+//! [`into_iter()`]: trait.IntoIterator.html#tymethod.into_iter
+//!
+//! ```
+//! let values = vec![1, 2, 3, 4, 5];
+//!
+//! for x in values {
+//!     println!("{}", x);
+//! }
+//! ```
+//!
+//! Rust de-sugars this into:
+//!
+//! ```
+//! let values = vec![1, 2, 3, 4, 5];
+//! {
+//!     let result = match values.into_iter() {
+//!         mut iter => loop {
+//!             match iter.next() {
+//!                 Some(x) => { println!("{}", x); },
+//!                 None => break,
+//!             }
+//!         },
+//!     };
+//!     result
 //! }
 //! ```
 //!
-//! Because `Iterator`s implement `IntoIterator`, this `for` loop syntax can be
-//! applied to any iterator over any type.
+//! First, we call `into_iter()` on the value. Then, we match on the iterator
+//! that returns, calling [`next()`] over and over until we see a `None`. At
+//! that point, we `break` out of the loop, and we're done iterating.
+//!
+//! There's one more subtle bit here: the standard library contains an
+//! interesting implementation of [`IntoIterator`]:
+//!
+//! ```ignore
+//! impl<I> IntoIterator for I where I: Iterator
+//! ```
+//!
+//! In other words, all [`Iterator`]s implement [`IntoIterator`], by just
+//! returning themselves. This means two things:
+//!
+//! 1. If you're writing an [`Iterator`], you can use it with a `for` loop.
+//! 2. If you're creating a collection, implementing [`IntoIterator`] for it
+//!    will allow your collection to be used with the `for` loop.
+//!
+//! # Adapters
+//!
+//! Functions which take an [`Iterator`] and return another [`Iterator`] are
+//! often called 'iterator adapters', as they're a form of the 'adapter
+//! pattern'.
+//!
+//! Common iterator adapters include [`map()`], [`take()`], and [`collect()`].
+//! For more, see their documentation.
+//!
+//! [`map()`]: trait.Iterator.html#method.map
+//! [`take()`]: trait.Iterator.html#method.take
+//! [`collect()`]: trait.Iterator.html#method.collect
+//!
+//! # Laziness
+//!
+//! Iterators (and iterator [adapters](#adapters)) are *lazy*. This means that
+//! just creating an iterator doesn't _do_ a whole lot. Nothing really happens
+//! until you call [`next()`]. This is sometimes a source of confusion when
+//! creating an iterator solely for its side effects. For example, the [`map()`]
+//! method calls a closure on each element it iterates over:
+//!
+//! ```
+//! let v = vec![1, 2, 3, 4, 5];
+//! v.iter().map(|x| println!("{}", x));
+//! ```
+//!
+//! This will not print any values, as we only created an iterator, rather than
+//! using it. The compiler will warn us about this kind of behavior:
+//!
+//! ```text
+//! warning: unused result which must be used: iterator adaptors are lazy and
+//! do nothing unless consumed
+//! ```
+//!
+//! The idiomatic way to write a [`map()`] for its side effects is to use a
+//! `for` loop instead:
+//!
+//! ```
+//! let v = vec![1, 2, 3, 4, 5];
+//!
+//! for x in &v {
+//!     println!("{}", x);
+//! }
+//! ```
+//!
+//! [`map()`]: trait.Iterator.html#method.map
+//!
+//! The two most common ways to evaluate an iterator are to use a `for` loop
+//! like this, or using the [`collect()`] adapter to produce a new collection.
+//!
+//! [`collect()`]: trait.Iterator.html#method.collect
+//!
+//! # Infinity
+//!
+//! Iterators do not have to be finite. As an example, an open-ended range is
+//! an infinite iterator:
+//!
+//! ```
+//! let numbers = 0..;
+//! ```
+//!
+//! It is common to use the [`take()`] iterator adapter to turn an infinite
+//! iterator into a finite one:
+//!
+//! ```
+//! let numbers = 0..;
+//! let five_numbers = numbers.take(5);
+//!
+//! for number in five_numbers {
+//!     println!("{}", number);
+//! }
+//! ```
+//!
+//! This will print the numbers `0` through `4`, each on their own line.
+//!
+//! [`take()`]: trait.Iterator.html#method.take
 
 #![stable(feature = "rust1", since = "1.0.0")]
 
@@ -1211,7 +1453,7 @@ fn ge<I>(mut self, other: I) -> bool where
 ///
 /// This is an idiosyncratic helper to try to factor out the
 /// commonalities of {max,min}{,_by}. In particular, this avoids
-/// having to implement optimisations several times.
+/// having to implement optimizations several times.
 #[inline]
 fn select_fold1<I,B, FProj, FCmp>(mut it: I,
                                   mut f_proj: FProj,
@@ -2790,7 +3032,52 @@ impl<A: Clone> DoubleEndedIterator for Repeat<A> {
     fn next_back(&mut self) -> Option<A> { Some(self.element.clone()) }
 }
 
-/// Creates a new iterator that endlessly repeats the element `elt`.
+/// Creates a new iterator that endlessly repeats a single element.
+///
+/// The `repeat()` function repeats a single value over and over and over and
+/// over and over and 🔁.
+///
+/// Infinite iterators like `repeat()` are often used with adapters like
+/// [`take()`], in order to make them finite.
+///
+/// [`take()`]: trait.Iterator.html#method.take
+///
+/// # Examples
+///
+/// Basic usage:
+///
+/// ```
+/// use std::iter;
+///
+/// // the number four 4ever:
+/// let mut fours = iter::repeat(4);
+///
+/// assert_eq!(Some(4), fours.next());
+/// assert_eq!(Some(4), fours.next());
+/// assert_eq!(Some(4), fours.next());
+/// assert_eq!(Some(4), fours.next());
+/// assert_eq!(Some(4), fours.next());
+///
+/// // yup, still four
+/// assert_eq!(Some(4), fours.next());
+/// ```
+///
+/// Going finite with [`take()`]:
+///
+/// ```
+/// use std::iter;
+///
+/// // that last example was too many fours. Let's only have four fours.
+/// let mut four_fours = iter::repeat(4).take(4);
+///
+/// assert_eq!(Some(4), four_fours.next());
+/// assert_eq!(Some(4), four_fours.next());
+/// assert_eq!(Some(4), four_fours.next());
+/// assert_eq!(Some(4), four_fours.next());
+///
+/// // ... and now we're done
+/// assert_eq!(None, four_fours.next());
+/// ```
 #[inline]
 #[stable(feature = "rust1", since = "1.0.0")]
 pub fn repeat<T: Clone>(elt: T) -> Repeat<T> {
@@ -2847,6 +3134,19 @@ fn default() -> Empty<T> {
 }
 
 /// Creates an iterator that yields nothing.
+///
+/// # Exampes
+///
+/// Basic usage:
+///
+/// ```
+/// use std::iter;
+///
+/// // this could have been an iterator over i32, but alas, it's just not.
+/// let mut nope = iter::empty::<i32>();
+///
+/// assert_eq!(None, nope.next());
+/// ```
 #[stable(feature = "iter_empty", since = "1.2.0")]
 pub fn empty<T>() -> Empty<T> {
     Empty(marker::PhantomData)
@@ -2887,6 +3187,56 @@ fn len(&self) -> usize {
 }
 
 /// Creates an iterator that yields an element exactly once.
+///
+/// This is commonly used to adapt a single value into a [`chain()`] of other
+/// kinds of iteration. Maybe you have an iterator that covers almost
+/// everything, but you need an extra special case. Maybe you have a function
+/// which works on iterators, but you only need to process one value.
+///
+/// [`chain()`]: trait.Iterator.html#method.chain
+///
+/// # Examples
+///
+/// Basic usage:
+///
+/// ```
+/// use std::iter;
+///
+/// // one is the loneliest number
+/// let mut one = iter::once(1);
+///
+/// assert_eq!(Some(1), one.next());
+///
+/// // just one, that's all we get
+/// assert_eq!(None, one.next());
+/// ```
+///
+/// Chaining together with another iterator. Let's say that we want to iterate
+/// over each file of the `.foo` directory, but also a configuration file,
+/// `.foorc`:
+///
+/// ```no_run
+/// use std::iter;
+/// use std::fs;
+/// use std::path::PathBuf;
+///
+/// let dirs = fs::read_dir(".foo").unwrap();
+///
+/// // we need to convert from an iterator of DirEntry-s to an iterator of
+/// // PathBufs, so we use map
+/// let dirs = dirs.map(|file| file.unwrap().path());
+///
+/// // now, our iterator just for our config file
+/// let config = iter::once(PathBuf::from(".foorc"));
+///
+/// // chain the two iterators together into one big iterator
+/// let files = dirs.chain(config);
+///
+/// // this will give us all of the files in .foo as well as .foorc
+/// for f in files {
+///     println!("{:?}", f);
+/// }
+/// ```
 #[stable(feature = "iter_once", since = "1.2.0")]
 pub fn once<T>(value: T) -> Once<T> {
     Once { inner: Some(value).into_iter() }
index 58e0bb37b0a979d68d82630d9a443c698ca16d46..bb112327abf4b02f0075411958ca63a9af2c911b 100644 (file)
@@ -279,7 +279,7 @@ macro_rules! unreachable {
     });
 }
 
-/// A standardised placeholder for marking unfinished code. It panics with the
+/// A standardized placeholder for marking unfinished code. It panics with the
 /// message `"not yet implemented"` when executed.
 ///
 /// This can be useful if you are prototyping and are just looking to have your
index bf95ce868500b5537f93d1e88e82c0b4f864b33b..f9480b4349d1107ece794503e96edbecfdff04f7 100644 (file)
@@ -172,7 +172,7 @@ pub trait Copy : Clone {
 ///
 /// A somewhat surprising consequence of the definition is `&mut T` is
 /// `Sync` (if `T` is `Sync`) even though it seems that it might
-/// provide unsynchronised mutation. The trick is a mutable reference
+/// provide unsynchronized mutation. The trick is a mutable reference
 /// stored in an aliasable reference (that is, `& &mut T`) becomes
 /// read-only, as if it were a `& &T`, hence there is no risk of a data
 /// race.
@@ -195,7 +195,7 @@ pub trait Copy : Clone {
 ///
 /// Any types with interior mutability must also use the `std::cell::UnsafeCell`
 /// wrapper around the value(s) which can be mutated when behind a `&`
-/// reference; not doing this is undefined behaviour (for example,
+/// reference; not doing this is undefined behavior (for example,
 /// `transmute`-ing from `&T` to `&mut T` is invalid).
 #[stable(feature = "rust1", since = "1.0.0")]
 #[lang = "sync"]
index 193b8d6d620de46dcd17c85e5bc0d80e81fb5acf..a87d135e42592551f518118a93969ca1ad6e436a 100644 (file)
@@ -37,7 +37,7 @@
 /// * You have two copies of a value (like when writing something like
 ///   [`mem::swap`][swap]), but need the destructor to only run once to
 ///   prevent a double `free`.
-/// * Transferring resources across [FFI][ffi] boundries.
+/// * Transferring resources across [FFI][ffi] boundaries.
 ///
 /// [swap]: fn.swap.html
 /// [ffi]: ../../book/ffi.html
@@ -264,9 +264,9 @@ unsafe fn dropped_impl<T>() -> T { intrinsics::init_dropped() }
 /// This is useful for FFI functions and initializing arrays sometimes,
 /// but should generally be avoided.
 ///
-/// # Undefined Behaviour
+/// # Undefined Behavior
 ///
-/// It is Undefined Behaviour to read uninitialized memory. Even just an
+/// It is Undefined Behavior to read uninitialized memory. Even just an
 /// uninitialized boolean. For instance, if you branch on the value of such
 /// a boolean your program may take one, both, or neither of the branches.
 ///
@@ -303,7 +303,7 @@ unsafe fn dropped_impl<T>() -> T { intrinsics::init_dropped() }
 ///
 ///     // DANGER ZONE: if anything panics or otherwise
 ///     // incorrectly reads the array here, we will have
-///     // Undefined Behaviour.
+///     // Undefined Behavior.
 ///
 ///     // It's ok to mutably iterate the data, since this
 ///     // doesn't involve reading it at all.
@@ -340,7 +340,7 @@ pub unsafe fn uninitialized<T>() -> T {
     intrinsics::uninit()
 }
 
-/// Swap the values at two mutable locations of the same type, without deinitialising or copying
+/// Swap the values at two mutable locations of the same type, without deinitializing or copying
 /// either one.
 ///
 /// # Examples
@@ -376,7 +376,7 @@ pub fn swap<T>(x: &mut T, y: &mut T) {
 }
 
 /// Replaces the value at a mutable location with a new one, returning the old value, without
-/// deinitialising or copying either one.
+/// deinitializing or copying either one.
 ///
 /// This is primarily used for transferring and swapping ownership of a value in a mutable
 /// location.
index c945e4e066159e9a558bf6ba2f0f0c4ba4777632..2cf8bad60cd41c7d1127471532151e48e15c0807 100644 (file)
@@ -38,13 +38,31 @@ unsafe impl Zeroable for u64 {}
 #[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Debug, Hash)]
 pub struct NonZero<T: Zeroable>(T);
 
+#[cfg(stage0)]
+macro_rules! nonzero_new {
+    () => (
+        /// Creates an instance of NonZero with the provided value.
+        /// You must indeed ensure that the value is actually "non-zero".
+        #[inline(always)]
+        pub unsafe fn new(inner: T) -> NonZero<T> {
+            NonZero(inner)
+        }
+    )
+}
+#[cfg(not(stage0))]
+macro_rules! nonzero_new {
+    () => (
+        /// Creates an instance of NonZero with the provided value.
+        /// You must indeed ensure that the value is actually "non-zero".
+        #[inline(always)]
+        pub unsafe const fn new(inner: T) -> NonZero<T> {
+            NonZero(inner)
+        }
+    )
+}
+
 impl<T: Zeroable> NonZero<T> {
-    /// Creates an instance of NonZero with the provided value.
-    /// You must indeed ensure that the value is actually "non-zero".
-    #[inline(always)]
-    pub unsafe fn new(inner: T) -> NonZero<T> {
-        NonZero(inner)
-    }
+    nonzero_new!{}
 }
 
 impl<T: Zeroable> Deref for NonZero<T> {
index 58e2a6e9bba4694859f234eb67edd72fa8ddbe87..414bcc874eac1ca320e7dac04aedc9a03516ce43 100644 (file)
@@ -59,7 +59,12 @@ pub fn parse_decimal(s: &str) -> ParseResult {
     let s = s.as_bytes();
     let (integral, s) = eat_digits(s);
     match s.first() {
-        None => Valid(Decimal::new(integral, b"", 0)),
+        None => {
+            if integral.is_empty() {
+                return Invalid; // No digits at all
+            }
+            Valid(Decimal::new(integral, b"", 0))
+        }
         Some(&b'e') | Some(&b'E') => {
             if integral.is_empty() {
                 return Invalid; // No digits before 'e'
index 56e55155c65e31b6d17440dde42fbcb5a3c2c5d8..8b005b2f8ba7e233b3ebd9755e465b05ae506c98 100644 (file)
@@ -17,6 +17,7 @@
 
 use char::CharExt;
 use cmp::{Eq, PartialOrd};
+use convert::From;
 use fmt;
 use intrinsics;
 use marker::{Copy, Sized};
@@ -1471,3 +1472,45 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
 }
 
 pub use num::dec2flt::ParseFloatError;
+
+// Conversion traits for primitive integer types
+// Conversions T -> T are covered by a blanket impl and therefore excluded
+// Some conversions from and to usize/isize are not implemented due to portability concerns
+macro_rules! impl_from {
+    ($Small: ty, $Large: ty) => {
+        #[stable(feature = "lossless_int_conv", since = "1.5.0")]
+        impl From<$Small> for $Large {
+            #[stable(feature = "lossless_int_conv", since = "1.5.0")]
+            #[inline]
+            fn from(small: $Small) -> $Large {
+                small as $Large
+            }
+        }
+    }
+}
+
+// Unsigned -> Unsigned
+impl_from! { u8, u16 }
+impl_from! { u8, u32 }
+impl_from! { u8, u64 }
+impl_from! { u8, usize }
+impl_from! { u16, u32 }
+impl_from! { u16, u64 }
+impl_from! { u32, u64 }
+
+// Signed -> Signed
+impl_from! { i8, i16 }
+impl_from! { i8, i32 }
+impl_from! { i8, i64 }
+impl_from! { i8, isize }
+impl_from! { i16, i32 }
+impl_from! { i16, i64 }
+impl_from! { i32, i64 }
+
+// Unsigned -> Signed
+impl_from! { u8, i16 }
+impl_from! { u8, i32 }
+impl_from! { u8, i64 }
+impl_from! { u16, i32 }
+impl_from! { u16, i64 }
+impl_from! { u32, i64 }
index 831616293cd8fb99de8c41f2c9d7d7585209ce90..960240d7f5fc874728195dd730016f1dd661a158 100644 (file)
@@ -69,7 +69,7 @@ pub const fn null<T>() -> *const T { 0 as *const T }
 pub const fn null_mut<T>() -> *mut T { 0 as *mut T }
 
 /// Swaps the values at two mutable locations of the same type, without
-/// deinitialising either. They may overlap, unlike `mem::swap` which is
+/// deinitializing either. They may overlap, unlike `mem::swap` which is
 /// otherwise equivalent.
 ///
 /// # Safety
@@ -145,9 +145,11 @@ pub unsafe fn read_and_drop<T>(dest: *mut T) -> T {
 ///
 /// # Safety
 ///
-/// Beyond accepting a raw pointer, this operation is unsafe because it does
-/// not drop the contents of `dst`. This could leak allocations or resources,
-/// so care must be taken not to overwrite an object that should be dropped.
+/// This operation is marked unsafe because it accepts a raw pointer.
+///
+/// It does not drop the contents of `dst`. This is safe, but it could leak
+/// allocations or resources, so care must be taken not to overwrite an object
+/// that should be dropped.
 ///
 /// This is appropriate for initializing uninitialized memory, or overwriting
 /// memory that has previously been `read` from.
@@ -245,7 +247,7 @@ pub unsafe fn as_ref<'a>(&self) -> Option<&'a T> where T: Sized {
     /// # Safety
     ///
     /// The offset must be in-bounds of the object, or one-byte-past-the-end.
-    /// Otherwise `offset` invokes Undefined Behaviour, regardless of whether
+    /// Otherwise `offset` invokes Undefined Behavior, regardless of whether
     /// the pointer is used.
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
index 382fd0f3788ced524be6e66de1ae874ecb0997b6..84467be6eca5641d30e15a0a4240fc827b761ec1 100644 (file)
@@ -94,7 +94,7 @@ fn clone(&self) -> Slice<T> { *self }
 /// Synthesizing a trait object with mismatched types—one where the
 /// vtable does not correspond to the type of the value to which the
 /// data pointer points—is highly likely to lead to undefined
-/// behaviour.
+/// behavior.
 ///
 /// # Examples
 ///
index 57daa95e8c44dd98edb0d91c38035f2a3c8caef1..c0a85e0df067cb6e18a5791b19c0aea5ef0e1285 100644 (file)
@@ -243,7 +243,7 @@ pub fn from_utf8(v: &[u8]) -> Result<&str, Utf8Error> {
 /// Converts a slice of bytes to a string slice without checking
 /// that the string contains valid UTF-8.
 ///
-/// See the safe version, [`from_utrf8()`][fromutf8], for more.
+/// See the safe version, [`from_utf8()`][fromutf8], for more.
 ///
 /// [fromutf8]: fn.from_utf8.html
 ///
@@ -965,7 +965,7 @@ fn next_back(&mut self) -> Option<&'a str> {
 #[allow(deprecated)]
 pub struct LinesAny<'a>(Lines<'a>);
 
-/// A nameable, clonable fn type
+/// A nameable, cloneable fn type
 #[derive(Clone)]
 struct LinesAnyMap;
 
index 51fea6e01717153807d12de369cf8e47c31c0d83..0c92b2fe2a7dc425de69110c586b98daf62c14d3 100644 (file)
@@ -101,6 +101,18 @@ fn lonely_dot() {
     assert_eq!(".".parse(), Ok(0.0));
 }
 
+#[test]
+fn lonely_sign() {
+    assert!("+".parse::<f32>().is_err());
+    assert!("-".parse::<f64>().is_err());
+}
+
+#[test]
+fn whitespace() {
+    assert!(" 1.0".parse::<f32>().is_err());
+    assert!("1.0 ".parse::<f64>().is_err());
+}
+
 #[test]
 fn nan() {
     assert!("NaN".parse::<f32>().unwrap().is_nan());
index 2a3ff88fe6da2b7a8993e1633a0054075a0afb69..5e2ec66bababebb362cce97e36ff38adcbbf730f 100644 (file)
@@ -137,4 +137,44 @@ fn test_empty() {
         assert_eq!("+".parse::<i8>().ok(), None);
         assert_eq!("".parse::<u8>().ok(), None);
     }
+
+    macro_rules! test_impl_from {
+        ($fn_name: ident, $Small: ty, $Large: ty) => {
+            #[test]
+            fn $fn_name() {
+                let small_max = <$Small>::max_value();
+                let small_min = <$Small>::min_value();
+                let large_max: $Large = small_max.into();
+                let large_min: $Large = small_min.into();
+                assert_eq!(large_max as $Small, small_max);
+                assert_eq!(large_min as $Small, small_min);
+            }
+        }
+    }
+
+    // Unsigned -> Unsigned
+    test_impl_from! { test_u8u16, u8, u16 }
+    test_impl_from! { test_u8u32, u8, u32 }
+    test_impl_from! { test_u8u64, u8, u64 }
+    test_impl_from! { test_u8usize, u8, usize }
+    test_impl_from! { test_u16u32, u16, u32 }
+    test_impl_from! { test_u16u64, u16, u64 }
+    test_impl_from! { test_u32u64, u32, u64 }
+
+    // Signed -> Signed
+    test_impl_from! { test_i8i16, i8, i16 }
+    test_impl_from! { test_i8i32, i8, i32 }
+    test_impl_from! { test_i8i64, i8, i64 }
+    test_impl_from! { test_i8isize, i8, isize }
+    test_impl_from! { test_i16i32, i16, i32 }
+    test_impl_from! { test_i16i64, i16, i64 }
+    test_impl_from! { test_i32i64, i32, i64 }
+
+    // Unsigned -> Signed
+    test_impl_from! { test_u8i16, u8, i16 }
+    test_impl_from! { test_u8i32, u8, i32 }
+    test_impl_from! { test_u8i64, u8, i64 }
+    test_impl_from! { test_u16i32, u16, i32 }
+    test_impl_from! { test_u16i64, u16, i64 }
+    test_impl_from! { test_u32i64, u32, i64 }
 }
index d85f653937c8056e55b645e0449af68d5308e3dc..521dddae78ff964dceeeb41524e865d784426b30 100644 (file)
@@ -30,7 +30,9 @@
 #![feature(unique)]
 #![cfg_attr(test, feature(rustc_private, rand, vec_push_all))]
 
-#[cfg(test)] #[macro_use] extern crate log;
+#[cfg(test)]
+#[macro_use]
+extern crate log;
 
 extern crate libc;
 
@@ -47,9 +49,7 @@ pub struct Error {
 
 impl Error {
     fn new() -> Error {
-        Error {
-            _unused: (),
-        }
+        Error { _unused: () }
     }
 }
 
@@ -73,7 +73,9 @@ fn deref(&self) -> &[u8] {
 
 impl Drop for Bytes {
     fn drop(&mut self) {
-        unsafe { libc::free(*self.ptr as *mut _); }
+        unsafe {
+            libc::free(*self.ptr as *mut _);
+        }
     }
 }
 
@@ -123,7 +125,7 @@ pub fn deflate_bytes_zlib(bytes: &[u8]) -> Bytes {
     deflate_bytes_internal(bytes, LZ_NORM | TDEFL_WRITE_ZLIB_HEADER)
 }
 
-fn inflate_bytes_internal(bytes: &[u8], flags: c_int) -> Result<Bytes,Error> {
+fn inflate_bytes_internal(bytes: &[u8], flags: c_int) -> Result<Bytes, Error> {
     unsafe {
         let mut outsz: size_t = 0;
         let res = tinfl_decompress_mem_to_heap(bytes.as_ptr() as *const _,
@@ -142,12 +144,12 @@ fn inflate_bytes_internal(bytes: &[u8], flags: c_int) -> Result<Bytes,Error> {
 }
 
 /// Decompress a buffer, without parsing any sort of header on the input.
-pub fn inflate_bytes(bytes: &[u8]) -> Result<Bytes,Error> {
+pub fn inflate_bytes(bytes: &[u8]) -> Result<Bytes, Error> {
     inflate_bytes_internal(bytes, 0)
 }
 
 /// Decompress a buffer that starts with a zlib header.
-pub fn inflate_bytes_zlib(bytes: &[u8]) -> Result<Bytes,Error> {
+pub fn inflate_bytes_zlib(bytes: &[u8]) -> Result<Bytes, Error> {
     inflate_bytes_internal(bytes, TINFL_FLAG_PARSE_ZLIB_HEADER)
 }
 
@@ -176,7 +178,8 @@ fn test_flate_round_trip() {
             let cmp = deflate_bytes(&input);
             let out = inflate_bytes(&cmp).unwrap();
             debug!("{} bytes deflated to {} ({:.1}% size)",
-                   input.len(), cmp.len(),
+                   input.len(),
+                   cmp.len(),
                    100.0 * ((cmp.len() as f64) / (input.len() as f64)));
             assert_eq!(&*input, &*out);
         }
index 9c02ccb08acd84764f56d94a307842916b80e1e2..ed767ab1e5cf97e3116deb0d01ad71b37cc04682 100644 (file)
@@ -75,7 +75,7 @@ pub struct FormatSpec<'a> {
     /// The descriptor string representing the name of the format desired for
     /// this argument, this can be empty or any number of characters, although
     /// it is required to be one word.
-    pub ty: &'a str
+    pub ty: &'a str,
 }
 
 /// Enum describing where an argument for a format can be located.
@@ -135,7 +135,7 @@ pub enum Count<'a> {
 }
 
 /// The parser structure for interpreting the input format string. This is
-/// modelled as an iterator over `Piece` structures to form a stream of tokens
+/// modeled as an iterator over `Piece` structures to form a stream of tokens
 /// being output.
 ///
 /// This is a recursive-descent parser for the sake of simplicity, and if
@@ -202,7 +202,12 @@ fn err(&mut self, msg: &str) {
     /// returned, otherwise the character is consumed and true is returned.
     fn consume(&mut self, c: char) -> bool {
         if let Some(&(_, maybe)) = self.cur.peek() {
-            if c == maybe { self.cur.next(); true } else { false }
+            if c == maybe {
+                self.cur.next();
+                true
+            } else {
+                false
+            }
         } else {
             false
         }
@@ -227,7 +232,11 @@ fn must_consume(&mut self, c: char) {
     /// character
     fn ws(&mut self) {
         while let Some(&(_, c)) = self.cur.peek() {
-            if c.is_whitespace() { self.cur.next(); } else { break }
+            if c.is_whitespace() {
+                self.cur.next();
+            } else {
+                break
+            }
         }
     }
 
@@ -237,8 +246,12 @@ fn string(&mut self, start: usize) -> &'a str {
         // we may not consume the character, peek the iterator
         while let Some(&(pos, c)) = self.cur.peek() {
             match c {
-                '{' | '}' => { return &self.input[start..pos]; }
-                _ => { self.cur.next(); }
+                '{' | '}' => {
+                    return &self.input[start..pos];
+                }
+                _ => {
+                    self.cur.next();
+                }
             }
         }
         &self.input[start..self.input.len()]
@@ -263,7 +276,7 @@ fn position(&mut self) -> Position<'a> {
                 Some(&(_, c)) if c.is_alphabetic() => {
                     ArgumentNamed(self.word())
                 }
-                _ => ArgumentNext
+                _ => ArgumentNext,
             }
         }
     }
@@ -279,7 +292,9 @@ fn format(&mut self) -> FormatSpec<'a> {
             width: CountImplied,
             ty: &self.input[..0],
         };
-        if !self.consume(':') { return spec }
+        if !self.consume(':') {
+            return spec
+        }
 
         // fill character
         if let Some(&(_, c)) = self.cur.peek() {
@@ -347,7 +362,11 @@ fn format(&mut self) -> FormatSpec<'a> {
     /// width.
     fn count(&mut self) -> Count<'a> {
         if let Some(i) = self.integer() {
-            if self.consume('$') { CountIsParam(i) } else { CountIs(i) }
+            if self.consume('$') {
+                CountIsParam(i)
+            } else {
+                CountIs(i)
+            }
         } else {
             let tmp = self.cur.clone();
             let word = self.word();
@@ -370,8 +389,13 @@ fn count(&mut self) -> Count<'a> {
     /// characters.
     fn word(&mut self) -> &'a str {
         let start = match self.cur.peek() {
-            Some(&(pos, c)) if c.is_xid_start() => { self.cur.next(); pos }
-            _ => { return &self.input[..0]; }
+            Some(&(pos, c)) if c.is_xid_start() => {
+                self.cur.next();
+                pos
+            }
+            _ => {
+                return &self.input[..0];
+            }
         };
         while let Some(&(pos, c)) = self.cur.peek() {
             if c.is_xid_continue() {
@@ -397,7 +421,11 @@ fn integer(&mut self) -> Option<usize> {
                 break
             }
         }
-        if found { Some(cur) } else { None }
+        if found {
+            Some(cur)
+        } else {
+            None
+        }
     }
 }
 
@@ -437,178 +465,210 @@ fn simple() {
         same("\\}}", &[String("\\"), String("}")]);
     }
 
-    #[test] fn invalid01() { musterr("{") }
-    #[test] fn invalid02() { musterr("}") }
-    #[test] fn invalid04() { musterr("{3a}") }
-    #[test] fn invalid05() { musterr("{:|}") }
-    #[test] fn invalid06() { musterr("{:>>>}") }
+    #[test]
+    fn invalid01() {
+        musterr("{")
+    }
+    #[test]
+    fn invalid02() {
+        musterr("}")
+    }
+    #[test]
+    fn invalid04() {
+        musterr("{3a}")
+    }
+    #[test]
+    fn invalid05() {
+        musterr("{:|}")
+    }
+    #[test]
+    fn invalid06() {
+        musterr("{:>>>}")
+    }
 
     #[test]
     fn format_nothing() {
-        same("{}", &[NextArgument(Argument {
-            position: ArgumentNext,
-            format: fmtdflt(),
-        })]);
+        same("{}",
+             &[NextArgument(Argument {
+                   position: ArgumentNext,
+                   format: fmtdflt(),
+               })]);
     }
     #[test]
     fn format_position() {
-        same("{3}", &[NextArgument(Argument {
-            position: ArgumentIs(3),
-            format: fmtdflt(),
-        })]);
+        same("{3}",
+             &[NextArgument(Argument {
+                   position: ArgumentIs(3),
+                   format: fmtdflt(),
+               })]);
     }
     #[test]
     fn format_position_nothing_else() {
-        same("{3:}", &[NextArgument(Argument {
-            position: ArgumentIs(3),
-            format: fmtdflt(),
-        })]);
+        same("{3:}",
+             &[NextArgument(Argument {
+                   position: ArgumentIs(3),
+                   format: fmtdflt(),
+               })]);
     }
     #[test]
     fn format_type() {
-        same("{3:a}", &[NextArgument(Argument {
-            position: ArgumentIs(3),
-            format: FormatSpec {
-                fill: None,
-                align: AlignUnknown,
-                flags: 0,
-                precision: CountImplied,
-                width: CountImplied,
-                ty: "a",
-            },
-        })]);
+        same("{3:a}",
+             &[NextArgument(Argument {
+                   position: ArgumentIs(3),
+                   format: FormatSpec {
+                       fill: None,
+                       align: AlignUnknown,
+                       flags: 0,
+                       precision: CountImplied,
+                       width: CountImplied,
+                       ty: "a",
+                   },
+               })]);
     }
     #[test]
     fn format_align_fill() {
-        same("{3:>}", &[NextArgument(Argument {
-            position: ArgumentIs(3),
-            format: FormatSpec {
-                fill: None,
-                align: AlignRight,
-                flags: 0,
-                precision: CountImplied,
-                width: CountImplied,
-                ty: "",
-            },
-        })]);
-        same("{3:0<}", &[NextArgument(Argument {
-            position: ArgumentIs(3),
-            format: FormatSpec {
-                fill: Some('0'),
-                align: AlignLeft,
-                flags: 0,
-                precision: CountImplied,
-                width: CountImplied,
-                ty: "",
-            },
-        })]);
-        same("{3:*<abcd}", &[NextArgument(Argument {
-            position: ArgumentIs(3),
-            format: FormatSpec {
-                fill: Some('*'),
-                align: AlignLeft,
-                flags: 0,
-                precision: CountImplied,
-                width: CountImplied,
-                ty: "abcd",
-            },
-        })]);
+        same("{3:>}",
+             &[NextArgument(Argument {
+                   position: ArgumentIs(3),
+                   format: FormatSpec {
+                       fill: None,
+                       align: AlignRight,
+                       flags: 0,
+                       precision: CountImplied,
+                       width: CountImplied,
+                       ty: "",
+                   },
+               })]);
+        same("{3:0<}",
+             &[NextArgument(Argument {
+                   position: ArgumentIs(3),
+                   format: FormatSpec {
+                       fill: Some('0'),
+                       align: AlignLeft,
+                       flags: 0,
+                       precision: CountImplied,
+                       width: CountImplied,
+                       ty: "",
+                   },
+               })]);
+        same("{3:*<abcd}",
+             &[NextArgument(Argument {
+                   position: ArgumentIs(3),
+                   format: FormatSpec {
+                       fill: Some('*'),
+                       align: AlignLeft,
+                       flags: 0,
+                       precision: CountImplied,
+                       width: CountImplied,
+                       ty: "abcd",
+                   },
+               })]);
     }
     #[test]
     fn format_counts() {
-        same("{:10s}", &[NextArgument(Argument {
-            position: ArgumentNext,
-            format: FormatSpec {
-                fill: None,
-                align: AlignUnknown,
-                flags: 0,
-                precision: CountImplied,
-                width: CountIs(10),
-                ty: "s",
-            },
-        })]);
-        same("{:10$.10s}", &[NextArgument(Argument {
-            position: ArgumentNext,
-            format: FormatSpec {
-                fill: None,
-                align: AlignUnknown,
-                flags: 0,
-                precision: CountIs(10),
-                width: CountIsParam(10),
-                ty: "s",
-            },
-        })]);
-        same("{:.*s}", &[NextArgument(Argument {
-            position: ArgumentNext,
-            format: FormatSpec {
-                fill: None,
-                align: AlignUnknown,
-                flags: 0,
-                precision: CountIsNextParam,
-                width: CountImplied,
-                ty: "s",
-            },
-        })]);
-        same("{:.10$s}", &[NextArgument(Argument {
-            position: ArgumentNext,
-            format: FormatSpec {
-                fill: None,
-                align: AlignUnknown,
-                flags: 0,
-                precision: CountIsParam(10),
-                width: CountImplied,
-                ty: "s",
-            },
-        })]);
-        same("{:a$.b$s}", &[NextArgument(Argument {
-            position: ArgumentNext,
-            format: FormatSpec {
-                fill: None,
-                align: AlignUnknown,
-                flags: 0,
-                precision: CountIsName("b"),
-                width: CountIsName("a"),
-                ty: "s",
-            },
-        })]);
+        same("{:10s}",
+             &[NextArgument(Argument {
+                   position: ArgumentNext,
+                   format: FormatSpec {
+                       fill: None,
+                       align: AlignUnknown,
+                       flags: 0,
+                       precision: CountImplied,
+                       width: CountIs(10),
+                       ty: "s",
+                   },
+               })]);
+        same("{:10$.10s}",
+             &[NextArgument(Argument {
+                   position: ArgumentNext,
+                   format: FormatSpec {
+                       fill: None,
+                       align: AlignUnknown,
+                       flags: 0,
+                       precision: CountIs(10),
+                       width: CountIsParam(10),
+                       ty: "s",
+                   },
+               })]);
+        same("{:.*s}",
+             &[NextArgument(Argument {
+                   position: ArgumentNext,
+                   format: FormatSpec {
+                       fill: None,
+                       align: AlignUnknown,
+                       flags: 0,
+                       precision: CountIsNextParam,
+                       width: CountImplied,
+                       ty: "s",
+                   },
+               })]);
+        same("{:.10$s}",
+             &[NextArgument(Argument {
+                   position: ArgumentNext,
+                   format: FormatSpec {
+                       fill: None,
+                       align: AlignUnknown,
+                       flags: 0,
+                       precision: CountIsParam(10),
+                       width: CountImplied,
+                       ty: "s",
+                   },
+               })]);
+        same("{:a$.b$s}",
+             &[NextArgument(Argument {
+                   position: ArgumentNext,
+                   format: FormatSpec {
+                       fill: None,
+                       align: AlignUnknown,
+                       flags: 0,
+                       precision: CountIsName("b"),
+                       width: CountIsName("a"),
+                       ty: "s",
+                   },
+               })]);
     }
     #[test]
     fn format_flags() {
-        same("{:-}", &[NextArgument(Argument {
-            position: ArgumentNext,
-            format: FormatSpec {
-                fill: None,
-                align: AlignUnknown,
-                flags: (1 << FlagSignMinus as u32),
-                precision: CountImplied,
-                width: CountImplied,
-                ty: "",
-            },
-        })]);
-        same("{:+#}", &[NextArgument(Argument {
-            position: ArgumentNext,
-            format: FormatSpec {
-                fill: None,
-                align: AlignUnknown,
-                flags: (1 << FlagSignPlus as u32) | (1 << FlagAlternate as u32),
-                precision: CountImplied,
-                width: CountImplied,
-                ty: "",
-            },
-        })]);
+        same("{:-}",
+             &[NextArgument(Argument {
+                   position: ArgumentNext,
+                   format: FormatSpec {
+                       fill: None,
+                       align: AlignUnknown,
+                       flags: (1 << FlagSignMinus as u32),
+                       precision: CountImplied,
+                       width: CountImplied,
+                       ty: "",
+                   },
+               })]);
+        same("{:+#}",
+             &[NextArgument(Argument {
+                   position: ArgumentNext,
+                   format: FormatSpec {
+                       fill: None,
+                       align: AlignUnknown,
+                       flags: (1 << FlagSignPlus as u32) | (1 << FlagAlternate as u32),
+                       precision: CountImplied,
+                       width: CountImplied,
+                       ty: "",
+                   },
+               })]);
     }
     #[test]
     fn format_mixture() {
-        same("abcd {3:a} efg", &[String("abcd "), NextArgument(Argument {
-            position: ArgumentIs(3),
-            format: FormatSpec {
-                fill: None,
-                align: AlignUnknown,
-                flags: 0,
-                precision: CountImplied,
-                width: CountImplied,
-                ty: "a",
-            },
-        }), String(" efg")]);
+        same("abcd {3:a} efg",
+             &[String("abcd "),
+               NextArgument(Argument {
+                   position: ArgumentIs(3),
+                   format: FormatSpec {
+                       fill: None,
+                       align: AlignUnknown,
+                       flags: 0,
+                       precision: CountImplied,
+                       width: CountImplied,
+                       ty: "a",
+                   },
+               }),
+               String(" efg")]);
     }
 }
index 7fafe97efc9ee34c156c108607d8fd28fff5dfa3..b82b7d122b3ce8205c760602202243faed391eeb 100644 (file)
@@ -456,7 +456,7 @@ pub trait Labeller<'a,N,E> {
     fn graph_id(&'a self) -> Id<'a>;
 
     /// Maps `n` to a unique identifier with respect to `self`. The
-    /// implementer is responsible for ensuring that the returned name
+    /// implementor is responsible for ensuring that the returned name
     /// is a valid DOT identifier.
     fn node_id(&'a self, n: &N) -> Id<'a>;
 
@@ -594,7 +594,7 @@ pub fn suffix_line(self, suffix: LabelText) -> LabelText<'static> {
 /// that is bound by the self lifetime `'a`.
 ///
 /// The `nodes` and `edges` method each return instantiations of
-/// `Cow<[T]>` to leave implementers the freedom to create
+/// `Cow<[T]>` to leave implementors the freedom to create
 /// entirely new vectors or to pass back slices into internally owned
 /// vectors.
 pub trait GraphWalk<'a, N: Clone, E: Clone> {
index 362303869d78ddcbb17d03c0ab870130d88499e1..3958969cfca3200936f2143e2297b792f2180814 100644 (file)
@@ -17,15 +17,17 @@ pub struct LogDirective {
     pub level: u32,
 }
 
-pub const LOG_LEVEL_NAMES: [&'static str; 4] = ["ERROR", "WARN", "INFO",
-                                               "DEBUG"];
+pub const LOG_LEVEL_NAMES: [&'static str; 4] = ["ERROR", "WARN", "INFO", "DEBUG"];
 
 /// Parse an individual log level that is either a number or a symbolic log level
 fn parse_log_level(level: &str) -> Option<u32> {
-    level.parse::<u32>().ok().or_else(|| {
-        let pos = LOG_LEVEL_NAMES.iter().position(|&name| name.eq_ignore_ascii_case(level));
-        pos.map(|p| p as u32 + 1)
-    }).map(|p| cmp::min(p, ::MAX_LOG_LEVEL))
+    level.parse::<u32>()
+         .ok()
+         .or_else(|| {
+             let pos = LOG_LEVEL_NAMES.iter().position(|&name| name.eq_ignore_ascii_case(level));
+             pos.map(|p| p as u32 + 1)
+         })
+         .map(|p| cmp::min(p, ::MAX_LOG_LEVEL))
 }
 
 /// Parse a logging specification string (e.g: "crate1,crate2::mod3,crate3::x=1/foo")
@@ -40,44 +42,48 @@ pub fn parse_logging_spec(spec: &str) -> (Vec<LogDirective>, Option<String>) {
     let mods = parts.next();
     let filter = parts.next();
     if parts.next().is_some() {
-        println!("warning: invalid logging spec '{}', \
-                 ignoring it (too many '/'s)", spec);
+        println!("warning: invalid logging spec '{}', ignoring it (too many '/'s)",
+                 spec);
         return (dirs, None);
     }
-    mods.map(|m| { for s in m.split(',') {
-        if s.is_empty() { continue }
-        let mut parts = s.split('=');
-        let (log_level, name) = match (parts.next(), parts.next().map(|s| s.trim()), parts.next()) {
-            (Some(part0), None, None) => {
-                // if the single argument is a log-level string or number,
-                // treat that as a global fallback
-                match parse_log_level(part0) {
-                    Some(num) => (num, None),
-                    None => (::MAX_LOG_LEVEL, Some(part0)),
-                }
+    if let Some(m) = mods {
+        for s in m.split(',') {
+            if s.is_empty() {
+                continue
             }
-            (Some(part0), Some(""), None) => (::MAX_LOG_LEVEL, Some(part0)),
-            (Some(part0), Some(part1), None) => {
-                match parse_log_level(part1) {
-                    Some(num) => (num, Some(part0)),
-                    _ => {
-                        println!("warning: invalid logging spec '{}', \
-                                 ignoring it", part1);
-                        continue
+            let mut parts = s.split('=');
+            let (log_level, name) = match (parts.next(),
+                                           parts.next().map(|s| s.trim()),
+                                           parts.next()) {
+                (Some(part0), None, None) => {
+                    // if the single argument is a log-level string or number,
+                    // treat that as a global fallback
+                    match parse_log_level(part0) {
+                        Some(num) => (num, None),
+                        None => (::MAX_LOG_LEVEL, Some(part0)),
                     }
                 }
-            },
-            _ => {
-                println!("warning: invalid logging spec '{}', \
-                         ignoring it", s);
-                continue
-            }
-        };
-        dirs.push(LogDirective {
-            name: name.map(str::to_owned),
-            level: log_level,
-        });
-    }});
+                (Some(part0), Some(""), None) => (::MAX_LOG_LEVEL, Some(part0)),
+                (Some(part0), Some(part1), None) => {
+                    match parse_log_level(part1) {
+                        Some(num) => (num, Some(part0)),
+                        _ => {
+                            println!("warning: invalid logging spec '{}', ignoring it", part1);
+                            continue
+                        }
+                    }
+                }
+                _ => {
+                    println!("warning: invalid logging spec '{}', ignoring it", s);
+                    continue
+                }
+            };
+            dirs.push(LogDirective {
+                name: name.map(str::to_owned),
+                level: log_level,
+            });
+        }
+    }
 
     (dirs, filter.map(str::to_owned))
 }
index 2c91a88f6ec9e8a5efd561757d0d321cb47ee7e3..9cb835bd8525d583c99eab127bd178f5048ad2cb 100644 (file)
@@ -235,7 +235,9 @@ pub trait Logger {
     fn log(&mut self, record: &LogRecord);
 }
 
-struct DefaultLogger { handle: Stderr }
+struct DefaultLogger {
+    handle: Stderr,
+}
 
 /// Wraps the log level with fmt implementations.
 #[derive(Copy, Clone, PartialEq, PartialOrd, Debug)]
@@ -246,7 +248,7 @@ fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
         let LogLevel(level) = *self;
         match LOG_LEVEL_NAMES.get(level as usize - 1) {
             Some(ref name) => fmt::Display::fmt(name, fmt),
-            None => fmt::Display::fmt(&level, fmt)
+            None => fmt::Display::fmt(&level, fmt),
         }
     }
 }
@@ -301,11 +303,10 @@ pub fn log(level: u32, loc: &'static LogLocation, args: fmt::Arguments) {
     // Completely remove the local logger from TLS in case anyone attempts to
     // frob the slot while we're doing the logging. This will destroy any logger
     // set during logging.
-    let mut logger: Box<Logger + Send> = LOCAL_LOGGER.with(|s| {
-        s.borrow_mut().take()
-    }).unwrap_or_else(|| {
-        box DefaultLogger { handle: io::stderr() }
-    });
+    let mut logger: Box<Logger + Send> = LOCAL_LOGGER.with(|s| s.borrow_mut().take())
+                                                     .unwrap_or_else(|| {
+                                                         box DefaultLogger { handle: io::stderr() }
+                                                     });
     logger.log(&LogRecord {
         level: LogLevel(level),
         args: args,
@@ -320,22 +321,20 @@ pub fn log(level: u32, loc: &'static LogLocation, args: fmt::Arguments) {
 /// safely
 #[doc(hidden)]
 #[inline(always)]
-pub fn log_level() -> u32 { unsafe { LOG_LEVEL } }
+pub fn log_level() -> u32 {
+    unsafe { LOG_LEVEL }
+}
 
 /// Replaces the thread-local logger with the specified logger, returning the old
 /// logger.
 pub fn set_logger(logger: Box<Logger + Send>) -> Option<Box<Logger + Send>> {
-    let mut l = Some(logger);
-    LOCAL_LOGGER.with(|slot| {
-        mem::replace(&mut *slot.borrow_mut(), l.take())
-    })
+    LOCAL_LOGGER.with(|slot| mem::replace(&mut *slot.borrow_mut(), Some(logger)))
 }
 
 /// A LogRecord is created by the logging macros, and passed as the only
 /// argument to Loggers.
 #[derive(Debug)]
 pub struct LogRecord<'a> {
-
     /// The module path of where the LogRecord originated.
     pub module_path: &'a str,
 
@@ -373,7 +372,9 @@ pub fn mod_enabled(level: u32, module: &str) -> bool {
     // 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.
-    if level > unsafe { LOG_LEVEL } { return false }
+    if level > unsafe { LOG_LEVEL } {
+        return false
+    }
 
     // This assertion should never get tripped unless we're in an at_exit
     // handler after logging has been torn down and a logging attempt was made.
@@ -385,14 +386,11 @@ pub fn mod_enabled(level: u32, module: &str) -> bool {
     }
 }
 
-fn enabled(level: u32,
-           module: &str,
-           iter: slice::Iter<directive::LogDirective>)
-           -> bool {
+fn enabled(level: u32, module: &str, iter: slice::Iter<directive::LogDirective>) -> bool {
     // Search for the longest match, the vector is assumed to be pre-sorted.
     for directive in iter.rev() {
         match directive.name {
-            Some(ref name) if !module.starts_with(&name[..]) => {},
+            Some(ref name) if !module.starts_with(&name[..]) => {}
             Some(..) | None => {
                 return level <= directive.level
             }
@@ -445,16 +443,14 @@ mod tests {
 
     #[test]
     fn match_full_path() {
-        let dirs = [
-            LogDirective {
-                name: Some("crate2".to_string()),
-                level: 3
-            },
-            LogDirective {
-                name: Some("crate1::mod1".to_string()),
-                level: 2
-            }
-        ];
+        let dirs = [LogDirective {
+                        name: Some("crate2".to_string()),
+                        level: 3,
+                    },
+                    LogDirective {
+                        name: Some("crate1::mod1".to_string()),
+                        level: 2,
+                    }];
         assert!(enabled(2, "crate1::mod1", dirs.iter()));
         assert!(!enabled(3, "crate1::mod1", dirs.iter()));
         assert!(enabled(3, "crate2", dirs.iter()));
@@ -463,49 +459,72 @@ fn match_full_path() {
 
     #[test]
     fn no_match() {
-        let dirs = [
-            LogDirective { name: Some("crate2".to_string()), level: 3 },
-            LogDirective { name: Some("crate1::mod1".to_string()), level: 2 }
-        ];
+        let dirs = [LogDirective {
+                        name: Some("crate2".to_string()),
+                        level: 3,
+                    },
+                    LogDirective {
+                        name: Some("crate1::mod1".to_string()),
+                        level: 2,
+                    }];
         assert!(!enabled(2, "crate3", dirs.iter()));
     }
 
     #[test]
     fn match_beginning() {
-        let dirs = [
-            LogDirective { name: Some("crate2".to_string()), level: 3 },
-            LogDirective { name: Some("crate1::mod1".to_string()), level: 2 }
-        ];
+        let dirs = [LogDirective {
+                        name: Some("crate2".to_string()),
+                        level: 3,
+                    },
+                    LogDirective {
+                        name: Some("crate1::mod1".to_string()),
+                        level: 2,
+                    }];
         assert!(enabled(3, "crate2::mod1", dirs.iter()));
     }
 
     #[test]
     fn match_beginning_longest_match() {
-        let dirs = [
-            LogDirective { name: Some("crate2".to_string()), level: 3 },
-            LogDirective { name: Some("crate2::mod".to_string()), level: 4 },
-            LogDirective { name: Some("crate1::mod1".to_string()), level: 2 }
-        ];
+        let dirs = [LogDirective {
+                        name: Some("crate2".to_string()),
+                        level: 3,
+                    },
+                    LogDirective {
+                        name: Some("crate2::mod".to_string()),
+                        level: 4,
+                    },
+                    LogDirective {
+                        name: Some("crate1::mod1".to_string()),
+                        level: 2,
+                    }];
         assert!(enabled(4, "crate2::mod1", dirs.iter()));
         assert!(!enabled(4, "crate2", dirs.iter()));
     }
 
     #[test]
     fn match_default() {
-        let dirs = [
-            LogDirective { name: None, level: 3 },
-            LogDirective { name: Some("crate1::mod1".to_string()), level: 2 }
-        ];
+        let dirs = [LogDirective {
+                        name: None,
+                        level: 3,
+                    },
+                    LogDirective {
+                        name: Some("crate1::mod1".to_string()),
+                        level: 2,
+                    }];
         assert!(enabled(2, "crate1::mod1", dirs.iter()));
         assert!(enabled(3, "crate2::mod2", dirs.iter()));
     }
 
     #[test]
     fn zero_level() {
-        let dirs = [
-            LogDirective { name: None, level: 3 },
-            LogDirective { name: Some("crate1::mod1".to_string()), level: 0 }
-        ];
+        let dirs = [LogDirective {
+                        name: None,
+                        level: 3,
+                    },
+                    LogDirective {
+                        name: Some("crate1::mod1".to_string()),
+                        level: 0,
+                    }];
         assert!(!enabled(1, "crate1::mod1", dirs.iter()));
         assert!(enabled(3, "crate2::mod2", dirs.iter()));
     }
index 2a5d4bbd2ec9db6818df0f201771fa148167cd8e..83d82e433064346825374922611aec6259fc69a9 100644 (file)
@@ -168,7 +168,7 @@ fn ind_sample<R: Rng>(&self, rng: &mut R) -> f64 {
 ///
 /// For `k > 0` integral, this distribution is the sum of the squares
 /// of `k` independent standard normal random variables. For other
-/// `k`, this uses the equivalent characterisation `χ²(k) = Gamma(k/2,
+/// `k`, this uses the equivalent characterization `χ²(k) = Gamma(k/2,
 /// 2)`.
 pub struct ChiSquared {
     repr: ChiSquaredRepr,
index cc70a695c8d594c1ab85cac67006c7a1ad77cd5c..7fe8b6e8806e9950073c52d65b2b9187ebf8466e 100644 (file)
 pub struct StandardNormal(pub f64);
 
 impl Rand for StandardNormal {
-    fn rand<R:Rng>(rng: &mut R) -> StandardNormal {
+    fn rand<R: Rng>(rng: &mut R) -> StandardNormal {
         #[inline]
         fn pdf(x: f64) -> f64 {
-            (-x*x/2.0).exp()
+            (-x * x / 2.0).exp()
         }
         #[inline]
-        fn zero_case<R:Rng>(rng: &mut R, u: f64) -> f64 {
+        fn zero_case<R: Rng>(rng: &mut R, u: f64) -> f64 {
             // compute a random number in the tail by hand
 
             // strange initial conditions, because the loop is not
@@ -56,15 +56,19 @@ fn zero_case<R:Rng>(rng: &mut R, u: f64) -> f64 {
                 y = y_.ln();
             }
 
-            if u < 0.0 { x - ziggurat_tables::ZIG_NORM_R } else { ziggurat_tables::ZIG_NORM_R - x }
+            if u < 0.0 {
+                x - ziggurat_tables::ZIG_NORM_R
+            } else {
+                ziggurat_tables::ZIG_NORM_R - x
+            }
         }
 
-        StandardNormal(ziggurat(
-            rng,
-            true, // this is symmetric
-            &ziggurat_tables::ZIG_NORM_X,
-            &ziggurat_tables::ZIG_NORM_F,
-            pdf, zero_case))
+        StandardNormal(ziggurat(rng,
+                                true, // this is symmetric
+                                &ziggurat_tables::ZIG_NORM_X,
+                                &ziggurat_tables::ZIG_NORM_F,
+                                pdf,
+                                zero_case))
     }
 }
 
@@ -89,12 +93,14 @@ pub fn new(mean: f64, std_dev: f64) -> Normal {
         assert!(std_dev >= 0.0, "Normal::new called with `std_dev` < 0");
         Normal {
             mean: mean,
-            std_dev: std_dev
+            std_dev: std_dev,
         }
     }
 }
 impl Sample<f64> for Normal {
-    fn sample<R: Rng>(&mut self, rng: &mut R) -> f64 { self.ind_sample(rng) }
+    fn sample<R: Rng>(&mut self, rng: &mut R) -> f64 {
+        self.ind_sample(rng)
+    }
 }
 impl IndependentSample<f64> for Normal {
     fn ind_sample<R: Rng>(&self, rng: &mut R) -> f64 {
@@ -110,7 +116,7 @@ fn ind_sample<R: Rng>(&self, rng: &mut R) -> f64 {
 /// std_dev**2)` distributed.
 #[derive(Copy, Clone)]
 pub struct LogNormal {
-    norm: Normal
+    norm: Normal,
 }
 
 impl LogNormal {
@@ -126,7 +132,9 @@ pub fn new(mean: f64, std_dev: f64) -> LogNormal {
     }
 }
 impl Sample<f64> for LogNormal {
-    fn sample<R: Rng>(&mut self, rng: &mut R) -> f64 { self.ind_sample(rng) }
+    fn sample<R: Rng>(&mut self, rng: &mut R) -> f64 {
+        self.ind_sample(rng)
+    }
 }
 impl IndependentSample<f64> for LogNormal {
     fn ind_sample<R: Rng>(&self, rng: &mut R) -> f64 {
@@ -179,7 +187,7 @@ mod bench {
     use std::prelude::v1::*;
     use self::test::Bencher;
     use std::mem::size_of;
-    use distributions::{Sample};
+    use distributions::Sample;
     use super::Normal;
 
     #[bench]
index 5f3148c7c33c57571882e009d36932884f324fa7..fc7531d3f61bae924d5091dbd6ec080c59cd7cf6 100644 (file)
@@ -134,26 +134,15 @@ fn visit_item(&mut self, i: &'ast Item) {
             ItemEnum(ref enum_definition, _) => {
                 for v in &enum_definition.variants {
                     let variant_def_index =
-                        self.insert_def(v.node.id,
+                        self.insert_def(v.node.data.id(),
                                         NodeVariant(&**v),
                                         DefPathData::EnumVariant(v.node.name));
 
-                    match v.node.kind {
-                        TupleVariantKind(ref args) => {
-                            for arg in args {
-                                self.create_def_with_parent(Some(variant_def_index),
-                                                            arg.id,
-                                                            DefPathData::PositionalField);
-                            }
-                        }
-                        StructVariantKind(ref def) => {
-                            for field in &def.fields {
-                                self.create_def_with_parent(
-                                    Some(variant_def_index),
-                                    field.node.id,
-                                    DefPathData::Field(field.node.kind));
-                            }
-                        }
+                    for field in v.node.data.fields() {
+                        self.create_def_with_parent(
+                            Some(variant_def_index),
+                            field.node.id,
+                            DefPathData::Field(field.node.kind));
                     }
                 }
             }
@@ -161,13 +150,13 @@ fn visit_item(&mut self, i: &'ast Item) {
             }
             ItemStruct(ref struct_def, _) => {
                 // If this is a tuple-like struct, register the constructor.
-                if let Some(ctor_id) = struct_def.ctor_id {
-                    self.insert_def(ctor_id,
+                if !struct_def.is_struct() {
+                    self.insert_def(struct_def.id(),
                                     NodeStructCtor(&**struct_def),
                                     DefPathData::StructCtor);
                 }
 
-                for field in &struct_def.fields {
+                for field in struct_def.fields() {
                     self.create_def(field.node.id, DefPathData::Field(field.node.kind));
                 }
             }
index 396e2bb5703b1ddd5b4b54ef9b0f93d864386846..2d84f6fc2bea8329ab0e24aa25877810924cdb0e 100644 (file)
@@ -124,7 +124,7 @@ pub enum Node<'ast> {
     NodeBlock(&'ast Block),
 
     /// NodeStructCtor represents a tuple struct.
-    NodeStructCtor(&'ast StructDef),
+    NodeStructCtor(&'ast VariantData),
 
     NodeLifetime(&'ast Lifetime),
     NodeTyParam(&'ast TyParam)
@@ -149,7 +149,7 @@ pub enum MapEntry<'ast> {
     EntryLocal(NodeId, &'ast Pat),
     EntryPat(NodeId, &'ast Pat),
     EntryBlock(NodeId, &'ast Block),
-    EntryStructCtor(NodeId, &'ast StructDef),
+    EntryStructCtor(NodeId, &'ast VariantData),
     EntryLifetime(NodeId, &'ast Lifetime),
     EntryTyParam(NodeId, &'ast TyParam),
 
@@ -471,18 +471,19 @@ pub fn expect_trait_item(&self, id: NodeId) -> &'ast TraitItem {
         }
     }
 
-    pub fn expect_struct(&self, id: NodeId) -> &'ast StructDef {
+    pub fn expect_struct(&self, id: NodeId) -> &'ast VariantData {
         match self.find(id) {
             Some(NodeItem(i)) => {
                 match i.node {
-                    ItemStruct(ref struct_def, _) => &**struct_def,
+                    ItemStruct(ref struct_def, _) => struct_def,
                     _ => panic!("struct ID bound to non-struct")
                 }
             }
             Some(NodeVariant(variant)) => {
-                match variant.node.kind {
-                    StructVariantKind(ref struct_def) => &**struct_def,
-                    _ => panic!("struct ID bound to enum variant that isn't struct-like"),
+                if variant.node.data.is_struct() {
+                    &variant.node.data
+                } else {
+                    panic!("struct ID bound to enum variant that isn't struct-like")
                 }
             }
             _ => panic!(format!("expected struct, found {}", self.node_to_string(id))),
@@ -527,6 +528,10 @@ pub fn get_path_elem(&self, id: NodeId) -> PathElem {
             NodeTraitItem(ti) => PathName(ti.name),
             NodeVariant(v) => PathName(v.node.name),
             NodeLifetime(lt) => PathName(lt.name),
+            NodeTyParam(tp) => PathName(tp.name),
+            NodeLocal(&Pat { node: PatIdent(_,l,_), .. }) => {
+                PathName(l.node.name)
+            },
             _ => panic!("no path elem for {:?}", node)
         }
     }
@@ -987,4 +992,3 @@ fn node_id_to_string(map: &Map, id: NodeId, include_id: bool) -> String {
         }
     }
 }
-
index 36236efe50d2c38e8e81fc5ef38afa77c4aeb394..f5c6cfe2437dcc66610b33d4cb58636946888af1 100644 (file)
@@ -661,14 +661,15 @@ fn visit_fn(&mut self, fk: hir_visit::FnKind<'v>, decl: &'v hir::FnDecl,
         hir_visit::walk_fn(self, fk, decl, body, span);
     }
 
-    fn visit_struct_def(&mut self,
-                        s: &hir::StructDef,
+    fn visit_variant_data(&mut self,
+                        s: &hir::VariantData,
                         name: ast::Name,
                         g: &hir::Generics,
-                        id: ast::NodeId) {
-        run_lints!(self, check_struct_def, late_passes, s, name, g, id);
+                        item_id: ast::NodeId,
+                        _: Span) {
+        run_lints!(self, check_struct_def, late_passes, s, name, g, item_id);
         hir_visit::walk_struct_def(self, s);
-        run_lints!(self, check_struct_def_post, late_passes, s, name, g, id);
+        run_lints!(self, check_struct_def_post, late_passes, s, name, g, item_id);
     }
 
     fn visit_struct_field(&mut self, s: &hir::StructField) {
@@ -678,10 +679,10 @@ fn visit_struct_field(&mut self, s: &hir::StructField) {
         })
     }
 
-    fn visit_variant(&mut self, v: &hir::Variant, g: &hir::Generics) {
+    fn visit_variant(&mut self, v: &hir::Variant, g: &hir::Generics, item_id: ast::NodeId) {
         self.with_lint_attrs(&v.node.attrs, |cx| {
             run_lints!(cx, check_variant, late_passes, v, g);
-            hir_visit::walk_variant(cx, v, g);
+            hir_visit::walk_variant(cx, v, g, item_id);
             run_lints!(cx, check_variant_post, late_passes, v, g);
         })
     }
@@ -810,14 +811,15 @@ fn visit_fn(&mut self, fk: ast_visit::FnKind<'v>, decl: &'v ast::FnDecl,
         ast_visit::walk_fn(self, fk, decl, body, span);
     }
 
-    fn visit_struct_def(&mut self,
-                        s: &ast::StructDef,
+    fn visit_variant_data(&mut self,
+                        s: &ast::VariantData,
                         ident: ast::Ident,
                         g: &ast::Generics,
-                        id: ast::NodeId) {
-        run_lints!(self, check_struct_def, early_passes, s, ident, g, id);
+                        item_id: ast::NodeId,
+                        _: Span) {
+        run_lints!(self, check_struct_def, early_passes, s, ident, g, item_id);
         ast_visit::walk_struct_def(self, s);
-        run_lints!(self, check_struct_def_post, early_passes, s, ident, g, id);
+        run_lints!(self, check_struct_def_post, early_passes, s, ident, g, item_id);
     }
 
     fn visit_struct_field(&mut self, s: &ast::StructField) {
@@ -827,10 +829,10 @@ fn visit_struct_field(&mut self, s: &ast::StructField) {
         })
     }
 
-    fn visit_variant(&mut self, v: &ast::Variant, g: &ast::Generics) {
+    fn visit_variant(&mut self, v: &ast::Variant, g: &ast::Generics, item_id: ast::NodeId) {
         self.with_lint_attrs(&v.node.attrs, |cx| {
             run_lints!(cx, check_variant, early_passes, v, g);
-            ast_visit::walk_variant(cx, v, g);
+            ast_visit::walk_variant(cx, v, g, item_id);
             run_lints!(cx, check_variant_post, early_passes, v, g);
         })
     }
index 5c316b58303fe5a2ee8377bb3fa17265658b5730..14c11af6f3863293f4f4e51dee855bad2bf3ef2a 100644 (file)
@@ -150,9 +150,9 @@ fn check_fn(&mut self, _: &LateContext,
     fn check_trait_item(&mut self, _: &LateContext, _: &hir::TraitItem) { }
     fn check_impl_item(&mut self, _: &LateContext, _: &hir::ImplItem) { }
     fn check_struct_def(&mut self, _: &LateContext,
-        _: &hir::StructDef, _: ast::Name, _: &hir::Generics, _: ast::NodeId) { }
+        _: &hir::VariantData, _: ast::Name, _: &hir::Generics, _: ast::NodeId) { }
     fn check_struct_def_post(&mut self, _: &LateContext,
-        _: &hir::StructDef, _: ast::Name, _: &hir::Generics, _: ast::NodeId) { }
+        _: &hir::VariantData, _: ast::Name, _: &hir::Generics, _: ast::NodeId) { }
     fn check_struct_field(&mut self, _: &LateContext, _: &hir::StructField) { }
     fn check_variant(&mut self, _: &LateContext, _: &hir::Variant, _: &hir::Generics) { }
     fn check_variant_post(&mut self, _: &LateContext, _: &hir::Variant, _: &hir::Generics) { }
@@ -192,9 +192,9 @@ fn check_fn(&mut self, _: &EarlyContext,
     fn check_trait_item(&mut self, _: &EarlyContext, _: &ast::TraitItem) { }
     fn check_impl_item(&mut self, _: &EarlyContext, _: &ast::ImplItem) { }
     fn check_struct_def(&mut self, _: &EarlyContext,
-        _: &ast::StructDef, _: ast::Ident, _: &ast::Generics, _: ast::NodeId) { }
+        _: &ast::VariantData, _: ast::Ident, _: &ast::Generics, _: ast::NodeId) { }
     fn check_struct_def_post(&mut self, _: &EarlyContext,
-        _: &ast::StructDef, _: ast::Ident, _: &ast::Generics, _: ast::NodeId) { }
+        _: &ast::VariantData, _: ast::Ident, _: &ast::Generics, _: ast::NodeId) { }
     fn check_struct_field(&mut self, _: &EarlyContext, _: &ast::StructField) { }
     fn check_variant(&mut self, _: &EarlyContext, _: &ast::Variant, _: &ast::Generics) { }
     fn check_variant_post(&mut self, _: &EarlyContext, _: &ast::Variant, _: &ast::Generics) { }
index 9d2b1548f29d87c3a4e1dcfec371ae6f05465d70..8e2c2e6a0bfbd2d0ce8fc09f787ee967edf3bd91 100644 (file)
@@ -315,7 +315,7 @@ fn encode_enum_variant_info<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>,
         let vid = variant.did;
         let variant_node_id = ecx.local_id(vid);
 
-        if let ty::VariantKind::Dict = variant.kind() {
+        if let ty::VariantKind::Struct = variant.kind() {
             // tuple-like enum variant fields aren't really items so
             // don't try to encode them.
             for field in &variant.fields {
@@ -328,7 +328,7 @@ fn encode_enum_variant_info<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>,
         encode_def_id_and_key(ecx, rbml_w, vid);
         encode_family(rbml_w, match variant.kind() {
             ty::VariantKind::Unit | ty::VariantKind::Tuple => 'v',
-            ty::VariantKind::Dict => 'V'
+            ty::VariantKind::Struct => 'V'
         });
         encode_name(rbml_w, variant.name);
         encode_parent_item(rbml_w, ecx.tcx.map.local_def_id(id));
@@ -381,12 +381,8 @@ fn each_auxiliary_node_id<F>(item: &hir::Item, callback: F) -> bool where
     match item.node {
         hir::ItemStruct(ref struct_def, _) => {
             // If this is a newtype struct, return the constructor.
-            match struct_def.ctor_id {
-                Some(ctor_id) if !struct_def.fields.is_empty() &&
-                        struct_def.fields[0].node.kind.is_unnamed() => {
-                    continue_ = callback(ctor_id);
-                }
-                _ => {}
+            if struct_def.is_tuple() {
+                continue_ = callback(struct_def.id());
             }
         }
         _ => {}
@@ -1023,7 +1019,7 @@ fn encode_info_for_item<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>,
         encode_attributes(rbml_w, &item.attrs);
         encode_repr_attrs(rbml_w, ecx, &item.attrs);
         for v in &enum_definition.variants {
-            encode_variant_id(rbml_w, ecx.tcx.map.local_def_id(v.node.id));
+            encode_variant_id(rbml_w, ecx.tcx.map.local_def_id(v.node.data.id()));
         }
         encode_inlined_item(ecx, rbml_w, InlinedItemRef::Item(item));
         encode_path(rbml_w, path);
@@ -1072,8 +1068,8 @@ fn encode_info_for_item<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>,
         // Encode inherent implementations for this structure.
         encode_inherent_implementations(ecx, rbml_w, def_id);
 
-        if let Some(ctor_id) = struct_def.ctor_id {
-            let ctor_did = ecx.tcx.map.local_def_id(ctor_id);
+        if !struct_def.is_struct() {
+            let ctor_did = ecx.tcx.map.local_def_id(struct_def.id());
             rbml_w.wr_tagged_u64(tag_items_data_item_struct_ctor,
                                  def_to_u64(ctor_did));
         }
@@ -1085,9 +1081,8 @@ fn encode_info_for_item<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>,
         }
 
         // If this is a tuple-like struct, encode the type of the constructor.
-        if let Some(ctor_id) = struct_def.ctor_id {
-            encode_info_for_struct_ctor(ecx, rbml_w, item.name,
-                                        ctor_id, index, item.id);
+        if !struct_def.is_struct() {
+            encode_info_for_struct_ctor(ecx, rbml_w, item.name, struct_def.id(), index, item.id);
         }
       }
       hir::ItemDefaultImpl(unsafety, _) => {
index 3b4cb56ec741f4b793463a8246d1f0726ae714ad..e81445f19ede661ff85aadda7ee947415bf41ce7 100644 (file)
@@ -1315,17 +1315,17 @@ fn copy_item_type(dcx: &DecodeContext,
                     def.variants.iter().zip(orig_def.variants.iter())
                 {
                     debug!("astencode: copying variant {:?} => {:?}",
-                           orig_variant.did, i_variant.node.id);
-                    copy_item_type(dcx, i_variant.node.id, orig_variant.did);
+                           orig_variant.did, i_variant.node.data.id());
+                    copy_item_type(dcx, i_variant.node.data.id(), orig_variant.did);
                 }
             }
             hir::ItemStruct(ref def, _) => {
-                if let Some(ctor_id) = def.ctor_id {
+                if !def.is_struct() {
                     let ctor_did = dcx.tcx.lookup_adt_def(orig_did)
                         .struct_variant().did;
                     debug!("astencode: copying ctor {:?} => {:?}", ctor_did,
-                           ctor_id);
-                    copy_item_type(dcx, ctor_id, ctor_did);
+                           def.id());
+                    copy_item_type(dcx, def.id(), ctor_did);
                 }
             }
             _ => {}
index a8f20815a9a8b872e126e4f3835834cf1fafa6c6..4d7dd60a27156cff033ea7ec03f96039c3239167 100644 (file)
@@ -518,7 +518,7 @@ fn construct_witness<'a,'tcx>(cx: &MatchCheckCtxt<'a,'tcx>, ctor: &Constructor,
 
         ty::TyEnum(adt, _) | ty::TyStruct(adt, _)  => {
             let v = adt.variant_of_ctor(ctor);
-            if let VariantKind::Dict = v.kind() {
+            if let VariantKind::Struct = v.kind() {
                 let field_pats: Vec<_> = v.fields.iter()
                     .zip(pats)
                     .filter(|&(_, ref pat)| pat.node != hir::PatWild(hir::PatWildSingle))
index acb66b8efe7eb059c9ec2a9839b39230a54250ce..fd73fe45180becc792314c348b6c0f0d6300d293 100644 (file)
@@ -54,7 +54,7 @@ fn visit_item(&mut self, it: &'ast hir::Item) {
                         let mut recursion_visitor =
                             CheckItemRecursionVisitor::new(self, &variant.span);
                         recursion_visitor.populate_enum_discriminants(enum_def);
-                        recursion_visitor.visit_variant(variant, generics);
+                        recursion_visitor.visit_variant(variant, generics, it.id);
                     }
                 }
             }
@@ -168,7 +168,7 @@ fn populate_enum_discriminants(&self, enum_definition: &'ast hir::EnumDef) {
         let mut discriminant_map = self.discriminant_map.borrow_mut();
         match enum_definition.variants.first() {
             None => { return; }
-            Some(variant) if discriminant_map.contains_key(&variant.node.id) => {
+            Some(variant) if discriminant_map.contains_key(&variant.node.data.id()) => {
                 return;
             }
             _ => {}
@@ -177,7 +177,7 @@ fn populate_enum_discriminants(&self, enum_definition: &'ast hir::EnumDef) {
         // Go through all the variants.
         let mut variant_stack: Vec<ast::NodeId> = Vec::new();
         for variant in enum_definition.variants.iter().rev() {
-            variant_stack.push(variant.node.id);
+            variant_stack.push(variant.node.data.id());
             // When we find an expression, every variant currently on the stack
             // is affected by that expression.
             if let Some(ref expr) = variant.node.disr_expr {
@@ -201,14 +201,14 @@ fn visit_item(&mut self, it: &'ast hir::Item) {
     }
 
     fn visit_enum_def(&mut self, enum_definition: &'ast hir::EnumDef,
-                      generics: &'ast hir::Generics) {
+                      generics: &'ast hir::Generics, item_id: ast::NodeId) {
         self.populate_enum_discriminants(enum_definition);
-        visit::walk_enum_def(self, enum_definition, generics);
+        visit::walk_enum_def(self, enum_definition, generics, item_id);
     }
 
     fn visit_variant(&mut self, variant: &'ast hir::Variant,
-                     _: &'ast hir::Generics) {
-        let variant_id = variant.node.id;
+                     _: &'ast hir::Generics, _: ast::NodeId) {
+        let variant_id = variant.node.data.id();
         let maybe_expr;
         if let Some(get_expr) = self.discriminant_map.borrow().get(&variant_id) {
             // This is necessary because we need to let the `discriminant_map`
@@ -269,9 +269,10 @@ fn visit_expr(&mut self, e: &'ast hir::Expr) {
                                 self.ast_map.expect_item(enum_node_id).node
                             {
                                 self.populate_enum_discriminants(enum_def);
+                                let enum_id = self.ast_map.as_local_node_id(enum_id).unwrap();
                                 let variant_id = self.ast_map.as_local_node_id(variant_id).unwrap();
                                 let variant = self.ast_map.expect_variant(variant_id);
-                                self.visit_variant(variant, generics);
+                                self.visit_variant(variant, generics, enum_id);
                             } else {
                                 self.sess.span_bug(e.span,
                                                    "`check_static_recursion` found \
index acda0fe2f0e3532ffd25fe837616a220e6caa5d5..3c68fb62e244519fad1b19848740bbe94304447d 100644 (file)
@@ -63,7 +63,7 @@ fn lookup_variant_by_id<'a>(tcx: &'a ty::ctxt,
     fn variant_expr<'a>(variants: &'a [P<hir::Variant>], id: ast::NodeId)
                         -> Option<&'a Expr> {
         for variant in variants {
-            if variant.node.id == id {
+            if variant.node.data.id() == id {
                 return variant.node.disr_expr.as_ref().map(|e| &**e);
             }
         }
index 6e31b733254bd73f90d370117d01fc62181dc19d..7b11419d92562c4e0300a05d87d15c49fc6c5243 100644 (file)
@@ -215,11 +215,11 @@ fn visit_node(&mut self, node: &ast_map::Node) {
 
 impl<'a, 'tcx, 'v> Visitor<'v> for MarkSymbolVisitor<'a, 'tcx> {
 
-    fn visit_struct_def(&mut self, def: &hir::StructDef, _: ast::Name,
-                        _: &hir::Generics, _: ast::NodeId) {
+    fn visit_variant_data(&mut self, def: &hir::VariantData, _: ast::Name,
+                        _: &hir::Generics, _: ast::NodeId, _: codemap::Span) {
         let has_extern_repr = self.struct_has_extern_repr;
         let inherited_pub_visibility = self.inherited_pub_visibility;
-        let live_fields = def.fields.iter().filter(|f| {
+        let live_fields = def.fields().filter(|f| {
             has_extern_repr || inherited_pub_visibility || match f.node.kind {
                 hir::NamedField(_, hir::Public) => true,
                 _ => false
@@ -339,7 +339,8 @@ fn visit_item(&mut self, item: &hir::Item) {
         }
         match item.node {
             hir::ItemEnum(ref enum_def, _) if allow_dead_code => {
-                self.worklist.extend(enum_def.variants.iter().map(|variant| variant.node.id));
+                self.worklist.extend(enum_def.variants.iter()
+                                                      .map(|variant| variant.node.data.id()));
             }
             hir::ItemTrait(_, _, _, ref trait_items) => {
                 for trait_item in trait_items {
@@ -426,7 +427,9 @@ fn find_live(tcx: &ty::ctxt,
 
 fn get_struct_ctor_id(item: &hir::Item) -> Option<ast::NodeId> {
     match item.node {
-        hir::ItemStruct(ref struct_def, _) => struct_def.ctor_id,
+        hir::ItemStruct(ref struct_def, _) if !struct_def.is_struct() => {
+            Some(struct_def.id())
+        }
         _ => None
     }
 }
@@ -464,7 +467,7 @@ fn should_warn_about_field(&mut self, node: &hir::StructField_) -> bool {
     }
 
     fn should_warn_about_variant(&mut self, variant: &hir::Variant_) -> bool {
-        !self.symbol_is_live(variant.id, None)
+        !self.symbol_is_live(variant.data.id(), None)
             && !has_allow_dead_code_or_lang_attr(&variant.attrs)
     }
 
@@ -540,7 +543,7 @@ fn visit_item(&mut self, item: &hir::Item) {
                 hir::ItemEnum(ref enum_def, _) => {
                     for variant in &enum_def.variants {
                         if self.should_warn_about_variant(&variant.node) {
-                            self.warn_dead_code(variant.node.id, variant.span,
+                            self.warn_dead_code(variant.node.data.id(), variant.span,
                                                 variant.node.name, "variant");
                         }
                     }
index 3e8325b86121dbed515172b9c60f74c01f5677b4..ef2b918a9f5d7ea449f5e8df4d4d87a947822a85 100644 (file)
@@ -44,13 +44,13 @@ pub enum Def {
              ast::NodeId), // expr node that creates the closure
 
     /// Note that if it's a tuple struct's definition, the node id of the DefId
-    /// may either refer to the item definition's id or the StructDef.ctor_id.
+    /// may either refer to the item definition's id or the VariantData.ctor_id.
     ///
     /// The cases that I have encountered so far are (this is not exhaustive):
     /// - If it's a ty_path referring to some tuple struct, then DefMap maps
     ///   it to a def whose id is the item definition's id.
     /// - If it's an ExprPath referring to some tuple struct, then DefMap maps
-    ///   it to a def whose id is the StructDef.ctor_id.
+    ///   it to a def whose id is the VariantData.ctor_id.
     DefStruct(DefId),
     DefLabel(ast::NodeId),
     DefMethod(DefId),
index c2235591ceef10d5408131aa82aa8e096fcb2458..af295c3e584b04310fe160b6657d298fd3eba0bd 100644 (file)
@@ -185,9 +185,9 @@ fn visit_item(&mut self, i: &Item) {
                       |v| visit::walk_item(v, i), required);
 
         if let hir::ItemStruct(ref sd, _) = i.node {
-            sd.ctor_id.map(|id| {
-                self.annotate(id, true, &i.attrs, i.span, |_| {}, true)
-            });
+            if !sd.is_struct() {
+                self.annotate(sd.id(), true, &i.attrs, i.span, |_| {}, true)
+            }
         }
     }
 
@@ -207,9 +207,9 @@ fn visit_impl_item(&mut self, ii: &hir::ImplItem) {
                       |v| visit::walk_impl_item(v, ii), true);
     }
 
-    fn visit_variant(&mut self, var: &Variant, g: &'v Generics) {
-        self.annotate(var.node.id, true, &var.node.attrs, var.span,
-                      |v| visit::walk_variant(v, var, g), true)
+    fn visit_variant(&mut self, var: &Variant, g: &'v Generics, item_id: NodeId) {
+        self.annotate(var.node.data.id(), true, &var.node.attrs, var.span,
+                      |v| visit::walk_variant(v, var, g, item_id), true)
     }
 
     fn visit_struct_field(&mut self, s: &StructField) {
index 4ffb519900356ab0687aeb73907c9407c9fb8afd..975a5adad2bd21a3f23624829a84cf23e2f3c2ad 100644 (file)
@@ -1533,7 +1533,7 @@ fn hash<H: Hasher>(&self, s: &mut H) {
 pub enum AdtKind { Struct, Enum }
 
 #[derive(Copy, Clone, Debug, Eq, PartialEq)]
-pub enum VariantKind { Dict, Tuple, Unit }
+pub enum VariantKind { Struct, Tuple, Unit }
 
 impl<'tcx, 'container> AdtDefData<'tcx, 'container> {
     fn new(tcx: &ctxt<'tcx>,
@@ -1716,7 +1716,7 @@ pub fn kind(&self) -> VariantKind {
             Some(&FieldDefData { name, .. }) if name == special_idents::unnamed_field.name => {
                 VariantKind::Tuple
             }
-            Some(_) => VariantKind::Dict
+            Some(_) => VariantKind::Struct
         }
     }
 
index 25b4cfad01ce0e3a43cd2f80c97f7e99b2e39af3..a9cfc7138d8d967808aa44183e7d833035c9b52c 100644 (file)
@@ -301,18 +301,18 @@ fn saw_stmt(node: &Stmt_) -> SawStmtComponent {
     }
 
     impl<'a, 'v> Visitor<'v> for StrictVersionHashVisitor<'a> {
-        fn visit_struct_def(&mut self, s: &StructDef, name: Name,
-                            g: &Generics, _: NodeId) {
+        fn visit_variant_data(&mut self, s: &VariantData, name: Name,
+                            g: &Generics, _: NodeId, _: Span) {
             SawStructDef(name.as_str()).hash(self.st);
             visit::walk_generics(self, g);
             visit::walk_struct_def(self, s)
         }
 
-        fn visit_variant(&mut self, v: &Variant, g: &Generics) {
+        fn visit_variant(&mut self, v: &Variant, g: &Generics, item_id: NodeId) {
             SawVariant.hash(self.st);
             // walk_variant does not call walk_generics, so do it here.
             visit::walk_generics(self, g);
-            visit::walk_variant(self, v, g)
+            visit::walk_variant(self, v, g, item_id)
         }
 
         // All of the remaining methods just record (in the hash
index 3ee45c3506e1907a1fe355efbd437787764ab9fc..16f586cf5e0627487883b2f37b90496635b1520f 100644 (file)
@@ -22,7 +22,9 @@
 
 //! A typesafe bitmask flag generator.
 
-#[cfg(test)] #[macro_use] extern crate std;
+#[cfg(test)]
+#[macro_use]
+extern crate std;
 
 /// The `bitflags!` macro generates a `struct` that holds a set of C-style
 /// bitmask flags. It is useful for creating typesafe wrappers for C APIs.
@@ -321,7 +323,7 @@ mod tests {
     }
 
     #[test]
-    fn test_bits(){
+    fn test_bits() {
         assert_eq!(Flags::empty().bits(), 0b00000000);
         assert_eq!(Flags::FlagA.bits(), 0b00000001);
         assert_eq!(Flags::FlagABC.bits(), 0b00000111);
@@ -354,7 +356,7 @@ fn test_from_bits_truncate() {
     }
 
     #[test]
-    fn test_is_empty(){
+    fn test_is_empty() {
         assert!(Flags::empty().is_empty());
         assert!(!Flags::FlagA.is_empty());
         assert!(!Flags::FlagABC.is_empty());
@@ -413,7 +415,7 @@ fn test_contains() {
     }
 
     #[test]
-    fn test_insert(){
+    fn test_insert() {
         let mut e1 = Flags::FlagA;
         let e2 = Flags::FlagA | Flags::FlagB;
         e1.insert(e2);
@@ -425,7 +427,7 @@ fn test_insert(){
     }
 
     #[test]
-    fn test_remove(){
+    fn test_remove() {
         let mut e1 = Flags::FlagA | Flags::FlagB;
         let e2 = Flags::FlagA | Flags::FlagC;
         e1.remove(e2);
@@ -484,12 +486,12 @@ fn test_ord() {
 
     #[test]
     fn test_hash() {
-      let mut x = Flags::empty();
-      let mut y = Flags::empty();
-      assert!(hash(&x) == hash(&y));
-      x = Flags::all();
-      y = Flags::FlagABC;
-      assert!(hash(&x) == hash(&y));
+        let mut x = Flags::empty();
+        let mut y = Flags::empty();
+        assert!(hash(&x) == hash(&y));
+        x = Flags::all();
+        y = Flags::FlagABC;
+        assert!(hash(&x) == hash(&y));
     }
 
     fn hash<T: Hash>(t: &T) -> u64 {
index c6108044beacea38e8112509414172d571c38193..dafca7188d5adc7b7b7d88f77b0a43c228b76b2d 100644 (file)
@@ -223,7 +223,7 @@ fn fold_poly_trait_ref(&mut self, p: PolyTraitRef) -> PolyTraitRef {
         noop_fold_poly_trait_ref(p, self)
     }
 
-    fn fold_struct_def(&mut self, struct_def: P<StructDef>) -> P<StructDef> {
+    fn fold_variant_data(&mut self, struct_def: P<VariantData>) -> P<VariantData> {
         noop_fold_struct_def(struct_def, self)
     }
 
@@ -247,10 +247,6 @@ fn fold_opt_lifetime(&mut self, o_lt: Option<Lifetime>) -> Option<Lifetime> {
         noop_fold_opt_lifetime(o_lt, self)
     }
 
-    fn fold_variant_arg(&mut self, va: VariantArg) -> VariantArg {
-        noop_fold_variant_arg(va, self)
-    }
-
     fn fold_opt_bounds(&mut self,
                        b: Option<OwnedSlice<TyParamBound>>)
                        -> Option<OwnedSlice<TyParamBound>> {
@@ -435,24 +431,14 @@ pub fn noop_fold_foreign_mod<T: Folder>(ForeignMod { abi, items }: ForeignMod,
 }
 
 pub fn noop_fold_variant<T: Folder>(v: P<Variant>, fld: &mut T) -> P<Variant> {
-    v.map(|Spanned { node: Variant_ { id, name, attrs, kind, disr_expr }, span }| {
-        Spanned {
-            node: Variant_ {
-                id: fld.new_id(id),
-                name: name,
-                attrs: fold_attrs(attrs, fld),
-                kind: match kind {
-                    TupleVariantKind(variant_args) => {
-                        TupleVariantKind(variant_args.move_map(|x| fld.fold_variant_arg(x)))
-                    }
-                    StructVariantKind(struct_def) => {
-                        StructVariantKind(fld.fold_struct_def(struct_def))
-                    }
-                },
-                disr_expr: disr_expr.map(|e| fld.fold_expr(e)),
-            },
-            span: fld.new_span(span),
-        }
+    v.map(|Spanned {node: Variant_ {name, attrs, data, disr_expr}, span}| Spanned {
+        node: Variant_ {
+            name: name,
+            attrs: fold_attrs(attrs, fld),
+            data: fld.fold_variant_data(data),
+            disr_expr: disr_expr.map(|e| fld.fold_expr(e)),
+        },
+        span: fld.new_span(span),
     })
 }
 
@@ -707,11 +693,16 @@ pub fn noop_fold_where_predicate<T: Folder>(pred: WherePredicate, fld: &mut T) -
     }
 }
 
-pub fn noop_fold_struct_def<T: Folder>(struct_def: P<StructDef>, fld: &mut T) -> P<StructDef> {
-    struct_def.map(|StructDef { fields, ctor_id }| {
-        StructDef {
-            fields: fields.move_map(|f| fld.fold_struct_field(f)),
-            ctor_id: ctor_id.map(|cid| fld.new_id(cid)),
+pub fn noop_fold_struct_def<T: Folder>(struct_def: P<VariantData>, fld: &mut T) -> P<VariantData> {
+    struct_def.map(|vdata| {
+        match vdata {
+            VariantData::Struct(fields, id) => {
+                VariantData::Struct(fields.move_map(|f| fld.fold_struct_field(f)), fld.new_id(id))
+            }
+            VariantData::Tuple(fields, id) => {
+                VariantData::Tuple(fields.move_map(|f| fld.fold_struct_field(f)), fld.new_id(id))
+            }
+            VariantData::Unit(id) => VariantData::Unit(fld.new_id(id))
         }
     })
 }
@@ -775,15 +766,6 @@ fn noop_fold_bounds<T: Folder>(bounds: TyParamBounds, folder: &mut T) -> TyParam
     bounds.move_map(|bound| folder.fold_ty_param_bound(bound))
 }
 
-fn noop_fold_variant_arg<T: Folder>(VariantArg { id, ty }: VariantArg,
-                                    folder: &mut T)
-                                    -> VariantArg {
-    VariantArg {
-        id: folder.new_id(id),
-        ty: folder.fold_ty(ty),
-    }
-}
-
 pub fn noop_fold_block<T: Folder>(b: P<Block>, folder: &mut T) -> P<Block> {
     b.map(|Block { id, stmts, expr, rules, span }| {
         Block {
@@ -828,7 +810,7 @@ pub fn noop_fold_item_underscore<T: Folder>(i: Item_, folder: &mut T) -> Item_ {
                      folder.fold_generics(generics))
         }
         ItemStruct(struct_def, generics) => {
-            let struct_def = folder.fold_struct_def(struct_def);
+            let struct_def = folder.fold_variant_data(struct_def);
             ItemStruct(struct_def, folder.fold_generics(generics))
         }
         ItemDefaultImpl(unsafety, ref trait_ref) => {
index 9066b93262cd64639fb0e8b4dfa1177b1395d596..e62eadaa4387dd962418d043c4ecbae4a58d3e73 100644 (file)
@@ -33,7 +33,6 @@
 pub use self::TyParamBound::*;
 pub use self::UnOp::*;
 pub use self::UnsafeSource::*;
-pub use self::VariantKind::*;
 pub use self::ViewPath_::*;
 pub use self::Visibility::*;
 pub use self::PathParameters::*;
@@ -50,6 +49,7 @@
 use util;
 
 use std::fmt;
+use std::{iter, option, slice};
 use serialize::{Encodable, Encoder, Decoder};
 
 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Copy)]
@@ -1015,20 +1015,6 @@ pub struct ForeignMod {
     pub items: Vec<P<ForeignItem>>,
 }
 
-#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
-pub struct VariantArg {
-    pub ty: P<Ty>,
-    pub id: NodeId,
-}
-
-#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
-pub enum VariantKind {
-    /// Tuple variant, e.g. `Foo(A, B)`
-    TupleVariantKind(Vec<VariantArg>),
-    /// Struct variant, e.g. `Foo {x: A, y: B}`
-    StructVariantKind(P<StructDef>),
-}
-
 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
 pub struct EnumDef {
     pub variants: Vec<P<Variant>>,
@@ -1038,8 +1024,7 @@ pub struct EnumDef {
 pub struct Variant_ {
     pub name: Name,
     pub attrs: Vec<Attribute>,
-    pub kind: VariantKind,
-    pub id: NodeId,
+    pub data: P<VariantData>,
     /// Explicit discriminant, eg `Foo = 1`
     pub disr_expr: Option<P<Expr>>,
 }
@@ -1176,13 +1161,50 @@ pub fn is_unnamed(&self) -> bool {
     }
 }
 
+/// Fields and Ids of enum variants and structs
+///
+/// For enum variants: `NodeId` represents both an Id of the variant itself (relevant for all
+/// variant kinds) and an Id of the variant's constructor (not relevant for `Struct`-variants).
+/// One shared Id can be successfully used for these two purposes.
+/// Id of the whole enum lives in `Item`.
+///
+/// For structs: `NodeId` represents an Id of the structure's constructor, so it is not actually
+/// used for `Struct`-structs (but still presents). Structures don't have an analogue of "Id of
+/// the variant itself" from enum variants.
+/// Id of the whole struct lives in `Item`.
 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
-pub struct StructDef {
-    /// Fields, not including ctor
-    pub fields: Vec<StructField>,
-    /// ID of the constructor. This is only used for tuple- or enum-like
-    /// structs.
-    pub ctor_id: Option<NodeId>,
+pub enum VariantData {
+    Struct(Vec<StructField>, NodeId),
+    Tuple(Vec<StructField>, NodeId),
+    Unit(NodeId),
+}
+
+pub type FieldIter<'a> = iter::FlatMap<option::IntoIter<&'a Vec<StructField>>,
+                                       slice::Iter<'a, StructField>,
+                                       fn(&Vec<StructField>) -> slice::Iter<StructField>>;
+
+impl VariantData {
+    pub fn fields(&self) -> FieldIter {
+        fn vec_iter<T>(v: &Vec<T>) -> slice::Iter<T> { v.iter() }
+        match *self {
+            VariantData::Struct(ref fields, _) | VariantData::Tuple(ref fields, _) => Some(fields),
+            _ => None,
+        }.into_iter().flat_map(vec_iter)
+    }
+    pub fn id(&self) -> NodeId {
+        match *self {
+            VariantData::Struct(_, id) | VariantData::Tuple(_, id) | VariantData::Unit(id) => id
+        }
+    }
+    pub fn is_struct(&self) -> bool {
+        if let VariantData::Struct(..) = *self { true } else { false }
+    }
+    pub fn is_tuple(&self) -> bool {
+        if let VariantData::Tuple(..) = *self { true } else { false }
+    }
+    pub fn is_unit(&self) -> bool {
+        if let VariantData::Unit(..) = *self { true } else { false }
+    }
 }
 
 /*
@@ -1226,7 +1248,7 @@ pub enum Item_ {
     /// An enum definition, e.g. `enum Foo<A, B> {C<A>, D<B>}`
     ItemEnum(EnumDef, Generics),
     /// A struct definition, e.g. `struct Foo<A> {x: A}`
-    ItemStruct(P<StructDef>, Generics),
+    ItemStruct(P<VariantData>, Generics),
     /// Represents a Trait Declaration
     ItemTrait(Unsafety, Generics, TyParamBounds, Vec<P<TraitItem>>),
 
index 4ee5fa2c1e9b5389c894dcfd4249f1e8f61e28a7..aeadc763a32d4a795084c94570283d4036f64948 100644 (file)
@@ -264,19 +264,9 @@ pub fn lower_foreign_mod(_lctx: &LoweringContext, fm: &ForeignMod) -> hir::Forei
 pub fn lower_variant(_lctx: &LoweringContext, v: &Variant) -> P<hir::Variant> {
     P(Spanned {
         node: hir::Variant_ {
-            id: v.node.id,
             name: v.node.name.name,
             attrs: v.node.attrs.clone(),
-            kind: match v.node.kind {
-                TupleVariantKind(ref variant_args) => {
-                    hir::TupleVariantKind(variant_args.iter()
-                                                      .map(|ref x| lower_variant_arg(_lctx, x))
-                                                      .collect())
-                }
-                StructVariantKind(ref struct_def) => {
-                    hir::StructVariantKind(lower_struct_def(_lctx, struct_def))
-                }
-            },
+            data: lower_struct_def(_lctx, &v.node.data),
             disr_expr: v.node.disr_expr.as_ref().map(|e| lower_expr(_lctx, e)),
         },
         span: v.span,
@@ -508,10 +498,17 @@ pub fn lower_where_predicate(_lctx: &LoweringContext,
     }
 }
 
-pub fn lower_struct_def(_lctx: &LoweringContext, sd: &StructDef) -> P<hir::StructDef> {
-    P(hir::StructDef {
-        fields: sd.fields.iter().map(|f| lower_struct_field(_lctx, f)).collect(),
-        ctor_id: sd.ctor_id,
+pub fn lower_struct_def(_lctx: &LoweringContext, sd: &VariantData) -> P<hir::VariantData> {
+    P(match *sd {
+        VariantData::Struct(ref fields, id) => {
+            hir::VariantData::Struct(fields.iter()
+                                           .map(|f| lower_struct_field(_lctx, f)).collect(), id)
+        }
+        VariantData::Tuple(ref fields, id) => {
+            hir::VariantData::Tuple(fields.iter()
+                                          .map(|f| lower_struct_field(_lctx, f)).collect(), id)
+        }
+        VariantData::Unit(id) => hir::VariantData::Unit(id)
     })
 }
 
@@ -567,13 +564,6 @@ fn lower_bounds(_lctx: &LoweringContext, bounds: &TyParamBounds) -> hir::TyParam
     bounds.iter().map(|bound| lower_ty_param_bound(_lctx, bound)).collect()
 }
 
-fn lower_variant_arg(_lctx: &LoweringContext, va: &VariantArg) -> hir::VariantArg {
-    hir::VariantArg {
-        id: va.id,
-        ty: lower_ty(_lctx, &va.ty),
-    }
-}
-
 pub fn lower_block(_lctx: &LoweringContext, b: &Block) -> P<hir::Block> {
     P(hir::Block {
         id: b.id,
@@ -1422,7 +1412,11 @@ pub fn lower_expr(lctx: &LoweringContext, e: &Expr) -> P<hir::Expr> {
                               vec![head])
                 };
 
-                let match_expr = expr_match(lctx, e.span, into_iter_expr, vec![iter_arm]);
+                let match_expr = expr_match(lctx,
+                                            e.span,
+                                            into_iter_expr,
+                                            vec![iter_arm],
+                                            hir::MatchSource::ForLoopDesugar);
 
                 // `{ let result = ...; result }`
                 let result_ident = lctx.str_to_ident("result");
@@ -1485,8 +1479,6 @@ pub fn lower_block_check_mode(_lctx: &LoweringContext, b: &BlockCheckMode) -> hi
     match *b {
         DefaultBlock => hir::DefaultBlock,
         UnsafeBlock(u) => hir::UnsafeBlock(lower_unsafe_source(_lctx, u)),
-        PushUnsafeBlock(u) => hir::PushUnsafeBlock(lower_unsafe_source(_lctx, u)),
-        PopUnsafeBlock(u) => hir::PopUnsafeBlock(lower_unsafe_source(_lctx, u)),
     }
 }
 
@@ -1574,11 +1566,12 @@ fn expr_path(lctx: &LoweringContext, path: hir::Path) -> P<hir::Expr> {
 fn expr_match(lctx: &LoweringContext,
               span: Span,
               arg: P<hir::Expr>,
-              arms: Vec<hir::Arm>)
+              arms: Vec<hir::Arm>,
+              source: hir::MatchSource)
               -> P<hir::Expr> {
     expr(lctx,
          span,
-         hir::ExprMatch(arg, arms, hir::MatchSource::Normal))
+         hir::ExprMatch(arg, arms, source))
 }
 
 fn expr_block(lctx: &LoweringContext, b: P<hir::Block>) -> P<hir::Expr> {
index 80b0a984681a310184560b8a41ff2363226f1d66..5e78aa5fbc1f8cf66e9af66bdeb41c826b073815 100644 (file)
@@ -734,7 +734,7 @@ pub fn print_item(&mut self, item: &hir::Item) -> io::Result<()> {
             }
             hir::ItemStruct(ref struct_def, ref generics) => {
                 try!(self.head(&visibility_qualified(item.vis, "struct")));
-                try!(self.print_struct(&**struct_def, generics, item.name, item.span));
+                try!(self.print_struct(&**struct_def, generics, item.name, item.span, true));
             }
 
             hir::ItemDefaultImpl(unsafety, ref trait_ref) => {
@@ -888,18 +888,19 @@ pub fn print_visibility(&mut self, vis: hir::Visibility) -> io::Result<()> {
     }
 
     pub fn print_struct(&mut self,
-                        struct_def: &hir::StructDef,
+                        struct_def: &hir::VariantData,
                         generics: &hir::Generics,
                         name: ast::Name,
-                        span: codemap::Span)
+                        span: codemap::Span,
+                        print_finalizer: bool)
                         -> io::Result<()> {
         try!(self.print_name(name));
         try!(self.print_generics(generics));
-        if ::util::struct_def_is_tuple_like(struct_def) {
-            if !struct_def.fields.is_empty() {
+        if !struct_def.is_struct() {
+            if struct_def.is_tuple() {
                 try!(self.popen());
-                try!(self.commasep(Inconsistent,
-                                   &struct_def.fields,
+                try!(self.commasep_iter(Inconsistent,
+                                   struct_def.fields(),
                                    |s, field| {
                                        match field.node.kind {
                                            hir::NamedField(..) => panic!("unexpected named field"),
@@ -913,7 +914,9 @@ pub fn print_struct(&mut self,
                 try!(self.pclose());
             }
             try!(self.print_where_clause(&generics.where_clause));
-            try!(word(&mut self.s, ";"));
+            if print_finalizer {
+                try!(word(&mut self.s, ";"));
+            }
             try!(self.end());
             self.end() // close the outer-box
         } else {
@@ -922,7 +925,7 @@ pub fn print_struct(&mut self,
             try!(self.bopen());
             try!(self.hardbreak_if_not_bol());
 
-            for field in &struct_def.fields {
+            for field in struct_def.fields() {
                 match field.node.kind {
                     hir::UnnamedField(..) => panic!("unexpected unnamed field"),
                     hir::NamedField(name, visibility) => {
@@ -943,21 +946,9 @@ pub fn print_struct(&mut self,
     }
 
     pub fn print_variant(&mut self, v: &hir::Variant) -> io::Result<()> {
-        match v.node.kind {
-            hir::TupleVariantKind(ref args) => {
-                try!(self.print_name(v.node.name));
-                if !args.is_empty() {
-                    try!(self.popen());
-                    try!(self.commasep(Consistent, &args[..], |s, arg| s.print_type(&*arg.ty)));
-                    try!(self.pclose());
-                }
-            }
-            hir::StructVariantKind(ref struct_def) => {
-                try!(self.head(""));
-                let generics = ::util::empty_generics();
-                try!(self.print_struct(&**struct_def, &generics, v.node.name, v.span));
-            }
-        }
+        try!(self.head(""));
+        let generics = ::util::empty_generics();
+        try!(self.print_struct(&v.node.data, &generics, v.node.name, v.span, false));
         match v.node.disr_expr {
             Some(ref d) => {
                 try!(space(&mut self.s));
index c6b2a2acc2b8d5b34e2a6cb39af6564ebb533c3f..5d8973ead47db27a1ddea1bc4a8128d9c7834b01 100644 (file)
@@ -81,12 +81,6 @@ pub fn binop_to_string(op: BinOp_) -> &'static str {
     }
 }
 
-/// Returns true if the given struct def is tuple-like; i.e. that its fields
-/// are unnamed.
-pub fn struct_def_is_tuple_like(struct_def: &hir::StructDef) -> bool {
-    struct_def.ctor_id.is_some()
-}
-
 pub fn stmt_id(s: &Stmt) -> NodeId {
     match s.node {
         StmtDecl(_, id) => id,
@@ -200,11 +194,6 @@ fn visit_item(&mut self, item: &Item) {
                     }
                 }
             }
-            ItemEnum(ref enum_definition, _) => {
-                for variant in &enum_definition.variants {
-                    self.operation.visit_id(variant.node.id)
-                }
-            }
             _ => {}
         }
 
@@ -292,13 +281,13 @@ fn visit_struct_field(&mut self, struct_field: &StructField) {
         visit::walk_struct_field(self, struct_field)
     }
 
-    fn visit_struct_def(&mut self,
-                        struct_def: &StructDef,
+    fn visit_variant_data(&mut self,
+                        struct_def: &VariantData,
                         _: Name,
                         _: &hir::Generics,
-                        id: NodeId) {
-        self.operation.visit_id(id);
-        struct_def.ctor_id.map(|ctor_id| self.operation.visit_id(ctor_id));
+                        _: NodeId,
+                        _: Span) {
+        self.operation.visit_id(struct_def.id());
         visit::walk_struct_def(self, struct_def);
     }
 
index 9e91ab34d089a9da5d848212245a4c7dc9698c49..00c2c3a3ddd65e1aca2561156be1639cef087d6c 100644 (file)
@@ -112,20 +112,20 @@ fn visit_ty_param_bound(&mut self, bounds: &'v TyParamBound) {
     fn visit_poly_trait_ref(&mut self, t: &'v PolyTraitRef, m: &'v TraitBoundModifier) {
         walk_poly_trait_ref(self, t, m)
     }
-    fn visit_struct_def(&mut self, s: &'v StructDef, _: Name, _: &'v Generics, _: NodeId) {
+    fn visit_variant_data(&mut self, s: &'v VariantData, _: Name,
+                        _: &'v Generics, _: NodeId, _: Span) {
         walk_struct_def(self, s)
     }
     fn visit_struct_field(&mut self, s: &'v StructField) {
         walk_struct_field(self, s)
     }
-    fn visit_enum_def(&mut self, enum_definition: &'v EnumDef, generics: &'v Generics) {
-        walk_enum_def(self, enum_definition, generics)
+    fn visit_enum_def(&mut self, enum_definition: &'v EnumDef,
+                      generics: &'v Generics, item_id: NodeId) {
+        walk_enum_def(self, enum_definition, generics, item_id)
     }
-
-    fn visit_variant(&mut self, v: &'v Variant, g: &'v Generics) {
-        walk_variant(self, v, g)
+    fn visit_variant(&mut self, v: &'v Variant, g: &'v Generics, item_id: NodeId) {
+        walk_variant(self, v, g, item_id)
     }
-
     fn visit_lifetime(&mut self, lifetime: &'v Lifetime) {
         walk_lifetime(self, lifetime)
     }
@@ -293,7 +293,7 @@ pub fn walk_item<'v, V: Visitor<'v>>(visitor: &mut V, item: &'v Item) {
         }
         ItemEnum(ref enum_definition, ref type_parameters) => {
             visitor.visit_generics(type_parameters);
-            visitor.visit_enum_def(enum_definition, type_parameters)
+            visitor.visit_enum_def(enum_definition, type_parameters, item.id)
         }
         ItemDefaultImpl(_, ref trait_ref) => {
             visitor.visit_trait_ref(trait_ref)
@@ -310,7 +310,8 @@ pub fn walk_item<'v, V: Visitor<'v>>(visitor: &mut V, item: &'v Item) {
         }
         ItemStruct(ref struct_definition, ref generics) => {
             visitor.visit_generics(generics);
-            visitor.visit_struct_def(struct_definition, item.name, generics, item.id)
+            visitor.visit_variant_data(struct_definition, item.name,
+                                     generics, item.id, item.span);
         }
         ItemTrait(_, ref generics, ref bounds, ref methods) => {
             visitor.visit_generics(generics);
@@ -323,30 +324,20 @@ pub fn walk_item<'v, V: Visitor<'v>>(visitor: &mut V, item: &'v Item) {
 
 pub fn walk_enum_def<'v, V: Visitor<'v>>(visitor: &mut V,
                                          enum_definition: &'v EnumDef,
-                                         generics: &'v Generics) {
+                                         generics: &'v Generics,
+                                         item_id: NodeId) {
     for variant in &enum_definition.variants {
-        visitor.visit_variant(variant, generics);
+        visitor.visit_variant(variant, generics, item_id);
     }
 }
 
 pub fn walk_variant<'v, V: Visitor<'v>>(visitor: &mut V,
                                         variant: &'v Variant,
-                                        generics: &'v Generics) {
+                                        generics: &'v Generics,
+                                        item_id: NodeId) {
     visitor.visit_name(variant.span, variant.node.name);
-
-    match variant.node.kind {
-        TupleVariantKind(ref variant_arguments) => {
-            for variant_argument in variant_arguments {
-                visitor.visit_ty(&variant_argument.ty)
-            }
-        }
-        StructVariantKind(ref struct_definition) => {
-            visitor.visit_struct_def(struct_definition,
-                                     variant.node.name,
-                                     generics,
-                                     variant.node.id)
-        }
-    }
+    visitor.visit_variant_data(&variant.node.data, variant.node.name,
+                             generics, item_id, variant.span);
     walk_list!(visitor, visit_expr, &variant.node.disr_expr);
     walk_list!(visitor, visit_attribute, &variant.node.attrs);
 }
@@ -637,8 +628,8 @@ pub fn walk_impl_item<'v, V: Visitor<'v>>(visitor: &mut V, impl_item: &'v ImplIt
     }
 }
 
-pub fn walk_struct_def<'v, V: Visitor<'v>>(visitor: &mut V, struct_definition: &'v StructDef) {
-    walk_list!(visitor, visit_struct_field, &struct_definition.fields);
+pub fn walk_struct_def<'v, V: Visitor<'v>>(visitor: &mut V, struct_definition: &'v VariantData) {
+    walk_list!(visitor, visit_struct_field, struct_definition.fields());
 }
 
 pub fn walk_struct_field<'v, V: Visitor<'v>>(visitor: &mut V, struct_field: &'v StructField) {
index 91d1d398a0e548ea782b2c9c4be8fce78754a76e..693de1740bfee9fdee03e7f453ef361ba40dc583 100644 (file)
@@ -280,9 +280,9 @@ fn check_pat(&mut self, cx: &LateContext, p: &hir::Pat) {
         }
     }
 
-    fn check_struct_def(&mut self, cx: &LateContext, s: &hir::StructDef,
+    fn check_struct_def(&mut self, cx: &LateContext, s: &hir::VariantData,
                         _: ast::Name, _: &hir::Generics, _: ast::NodeId) {
-        for sf in &s.fields {
+        for sf in s.fields() {
             if let hir::StructField_ { kind: hir::NamedField(name, _), .. } = sf.node {
                 self.check_snake_case(cx, "structure field", &name.as_str(),
                                       Some(sf.span));
index 1df3c1609b890894d02e116b5a538ff08c758db0..f5a58656080db785f1fd276c677905637093d826 100644 (file)
@@ -123,7 +123,7 @@ fn check_item(&mut self, cx: &LateContext, it: &hir::Item) {
         // If it's a struct, we also have to check the fields' types
         match it.node {
             hir::ItemStruct(ref struct_def, _) => {
-                for struct_field in &struct_def.fields {
+                for struct_field in struct_def.fields() {
                     self.check_heap_type(cx, struct_field.span,
                                          cx.tcx.node_id_to_type(struct_field.node.id));
                 }
@@ -427,15 +427,15 @@ fn exit_lint_attrs(&mut self, _: &LateContext, _: &[ast::Attribute]) {
         self.doc_hidden_stack.pop().expect("empty doc_hidden_stack");
     }
 
-    fn check_struct_def(&mut self, _: &LateContext, _: &hir::StructDef,
-                        _: ast::Name, _: &hir::Generics, id: ast::NodeId) {
-        self.struct_def_stack.push(id);
+    fn check_struct_def(&mut self, _: &LateContext, _: &hir::VariantData,
+                        _: ast::Name, _: &hir::Generics, item_id: ast::NodeId) {
+        self.struct_def_stack.push(item_id);
     }
 
-    fn check_struct_def_post(&mut self, _: &LateContext, _: &hir::StructDef,
-                             _: ast::Name, _: &hir::Generics, id: ast::NodeId) {
+    fn check_struct_def_post(&mut self, _: &LateContext, _: &hir::VariantData,
+                             _: ast::Name, _: &hir::Generics, item_id: ast::NodeId) {
         let popped = self.struct_def_stack.pop().expect("empty struct_def_stack");
-        assert!(popped == id);
+        assert!(popped == item_id);
     }
 
     fn check_crate(&mut self, cx: &LateContext, krate: &hir::Crate) {
@@ -527,7 +527,8 @@ fn check_struct_field(&mut self, cx: &LateContext, sf: &hir::StructField) {
     }
 
     fn check_variant(&mut self, cx: &LateContext, v: &hir::Variant, _: &hir::Generics) {
-        self.check_missing_docs_attrs(cx, Some(v.node.id), &v.node.attrs, v.span, "a variant");
+        self.check_missing_docs_attrs(cx, Some(v.node.data.id()),
+                                      &v.node.attrs, v.span, "a variant");
         assert!(!self.in_variant);
         self.in_variant = true;
     }
index ca5411f9c790a5e3a3c9d05da956725e71ff1322..608558ac2bdb9e6a7005192246d590cf2d4aa147 100644 (file)
@@ -82,7 +82,7 @@ fn visit_item(&mut self, item: &hir::Item) {
                     // The parent is considered the enclosing enum because the
                     // enum will dictate the privacy visibility of this variant
                     // instead.
-                    self.parents.insert(variant.node.id, item.id);
+                    self.parents.insert(variant.node.data.id(), item.id);
                 }
             }
 
@@ -128,18 +128,17 @@ fn visit_impl_item(&mut self, ii: &'v hir::ImplItem) {
         visit::walk_impl_item(self, ii);
     }
 
-    fn visit_struct_def(&mut self, s: &hir::StructDef, _: ast::Name,
-                        _: &'v hir::Generics, n: ast::NodeId) {
+    fn visit_variant_data(&mut self, s: &hir::VariantData, _: ast::Name,
+                        _: &'v hir::Generics, item_id: ast::NodeId, _: Span) {
         // Struct constructors are parented to their struct definitions because
         // they essentially are the struct definitions.
-        match s.ctor_id {
-            Some(id) => { self.parents.insert(id, n); }
-            None => {}
+        if !s.is_struct() {
+            self.parents.insert(s.id(), item_id);
         }
 
         // While we have the id of the struct definition, go ahead and parent
         // all the fields.
-        for field in &s.fields {
+        for field in s.fields() {
             self.parents.insert(field.node.id, self.curparent);
         }
         visit::walk_struct_def(self, s)
@@ -234,8 +233,8 @@ fn visit_item(&mut self, item: &hir::Item) {
             // public all variants are public unless they're explicitly priv
             hir::ItemEnum(ref def, _) if public_first => {
                 for variant in &def.variants {
-                    self.exported_items.insert(variant.node.id);
-                    self.public_items.insert(variant.node.id);
+                    self.exported_items.insert(variant.node.data.id());
+                    self.public_items.insert(variant.node.data.id());
                 }
             }
 
@@ -320,12 +319,11 @@ fn visit_item(&mut self, item: &hir::Item) {
 
             // Struct constructors are public if the struct is all public.
             hir::ItemStruct(ref def, _) if public_first => {
-                match def.ctor_id {
-                    Some(id) => { self.exported_items.insert(id); }
-                    None => {}
+                if !def.is_struct() {
+                    self.exported_items.insert(def.id());
                 }
                 // fields can be public or private, so lets check
-                for field in &def.fields {
+                for field in def.fields() {
                     let vis = match field.node.kind {
                         hir::NamedField(_, vis) | hir::UnnamedField(vis) => vis
                     };
@@ -1090,8 +1088,8 @@ fn check_inherited(tcx: &ty::ctxt, sp: Span, vis: hir::Visibility) {
                           "visibility has no effect inside functions");
             }
         }
-        let check_struct = |def: &hir::StructDef| {
-            for f in &def.fields {
+        let check_struct = |def: &hir::VariantData| {
+            for f in def.fields() {
                match f.node.kind {
                     hir::NamedField(_, p) => check_inherited(tcx, f.span, p),
                     hir::UnnamedField(..) => {}
@@ -1432,20 +1430,20 @@ fn visit_ty(&mut self, t: &hir::Ty) {
         visit::walk_ty(self, t)
     }
 
-    fn visit_variant(&mut self, v: &hir::Variant, g: &hir::Generics) {
-        if self.exported_items.contains(&v.node.id) {
+    fn visit_variant(&mut self, v: &hir::Variant, g: &hir::Generics, item_id: ast::NodeId) {
+        if self.exported_items.contains(&v.node.data.id()) {
             self.in_variant = true;
-            visit::walk_variant(self, v, g);
+            visit::walk_variant(self, v, g, item_id);
             self.in_variant = false;
         }
     }
 
     fn visit_struct_field(&mut self, s: &hir::StructField) {
-        match s.node.kind {
-            hir::NamedField(_, vis) if vis == hir::Public || self.in_variant => {
-                visit::walk_struct_field(self, s);
-            }
-            _ => {}
+        let vis = match s.node.kind {
+            hir::NamedField(_, vis) | hir::UnnamedField(vis) => vis
+        };
+        if vis == hir::Public || self.in_variant {
+            visit::walk_struct_field(self, s);
         }
     }
 
index f74144565fc588415c475b944dfbf40193f61072..c051f8c263723916ede63359efcb5a17f644b067 100644 (file)
@@ -49,8 +49,6 @@
 use rustc_front::hir::{ItemStruct, ItemTrait, ItemTy, ItemUse};
 use rustc_front::hir::{NamedField, PathListIdent, PathListMod, Public};
 use rustc_front::hir::StmtDecl;
-use rustc_front::hir::StructVariantKind;
-use rustc_front::hir::TupleVariantKind;
 use rustc_front::hir::UnnamedField;
 use rustc_front::hir::{Variant, ViewPathGlob, ViewPathList, ViewPathSimple};
 use rustc_front::hir::Visibility;
@@ -494,9 +492,10 @@ fn build_reduced_graph_for_item(&mut self, item: &Item, parent: &Rc<Module>) ->
             // These items live in both the type and value namespaces.
             ItemStruct(ref struct_def, _) => {
                 // Adding to both Type and Value namespaces or just Type?
-                let (forbid, ctor_id) = match struct_def.ctor_id {
-                    Some(ctor_id)   => (ForbidDuplicateTypesAndValues, Some(ctor_id)),
-                    None            => (ForbidDuplicateTypesAndModules, None)
+                let (forbid, ctor_id) = if struct_def.is_struct() {
+                    (ForbidDuplicateTypesAndModules, None)
+                } else {
+                    (ForbidDuplicateTypesAndValues, Some(struct_def.id()))
                 };
 
                 let name_bindings = self.add_child(name, parent, forbid, sp);
@@ -515,7 +514,7 @@ fn build_reduced_graph_for_item(&mut self, item: &Item, parent: &Rc<Module>) ->
                 }
 
                 // Record the def ID and fields of this struct.
-                let named_fields = struct_def.fields.iter().filter_map(|f| {
+                let named_fields = struct_def.fields().filter_map(|f| {
                     match f.node.kind {
                         NamedField(name, _) => Some(name),
                         UnnamedField(_) => None
@@ -589,14 +588,13 @@ fn build_reduced_graph_for_variant(&mut self,
                                        item_id: DefId,
                                        parent: &Rc<Module>) {
         let name = variant.node.name;
-        let is_exported = match variant.node.kind {
-            TupleVariantKind(_) => false,
-            StructVariantKind(_) => {
-                // Not adding fields for variants as they are not accessed with a self receiver
-                let variant_def_id = self.ast_map.local_def_id(variant.node.id);
-                self.structs.insert(variant_def_id, Vec::new());
-                true
-            }
+        let is_exported = if variant.node.data.is_struct() {
+            // Not adding fields for variants as they are not accessed with a self receiver
+            let variant_def_id = self.ast_map.local_def_id(variant.node.data.id());
+            self.structs.insert(variant_def_id, Vec::new());
+            true
+        } else {
+            false
         };
 
         let child = self.add_child(name, parent,
@@ -605,10 +603,12 @@ fn build_reduced_graph_for_variant(&mut self,
         // variants are always treated as importable to allow them to be glob
         // used
         child.define_value(DefVariant(item_id,
-                                      self.ast_map.local_def_id(variant.node.id), is_exported),
+                                      self.ast_map.local_def_id(variant.node.data.id()),
+                                      is_exported),
                            variant.span, DefModifiers::PUBLIC | DefModifiers::IMPORTABLE);
         child.define_type(DefVariant(item_id,
-                                     self.ast_map.local_def_id(variant.node.id), is_exported),
+                                     self.ast_map.local_def_id(variant.node.data.id()),
+                                     is_exported),
                           variant.span, DefModifiers::PUBLIC | DefModifiers::IMPORTABLE);
     }
 
index 40477d8698ebec8a61f8cf6291421fb05bde3e44..ac09534f1e0e5eecff77883b9fd23f2a2f8b7a0d 100644 (file)
@@ -491,7 +491,7 @@ fn visit_poly_trait_ref(&mut self,
         }
         visit::walk_poly_trait_ref(self, tref, m);
     }
-    fn visit_variant(&mut self, variant: &hir::Variant, generics: &Generics) {
+    fn visit_variant(&mut self, variant: &hir::Variant, generics: &Generics, item_id: ast::NodeId) {
         execute_callback!(hir_map::Node::NodeVariant(variant), self);
         if let Some(ref dis_expr) = variant.node.disr_expr {
             // resolve the discriminator expr as a constant
@@ -501,19 +501,8 @@ fn visit_variant(&mut self, variant: &hir::Variant, generics: &Generics) {
         }
 
         // `visit::walk_variant` without the discriminant expression.
-        match variant.node.kind {
-            hir::TupleVariantKind(ref variant_arguments) => {
-                for variant_argument in variant_arguments {
-                    self.visit_ty(&*variant_argument.ty);
-                }
-            }
-            hir::StructVariantKind(ref struct_definition) => {
-                self.visit_struct_def(&**struct_definition,
-                                      variant.node.name,
-                                      generics,
-                                      variant.node.id);
-            }
-        }
+        self.visit_variant_data(&variant.node.data, variant.node.name,
+                              generics, item_id, variant.span);
     }
     fn visit_foreign_item(&mut self, foreign_item: &hir::ForeignItem) {
         execute_callback!(hir_map::Node::NodeForeignItem(foreign_item), self);
index 05236a7a6fb2823fffee6d1b20ea2105953d4edb..2ad2e7528e442be491b35512d349bd8cb9354cb3 100644 (file)
 
 register_long_diagnostics! {
 
+E0510: r##"
+`return_address` was used in an invalid context. Erroneous code example:
+
+```
+extern "rust-intrinsic" {
+    fn return_address() -> *const u8;
+}
+
+pub unsafe fn by_value() -> i32 {
+    let _ = return_address();
+    // error: invalid use of `return_address` intrinsic: function does
+    //        not use out pointer
+    0
+}
+```
+
+Return values may be stored in a return register(s) or written into a so-called
+out pointer. In case the returned value is too big (this is
+target-ABI-dependent and generally not portable or future proof) to fit into
+the return register(s), the compiler will return the value by writing it into
+space allocated in the caller's stack frame. Example:
+
+```
+extern "rust-intrinsic" {
+    fn return_address() -> *const u8;
+}
+
+pub unsafe fn by_pointer() -> String {
+    let _ = return_address();
+    String::new() // ok!
+}
+```
+"##,
+
+E0511: r##"
+Invalid monomorphization of an intrinsic function was used. Erroneous code
+example:
+
+```
+extern "platform-intrinsic" {
+    fn simd_add<T>(a: T, b: T) -> T;
+}
+
+unsafe { simd_add(0, 1); }
+// error: invalid monomorphization of `simd_add` intrinsic
+```
+
+The generic type has to be a SIMD type. Example:
+
+```
+#[repr(simd)]
+#[derive(Copy, Clone)]
+struct i32x1(i32);
+
+extern "platform-intrinsic" {
+    fn simd_add<T>(a: T, b: T) -> T;
+}
+
+unsafe { simd_add(i32x1(0), i32x1(1)); } // ok!
+```
+"##,
+
+E0512: r##"
+Transmute with two differently sized types was attempted. Erroneous code
+example:
+
+```
+extern "rust-intrinsic" {
+    pub fn ctpop8(x: u8) -> u8;
+}
+
+fn main() {
+    unsafe { ctpop8(::std::mem::transmute(0u16)); }
+    // error: transmute called with differently sized types
+}
+```
+
+Please use types with same size or use the expected type directly. Example:
+
+```
+extern "rust-intrinsic" {
+    pub fn ctpop8(x: u8) -> u8;
+}
+
+fn main() {
+    unsafe { ctpop8(::std::mem::transmute(0i8)); } // ok!
+    // or:
+    unsafe { ctpop8(0u8); } // ok!
+}
+```
+"##,
+
 E0515: r##"
 A constant index expression was out of bounds. Erroneous code example:
 
 Example:
 
 ```
-let x = &[0, 1, 2][2]; // ok!
+let x = &[0, 1, 2][2]; // ok
 ```
 "##,
 
 }
-
-register_diagnostics! {
-    E0510, // invalid use of `return_address` intrinsic: function does not use out pointer
-    E0511, // invalid monomorphization of `{}` intrinsic
-    E0512, // transmute called on types with potentially different sizes...
-}
index 09825f1f919394439c24477ada884cfba7c387ec..e5fadc9a19b92d174207198fdde328590ebfe77d 100644 (file)
@@ -69,7 +69,7 @@ pub struct DumpCsvVisitor<'l, 'tcx: 'l> {
     analysis: &'l ty::CrateAnalysis,
 
     span: SpanUtils<'l>,
-    fmt: FmtStrs<'l>,
+    fmt: FmtStrs<'l, 'tcx>,
 
     cur_scope: NodeId,
 }
@@ -91,7 +91,8 @@ pub fn new(tcx: &'l ty::ctxt<'tcx>,
                                   out: output_file,
                                   dump_spans: false,
                               },
-                              span_utils),
+                              span_utils,
+                              tcx),
             cur_scope: 0,
         }
     }
@@ -458,26 +459,22 @@ fn process_const(&mut self,
 
     fn process_struct(&mut self,
                       item: &ast::Item,
-                      def: &ast::StructDef,
+                      def: &ast::VariantData,
                       ty_params: &ast::Generics) {
         let qualname = format!("::{}", self.tcx.map.path_to_string(item.id));
 
-        let ctor_id = match def.ctor_id {
-            Some(node_id) => node_id,
-            None => ast::DUMMY_NODE_ID,
-        };
         let val = self.span.snippet(item.span);
         let sub_span = self.span.sub_span_after_keyword(item.span, keywords::Struct);
         self.fmt.struct_str(item.span,
                             sub_span,
                             item.id,
-                            ctor_id,
+                            def.id(),
                             &qualname,
                             self.cur_scope,
                             &val);
 
         // fields
-        for field in &def.fields {
+        for field in def.fields() {
             self.process_struct_field_def(field, item.id);
             self.visit_ty(&field.node.ty);
         }
@@ -504,40 +501,19 @@ fn process_enum(&mut self,
             qualname.push_str("::");
             qualname.push_str(name);
             let val = self.span.snippet(variant.span);
-            match variant.node.kind {
-                ast::TupleVariantKind(ref args) => {
-                    // first ident in span is the variant's name
-                    self.fmt.tuple_variant_str(variant.span,
-                                               self.span.span_for_first_ident(variant.span),
-                                               variant.node.id,
-                                               name,
-                                               &qualname,
-                                               &enum_data.qualname,
-                                               &val,
-                                               enum_data.id);
-                    for arg in args {
-                        self.visit_ty(&*arg.ty);
-                    }
-                }
-                ast::StructVariantKind(ref struct_def) => {
-                    let ctor_id = match struct_def.ctor_id {
-                        Some(node_id) => node_id,
-                        None => ast::DUMMY_NODE_ID,
-                    };
-                    self.fmt.struct_variant_str(variant.span,
-                                                self.span.span_for_first_ident(variant.span),
-                                                variant.node.id,
-                                                ctor_id,
-                                                &qualname,
-                                                &enum_data.qualname,
-                                                &val,
-                                                enum_data.id);
-
-                    for field in &struct_def.fields {
-                        self.process_struct_field_def(field, variant.node.id);
-                        self.visit_ty(&*field.node.ty);
-                    }
-                }
+
+            self.fmt.struct_variant_str(variant.span,
+                                        self.span.span_for_first_ident(variant.span),
+                                        variant.node.data.id(),
+                                        variant.node.data.id(),
+                                        &qualname,
+                                        &enum_data.qualname,
+                                        &val,
+                                        enum_data.id);
+
+            for field in variant.node.data.fields() {
+                self.process_struct_field_def(field, variant.node.data.id());
+                self.visit_ty(&*field.node.ty);
             }
         }
         self.process_generic_params(ty_params, item.span, &enum_data.qualname, enum_data.id);
index ade7f95f40bca720b17ca0dd5ab4b7fe4e467df1..a32d8b1b761c540e839e3ad0df8bef5484d0e3ad 100644 (file)
@@ -15,6 +15,7 @@
 
 use metadata::cstore::LOCAL_CRATE;
 use middle::def_id::{CRATE_DEF_INDEX, DefId};
+use middle::ty;
 
 use std::io::Write;
 
@@ -51,9 +52,10 @@ pub fn dump_span(&mut self, su: SpanUtils, kind: &str, span: Span, _sub_span: Op
     }
 }
 
-pub struct FmtStrs<'a> {
+pub struct FmtStrs<'a, 'tcx: 'a> {
     pub recorder: Box<Recorder>,
     span: SpanUtils<'a>,
+    tcx: &'a ty::ctxt<'tcx>,
 }
 
 macro_rules! s { ($e:expr) => { format!("{}", $e) }}
@@ -96,11 +98,29 @@ pub enum Row {
     FnRef,
 }
 
-impl<'a> FmtStrs<'a> {
-    pub fn new(rec: Box<Recorder>, span: SpanUtils<'a>) -> FmtStrs<'a> {
+impl<'a, 'tcx: 'a> FmtStrs<'a, 'tcx> {
+    pub fn new(rec: Box<Recorder>,
+               span: SpanUtils<'a>,
+               tcx: &'a ty::ctxt<'tcx>)
+               -> FmtStrs<'a, 'tcx> {
         FmtStrs {
             recorder: rec,
             span: span,
+            tcx: tcx,
+        }
+    }
+
+    // Emitted ids are used to cross-reference items across crates. DefIds and
+    // NodeIds do not usually correspond in any way. The strategy is to use the
+    // index from the DefId as a crate-local id. However, within a crate, DefId
+    // indices and NodeIds can overlap. So, we must adjust the NodeIds. If an
+    // item can be identified by a DefId as well as a NodeId, then we use the
+    // DefId index as the id. If it can't, then we have to use the NodeId, but
+    // need to adjust it so it will not clash with any possible DefId index.
+    fn normalize_node_id(&self, id: NodeId) -> usize {
+        match self.tcx.map.opt_local_def_id(id) {
+            Some(id) => id.index.as_usize(),
+            None => id as usize + self.tcx.map.num_local_def_ids()
         }
     }
 
@@ -321,6 +341,7 @@ pub fn variable_str(&mut self,
         let mut qualname = String::from(name);
         qualname.push_str("$");
         qualname.push_str(&id.to_string());
+        let id = self.normalize_node_id(id);
         self.check_and_record(Variable,
                               span,
                               sub_span,
@@ -338,6 +359,7 @@ pub fn formal_str(&mut self,
         let mut qualname = String::from(fn_name);
         qualname.push_str("::");
         qualname.push_str(name);
+        let id = self.normalize_node_id(id);
         self.check_and_record(Variable,
                               span,
                               sub_span,
@@ -354,6 +376,8 @@ pub fn static_str(&mut self,
                       value: &str,
                       typ: &str,
                       scope_id: NodeId) {
+        let id = self.normalize_node_id(id);
+        let scope_id = self.normalize_node_id(scope_id);
         self.check_and_record(Variable,
                               span,
                               sub_span,
@@ -368,6 +392,8 @@ pub fn field_str(&mut self,
                      qualname: &str,
                      typ: &str,
                      scope_id: NodeId) {
+        let id = self.normalize_node_id(id);
+        let scope_id = self.normalize_node_id(scope_id);
         self.check_and_record(Variable,
                               span,
                               sub_span,
@@ -381,6 +407,8 @@ pub fn enum_str(&mut self,
                     name: &str,
                     scope_id: NodeId,
                     value: &str) {
+        let id = self.normalize_node_id(id);
+        let scope_id = self.normalize_node_id(scope_id);
         self.check_and_record(Enum, span, sub_span, svec!(id, name, scope_id, value));
     }
 
@@ -393,6 +421,8 @@ pub fn tuple_variant_str(&mut self,
                              typ: &str,
                              val: &str,
                              scope_id: NodeId) {
+        let id = self.normalize_node_id(id);
+        let scope_id = self.normalize_node_id(scope_id);
         self.check_and_record(Variant,
                               span,
                               sub_span,
@@ -408,6 +438,9 @@ pub fn struct_variant_str(&mut self,
                               typ: &str,
                               val: &str,
                               scope_id: NodeId) {
+        let id = self.normalize_node_id(id);
+        let scope_id = self.normalize_node_id(scope_id);
+        let ctor_id = self.normalize_node_id(ctor_id);
         self.check_and_record(VariantStruct,
                               span,
                               sub_span,
@@ -420,6 +453,8 @@ pub fn fn_str(&mut self,
                   id: NodeId,
                   name: &str,
                   scope_id: NodeId) {
+        let id = self.normalize_node_id(id);
+        let scope_id = self.normalize_node_id(scope_id);
         self.check_and_record(Function,
                               span,
                               sub_span,
@@ -433,6 +468,8 @@ pub fn method_str(&mut self,
                       name: &str,
                       decl_id: Option<DefId>,
                       scope_id: NodeId) {
+        let id = self.normalize_node_id(id);
+        let scope_id = self.normalize_node_id(scope_id);
         let values = match decl_id {
             Some(decl_id) => svec!(id,
                                    name,
@@ -450,6 +487,8 @@ pub fn method_decl_str(&mut self,
                            id: NodeId,
                            name: &str,
                            scope_id: NodeId) {
+        let id = self.normalize_node_id(id);
+        let scope_id = self.normalize_node_id(scope_id);
         self.check_and_record(MethodDecl, span, sub_span, svec!(id, name, scope_id));
     }
 
@@ -461,6 +500,9 @@ pub fn struct_str(&mut self,
                       name: &str,
                       scope_id: NodeId,
                       value: &str) {
+        let id = self.normalize_node_id(id);
+        let scope_id = self.normalize_node_id(scope_id);
+        let ctor_id = self.normalize_node_id(ctor_id);
         self.check_and_record(Struct,
                               span,
                               sub_span,
@@ -474,6 +516,8 @@ pub fn trait_str(&mut self,
                      name: &str,
                      scope_id: NodeId,
                      value: &str) {
+        let id = self.normalize_node_id(id);
+        let scope_id = self.normalize_node_id(scope_id);
         self.check_and_record(Trait, span, sub_span, svec!(id, name, scope_id, value));
     }
 
@@ -484,6 +528,8 @@ pub fn impl_str(&mut self,
                     ref_id: Option<DefId>,
                     trait_id: Option<DefId>,
                     scope_id: NodeId) {
+        let id = self.normalize_node_id(id);
+        let scope_id = self.normalize_node_id(scope_id);
         let ref_id = ref_id.unwrap_or(CRATE_ROOT_DEF_ID);
         let trait_id = trait_id.unwrap_or(CRATE_ROOT_DEF_ID);
         self.check_and_record(Impl,
@@ -504,6 +550,8 @@ pub fn mod_str(&mut self,
                    name: &str,
                    parent: NodeId,
                    filename: &str) {
+        let id = self.normalize_node_id(id);
+        let parent = self.normalize_node_id(parent);
         self.check_and_record(Module,
                               span,
                               sub_span,
@@ -517,6 +565,8 @@ pub fn use_alias_str(&mut self,
                          mod_id: Option<DefId>,
                          name: &str,
                          parent: NodeId) {
+        let id = self.normalize_node_id(id);
+        let parent = self.normalize_node_id(parent);
         let mod_id = mod_id.unwrap_or(CRATE_ROOT_DEF_ID);
         self.check_and_record(UseAlias,
                               span,
@@ -530,6 +580,8 @@ pub fn use_glob_str(&mut self,
                         id: NodeId,
                         values: &str,
                         parent: NodeId) {
+        let id = self.normalize_node_id(id);
+        let parent = self.normalize_node_id(parent);
         self.check_and_record(UseGlob, span, sub_span, svec!(id, values, parent));
     }
 
@@ -541,6 +593,8 @@ pub fn extern_crate_str(&mut self,
                             name: &str,
                             loc: &str,
                             parent: NodeId) {
+        let id = self.normalize_node_id(id);
+        let parent = self.normalize_node_id(parent);
         self.check_and_record(ExternCrate,
                               span,
                               sub_span,
@@ -552,6 +606,7 @@ pub fn inherit_str(&mut self,
                        sub_span: Option<Span>,
                        base_id: DefId,
                        deriv_id: NodeId) {
+        let deriv_id = self.normalize_node_id(deriv_id);
         self.check_and_record(Inheritance,
                               span,
                               sub_span,
@@ -563,6 +618,7 @@ pub fn fn_call_str(&mut self,
                        sub_span: Option<Span>,
                        id: DefId,
                        scope_id: NodeId) {
+        let scope_id = self.normalize_node_id(scope_id);
         self.check_and_record(FnCall,
                               span,
                               sub_span,
@@ -575,6 +631,7 @@ pub fn meth_call_str(&mut self,
                          defid: Option<DefId>,
                          declid: Option<DefId>,
                          scope_id: NodeId) {
+        let scope_id = self.normalize_node_id(scope_id);
         let defid = defid.unwrap_or(CRATE_ROOT_DEF_ID);
         let (dcn, dck) = match declid {
             Some(declid) => (s!(declid.index.as_usize()), s!(declid.krate)),
@@ -587,6 +644,7 @@ pub fn meth_call_str(&mut self,
     }
 
     pub fn sub_mod_ref_str(&mut self, span: Span, sub_span: Span, qualname: &str, parent: NodeId) {
+        let parent = self.normalize_node_id(parent);
         self.record_with_span(ModRef, span, sub_span, svec!(0, 0, qualname, parent));
     }
 
@@ -596,6 +654,7 @@ pub fn typedef_str(&mut self,
                        id: NodeId,
                        qualname: &str,
                        value: &str) {
+        let id = self.normalize_node_id(id);
         self.check_and_record(Typedef, span, sub_span, svec!(id, qualname, value));
     }
 
@@ -621,6 +680,7 @@ pub fn ref_str(&mut self,
                    sub_span: Option<Span>,
                    id: DefId,
                    scope_id: NodeId) {
+        let scope_id = self.normalize_node_id(scope_id);
         self.check_and_record(kind,
                               span,
                               sub_span,
index 05b20ac3fb7d436a3d3fead1315e4b7f245f2502..9fa1aaf76f819dc5fcd1d31c42c954a9ff874e69 100644 (file)
@@ -2428,13 +2428,12 @@ pub fn get_item_val(ccx: &CrateContext, id: ast::NodeId) -> ValueRef {
 
         hir_map::NodeVariant(ref v) => {
             let llfn;
-            let args = match v.node.kind {
-                hir::TupleVariantKind(ref args) => args,
-                hir::StructVariantKind(_) => {
-                    ccx.sess().bug("struct variant kind unexpected in get_item_val")
-                }
+            let fields = if v.node.data.is_struct() {
+                ccx.sess().bug("struct variant kind unexpected in get_item_val")
+            } else {
+                v.node.data.fields()
             };
-            assert!(!args.is_empty());
+            assert!(fields.count() != 0);
             let ty = ccx.tcx().node_id_to_type(id);
             let parent = ccx.tcx().map.get_parent(id);
             let enm = ccx.tcx().map.expect_item(parent);
@@ -2455,12 +2454,11 @@ pub fn get_item_val(ccx: &CrateContext, id: ast::NodeId) -> ValueRef {
 
         hir_map::NodeStructCtor(struct_def) => {
             // Only register the constructor if this is a tuple-like struct.
-            let ctor_id = match struct_def.ctor_id {
-                None => {
-                    ccx.sess().bug("attempt to register a constructor of \
-                                    a non-tuple-like struct")
-                }
-                Some(ctor_id) => ctor_id,
+            let ctor_id = if struct_def.is_struct() {
+                ccx.sess().bug("attempt to register a constructor of \
+                                  a non-tuple-like struct")
+            } else {
+                struct_def.id()
             };
             let parent = ccx.tcx().map.get_parent(id);
             let struct_item = ccx.tcx().map.expect_item(parent);
index fa3824866ccb8880738d9055fa54e1e9fe94437a..3ca82b673ff5b1c181ede27c63677333b7755976 100644 (file)
@@ -410,18 +410,53 @@ fn x86_64_ty<F>(ccx: &CrateContext,
         }
     }
 
-    let mut arg_tys = Vec::new();
-    for t in atys {
-        let ty = x86_64_ty(ccx, *t, |cls| cls.is_pass_byval(), Attribute::ByVal);
-        arg_tys.push(ty);
-    }
+    let mut int_regs = 6; // RDI, RSI, RDX, RCX, R8, R9
+    let mut sse_regs = 8;
 
     let ret_ty = if ret_def {
-        x86_64_ty(ccx, rty, |cls| cls.is_ret_bysret(), Attribute::StructRet)
+        x86_64_ty(ccx, rty, |cls| {
+            if cls.is_ret_bysret() {
+                // `sret` parameter thus one less register available
+                int_regs -= 1;
+                true
+            } else {
+                false
+            }
+        }, Attribute::StructRet)
     } else {
         ArgType::direct(Type::void(ccx), None, None, None)
     };
 
+    let mut arg_tys = Vec::new();
+    for t in atys {
+        let ty = x86_64_ty(ccx, *t, |cls| {
+            let needed_int = cls.iter().filter(|&&c| c == Int).count();
+            let needed_sse = cls.iter().filter(|c| c.is_sse()).count();
+            let in_mem = cls.is_pass_byval() ||
+                         int_regs < needed_int ||
+                         sse_regs < needed_sse;
+            if in_mem {
+                // `byval` parameter thus one less integer register available
+                int_regs -= 1;
+            } else {
+                // split into sized chunks passed individually
+                int_regs -= needed_int;
+                sse_regs -= needed_sse;
+            }
+            in_mem
+        }, Attribute::ByVal);
+        arg_tys.push(ty);
+
+        // An integer, pointer, double or float parameter
+        // thus the above closure passed to `x86_64_ty` won't
+        // get called.
+        if t.kind() == Integer || t.kind() == Pointer {
+            int_regs -= 1;
+        } else if t.kind() == Double || t.kind() == Float {
+            sse_regs -= 1;
+        }
+    }
+
     return FnType {
         arg_tys: arg_tys,
         ret_ty: ret_ty,
index 0a39150dbd36a684fcdd358588044a6d841d73d1..120c8dc0384cef59da2c947aa50b500cc866f46a 100644 (file)
@@ -46,7 +46,7 @@ pub fn compute_abi_info(ccx: &CrateContext,
                     2 => ArgType::direct(t, Some(Type::i16(ccx)), None, None),
                     4 => ArgType::direct(t, Some(Type::i32(ccx)), None, None),
                     8 => ArgType::direct(t, Some(Type::i64(ccx)), None, None),
-                    _ => ArgType::indirect(t, Some(Attribute::ByVal))
+                    _ => ArgType::indirect(t, None)
                 }
             }
             _ => {
index 86a65f57bdab08b6859bcd695f7ddef865dcf319..c8525e33e2667e6f22619c784cf422f97dd97ace 100644 (file)
@@ -417,10 +417,9 @@ fn is_named_tuple_constructor(tcx: &ty::ctxt, def_id: DefId) -> bool {
             || "local item should be in ast map".to_string());
 
         match map_node {
-            hir_map::NodeVariant(v) => match v.node.kind {
-                hir::TupleVariantKind(ref args) => !args.is_empty(),
-                _ => false
-            },
+            hir_map::NodeVariant(v) => {
+                v.node.data.is_tuple()
+            }
             hir_map::NodeStructCtor(_) => true,
             _ => false
         }
index f509ed8dc5cbc62628f647d5a47f3901c41d9058..7c72b249a6e81afa5f95181d8760cc74ec84389e 100644 (file)
@@ -818,7 +818,7 @@ fn const_expr_unadjusted<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
                         ty::VariantKind::Tuple => {
                             expr::trans_def_fn_unadjusted(cx, e, def, param_substs).val
                         }
-                        ty::VariantKind::Dict => {
+                        ty::VariantKind::Struct => {
                             cx.sess().span_bug(e.span, "path-expr refers to a dict variant!")
                         }
                     }
index bc5152cba1f2cd7b0da2391f1b98f82ce0f9371c..aeda8f723cfeea3c7961b208b591bd10428fe78c 100644 (file)
@@ -1365,7 +1365,7 @@ fn create_member_descriptions<'a>(&self, cx: &CrateContext<'a, 'tcx>)
                 let sole_struct_member_description = MemberDescription {
                     name: match non_null_variant.kind() {
                         ty::VariantKind::Tuple => "__0".to_string(),
-                        ty::VariantKind::Dict => {
+                        ty::VariantKind::Struct => {
                             non_null_variant.fields[0].name.to_string()
                         }
                         ty::VariantKind::Unit => unreachable!()
@@ -1540,7 +1540,7 @@ fn describe_enum_variant<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
                    .map(|(i, _)| format!("__{}", i))
                    .collect()
         }
-        ty::VariantKind::Dict => {
+        ty::VariantKind::Struct => {
             variant.fields
                    .iter()
                    .map(|f| f.name.to_string())
index 6b9f1559d3793c3eb081cd0b0b60c152d9c06052..95e9e8581bd614b22c3b643c1834165931404ab2 100644 (file)
@@ -27,6 +27,7 @@
 use trans::type_::Type;
 use trans::type_of::*;
 use trans::type_of;
+use middle::infer;
 use middle::ty::{self, Ty};
 use middle::subst::Substs;
 
@@ -254,6 +255,7 @@ pub fn trans_native_call<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
         _ => ccx.sess().bug("trans_native_call called on non-function type")
     };
     let fn_sig = ccx.tcx().erase_late_bound_regions(fn_sig);
+    let fn_sig = infer::normalize_associated_type(ccx.tcx(), &fn_sig);
     let llsig = foreign_signature(ccx, &fn_sig, &passed_arg_tys[..]);
     let fn_type = cabi::compute_abi_info(ccx,
                                          &llsig.llarg_tys,
@@ -558,8 +560,6 @@ pub fn register_rust_fn_with_foreign_abi(ccx: &CrateContext,
                                          -> ValueRef {
     let _icx = push_ctxt("foreign::register_foreign_fn");
 
-    let tys = foreign_types_for_id(ccx, node_id);
-    let llfn_ty = lltype_for_fn_from_foreign_types(ccx, &tys);
     let t = ccx.tcx().node_id_to_type(node_id);
     let cconv = match t.sty {
         ty::TyBareFn(_, ref fn_ty) => {
@@ -567,6 +567,8 @@ pub fn register_rust_fn_with_foreign_abi(ccx: &CrateContext,
         }
         _ => panic!("expected bare fn in register_rust_fn_with_foreign_abi")
     };
+    let tys = foreign_types_for_fn_ty(ccx, t);
+    let llfn_ty = lltype_for_fn_from_foreign_types(ccx, &tys);
     let llfn = base::register_fn_llvmty(ccx, sp, sym, node_id, cconv, llfn_ty);
     add_argument_attributes(&tys, llfn);
     debug!("register_rust_fn_with_foreign_abi(node_id={}, llfn_ty={}, llfn={})",
@@ -937,11 +939,6 @@ fn foreign_signature<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
     }
 }
 
-fn foreign_types_for_id<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
-                                  id: ast::NodeId) -> ForeignTypes<'tcx> {
-    foreign_types_for_fn_ty(ccx, ccx.tcx().node_id_to_type(id))
-}
-
 fn foreign_types_for_fn_ty<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
                                      ty: Ty<'tcx>) -> ForeignTypes<'tcx> {
     let fn_sig = match ty.sty {
@@ -949,6 +946,7 @@ fn foreign_types_for_fn_ty<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
         _ => ccx.sess().bug("foreign_types_for_fn_ty called on non-function type")
     };
     let fn_sig = ccx.tcx().erase_late_bound_regions(fn_sig);
+    let fn_sig = infer::normalize_associated_type(ccx.tcx(), &fn_sig);
     let llsig = foreign_signature(ccx, &fn_sig, &fn_sig.inputs);
     let fn_ty = cabi::compute_abi_info(ccx,
                                        &llsig.llarg_tys,
index b8f75df8c11caae241d638dbe2bbd0d24a192bc7..14e1ca7675f790f9981089818017478ff4a362eb 100644 (file)
@@ -110,18 +110,17 @@ fn instantiate_inline(ccx: &CrateContext, fn_id: DefId)
                     let ty_vs = &ccx.tcx().lookup_adt_def(parent_id).variants;
                     assert_eq!(ast_vs.len(), ty_vs.len());
                     for (ast_v, ty_v) in ast_vs.iter().zip(ty_vs.iter()) {
-                        if ty_v.did == fn_id { my_id = ast_v.node.id; }
-                        ccx.external().borrow_mut().insert(ty_v.did, Some(ast_v.node.id));
+                        if ty_v.did == fn_id { my_id = ast_v.node.data.id(); }
+                        ccx.external().borrow_mut().insert(ty_v.did, Some(ast_v.node.data.id()));
                     }
                 }
                 hir::ItemStruct(ref struct_def, _) => {
-                    match struct_def.ctor_id {
-                        None => ccx.sess().bug("instantiate_inline: called on a \
-                                                non-tuple struct"),
-                        Some(ctor_id) => {
-                            ccx.external().borrow_mut().insert(fn_id, Some(ctor_id));
-                            my_id = ctor_id;
-                        }
+                    if struct_def.is_struct() {
+                        ccx.sess().bug("instantiate_inline: called on a \
+                                                                 non-tuple struct")
+                    } else {
+                        ccx.external().borrow_mut().insert(fn_id, Some(struct_def.id()));
+                        my_id = struct_def.id();
                     }
                 }
                 _ => ccx.sess().bug("instantiate_inline: item has a \
index 33f798be85e87101c66663c0f44c7ca79ee5fb66..f84f0feb9603020e139ed75e6b6e3299b2b63884 100644 (file)
@@ -246,9 +246,11 @@ pub fn monomorphic_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
         hir_map::NodeStructCtor(struct_def) => {
             let d = mk_lldecl(abi::Rust);
             attributes::inline(d, attributes::InlineAttr::Hint);
+            if struct_def.is_struct() {
+                panic!("ast-mapped struct didn't have a ctor id")
+            }
             base::trans_tuple_struct(ccx,
-                                     struct_def.ctor_id.expect("ast-mapped tuple struct \
-                                                                didn't have a ctor id"),
+                                     struct_def.id(),
                                      psubsts,
                                      d);
             d
index 8bcff22575563592178e9f678495cc02e1717160..db5dd19c9236c68013dacca90f87cb61f2c545df 100644 (file)
@@ -530,7 +530,7 @@ pub fn check_pat_struct<'a, 'tcx>(pcx: &pat_ctxt<'a, 'tcx>, pat: &'tcx hir::Pat,
     let tcx = pcx.fcx.ccx.tcx;
 
     let def = tcx.def_map.borrow().get(&pat.id).unwrap().full_def();
-    let variant = match fcx.def_struct_variant(def) {
+    let variant = match fcx.def_struct_variant(def, path.span) {
         Some((_, variant)) => variant,
         None => {
             let name = pprust::path_to_string(path);
index f6b007018b88a6b3b97c83ef7d3eace3715ae67d..ba1af220d8e0fb915d062864a577fd210be77eb9 100644 (file)
@@ -1464,7 +1464,8 @@ pub fn instantiate_type(&self,
 
     /// Return the dict-like variant corresponding to a given `Def`.
     pub fn def_struct_variant(&self,
-                              def: def::Def)
+                              def: def::Def,
+                              span: Span)
                               -> Option<(ty::AdtDef<'tcx>, ty::VariantDef<'tcx>)>
     {
         let (adt, variant) = match def {
@@ -1484,11 +1485,20 @@ pub fn def_struct_variant(&self,
         };
 
         let var_kind = variant.kind();
-        if var_kind == ty::VariantKind::Dict || var_kind == ty::VariantKind::Unit {
+        if var_kind == ty::VariantKind::Struct {
             Some((adt, variant))
-        } else {
-            None
-        }
+        } else if var_kind == ty::VariantKind::Unit {
+            if !self.tcx().sess.features.borrow().braced_empty_structs {
+                self.tcx().sess.span_err(span, "empty structs and enum variants \
+                                                with braces are unstable");
+                fileline_help!(self.tcx().sess, span, "add #![feature(braced_empty_structs)] to \
+                                                       the crate features to enable");
+            }
+
+             Some((adt, variant))
+         } else {
+             None
+         }
     }
 
     pub fn write_nil(&self, node_id: ast::NodeId) {
@@ -3177,7 +3187,7 @@ fn check_expr_struct<'a, 'tcx>(fcx: &FnCtxt<'a,'tcx>,
 
         // Find the relevant variant
         let def = lookup_full_def(tcx, path.span, expr.id);
-        let (adt, variant) = match fcx.def_struct_variant(def) {
+        let (adt, variant) = match fcx.def_struct_variant(def, path.span) {
             Some((adt, variant)) => (adt, variant),
             None => {
                 span_err!(fcx.tcx().sess, path.span, E0071,
index c2610da3944cc5fd010304b22f1e162eddc79a16..31e6c942dc697f75e5716f138d23f914cc8ef965 100644 (file)
@@ -592,6 +592,8 @@ fn visit_expr(rcx: &mut Rcx, expr: &hir::Expr) {
         };
 
         substs_wf_in_scope(rcx, origin, &callee.substs, expr.span, expr_region);
+        type_must_outlive(rcx, infer::ExprTypeIsNotInScope(callee.ty, expr.span),
+                          callee.ty, expr_region);
     }
 
     // Check any autoderefs or autorefs that appear.
@@ -664,6 +666,8 @@ fn visit_expr(rcx: &mut Rcx, expr: &hir::Expr) {
         }
     }
 
+    debug!("regionck::visit_expr(e={:?}, repeating_scope={}) - visiting subexprs",
+           expr, rcx.repeating_scope);
     match expr.node {
         hir::ExprPath(..) => {
             rcx.fcx.opt_node_ty_substs(expr.id, |item_substs| {
index b5cf069bda6847dcade038ccfc1f6a1e83c8f764..14947d9955efdce9602e8564b4baf1d9d60f1888 100644 (file)
@@ -624,11 +624,10 @@ struct AdtField<'tcx> {
 }
 
 fn struct_variant<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
-                            struct_def: &hir::StructDef)
+                            struct_def: &hir::VariantData)
                             -> AdtVariant<'tcx> {
     let fields =
-        struct_def.fields
-        .iter()
+        struct_def.fields()
         .map(|field| {
             let field_ty = fcx.tcx().node_id_to_type(field.node.id);
             let field_ty = fcx.instantiate_type_scheme(field.span,
@@ -647,41 +646,7 @@ fn enum_variants<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
                            enum_def: &hir::EnumDef)
                            -> Vec<AdtVariant<'tcx>> {
     enum_def.variants.iter()
-        .map(|variant| {
-            match variant.node.kind {
-                hir::TupleVariantKind(ref args) if !args.is_empty() => {
-                    let ctor_ty = fcx.tcx().node_id_to_type(variant.node.id);
-
-                    // the regions in the argument types come from the
-                    // enum def'n, and hence will all be early bound
-                    let arg_tys = fcx.tcx().no_late_bound_regions(&ctor_ty.fn_args()).unwrap();
-                    AdtVariant {
-                        fields: args.iter().enumerate().map(|(index, arg)| {
-                            let arg_ty = arg_tys[index];
-                            let arg_ty =
-                                fcx.instantiate_type_scheme(variant.span,
-                                                            &fcx.inh
-                                                                .infcx
-                                                                .parameter_environment
-                                                                .free_substs,
-                                                            &arg_ty);
-                            AdtField {
-                                ty: arg_ty,
-                                span: arg.ty.span
-                            }
-                        }).collect()
-                    }
-                }
-                hir::TupleVariantKind(_) => {
-                    AdtVariant {
-                        fields: Vec::new()
-                    }
-                }
-                hir::StructVariantKind(ref struct_def) => {
-                    struct_variant(fcx, &**struct_def)
-                }
-            }
-        })
+        .map(|variant| struct_variant(fcx, &variant.node.data))
         .collect()
 }
 
index b8d942ad22703ddf23dbb3792ceae67c3d0c6091..4cfc34dbb2384d836a5d3cf73740a9192e3830d1 100644 (file)
@@ -521,11 +521,10 @@ struct AdtField<'tcx> {
 }
 
 fn struct_variant<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
-                            struct_def: &hir::StructDef)
+                            struct_def: &hir::VariantData)
                             -> AdtVariant<'tcx> {
     let fields =
-        struct_def.fields
-        .iter()
+        struct_def.fields()
         .map(|field| {
             let field_ty = fcx.tcx().node_id_to_type(field.node.id);
             let field_ty = fcx.instantiate_type_scheme(field.span,
@@ -544,41 +543,7 @@ fn enum_variants<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
                            enum_def: &hir::EnumDef)
                            -> Vec<AdtVariant<'tcx>> {
     enum_def.variants.iter()
-        .map(|variant| {
-            match variant.node.kind {
-                hir::TupleVariantKind(ref args) if !args.is_empty() => {
-                    let ctor_ty = fcx.tcx().node_id_to_type(variant.node.id);
-
-                    // the regions in the argument types come from the
-                    // enum def'n, and hence will all be early bound
-                    let arg_tys = fcx.tcx().no_late_bound_regions(&ctor_ty.fn_args()).unwrap();
-                    AdtVariant {
-                        fields: args.iter().enumerate().map(|(index, arg)| {
-                            let arg_ty = arg_tys[index];
-                            let arg_ty =
-                                fcx.instantiate_type_scheme(variant.span,
-                                                            &fcx.inh
-                                                                .infcx
-                                                                .parameter_environment
-                                                                .free_substs,
-                                                            &arg_ty);
-                            AdtField {
-                                ty: arg_ty,
-                                span: arg.ty.span
-                            }
-                        }).collect()
-                    }
-                }
-                hir::TupleVariantKind(_) => {
-                    AdtVariant {
-                        fields: Vec::new()
-                    }
-                }
-                hir::StructVariantKind(ref struct_def) => {
-                    struct_variant(fcx, &**struct_def)
-                }
-            }
-        })
+        .map(|variant| struct_variant(fcx, &variant.node.data))
         .collect()
 }
 
index 16884e76a8ec72279169d32edb71323b969905d7..2c18a245159cffbfe5924fb3db0417f76588b896 100644 (file)
@@ -131,7 +131,7 @@ fn fix_scalar_binary_expr(&mut self, e: &hir::Expr) {
                                 "overloaded augmented assignments are not stable");
                             fileline_help!(
                                 tcx.sess, e.span,
-                                "add #![feature(augmented_assignments)] to the crate features \
+                                "add #![feature(augmented_assignments)] to the crate root \
                                  to enable");
                         }
                     }
index 69d170602303bab99afe0669e5b0cd1052874163..194710a46fbceb388f30665b12aabe1c351f46ea 100644 (file)
@@ -1010,12 +1010,12 @@ fn convert_item(ccx: &CrateCtxt, it: &hir::Item) {
             let it_def_id = ccx.tcx.map.local_def_id(it.id);
             let variant = tcx.lookup_adt_def_master(it_def_id).struct_variant();
 
-            for (f, ty_f) in struct_def.fields.iter().zip(variant.fields.iter()) {
+            for (f, ty_f) in struct_def.fields().zip(variant.fields.iter()) {
                 convert_field(ccx, &scheme.generics, &predicates, f, ty_f)
             }
 
-            if let Some(ctor_id) = struct_def.ctor_id {
-                convert_variant_ctor(tcx, ctor_id, variant, scheme, predicates);
+            if !struct_def.is_struct() {
+                convert_variant_ctor(tcx, struct_def.id(), variant, scheme, predicates);
             }
         },
         hir::ItemTy(_, ref generics) => {
@@ -1039,7 +1039,7 @@ fn convert_variant_ctor<'a, 'tcx>(tcx: &ty::ctxt<'tcx>,
                                   scheme: ty::TypeScheme<'tcx>,
                                   predicates: ty::GenericPredicates<'tcx>) {
     let ctor_ty = match variant.kind() {
-        VariantKind::Unit | VariantKind::Dict => scheme.ty,
+        VariantKind::Unit | VariantKind::Struct => scheme.ty,
         VariantKind::Tuple => {
             let inputs: Vec<_> =
                 variant.fields
@@ -1065,32 +1065,17 @@ fn convert_enum_variant_types<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
                                         scheme: ty::TypeScheme<'tcx>,
                                         predicates: ty::GenericPredicates<'tcx>,
                                         variants: &[P<hir::Variant>]) {
-    let tcx = ccx.tcx;
-    let icx = ccx.icx(&predicates);
-
     // fill the field types
     for (variant, ty_variant) in variants.iter().zip(def.variants.iter()) {
-        match variant.node.kind {
-            hir::TupleVariantKind(ref args) => {
-                let rs = ExplicitRscope;
-                let input_tys: Vec<_> = args.iter().map(|va| icx.to_ty(&rs, &*va.ty)).collect();
-                for (field, &ty) in ty_variant.fields.iter().zip(input_tys.iter()) {
-                    field.fulfill_ty(ty);
-                }
-            }
-
-            hir::StructVariantKind(ref struct_def) => {
-                for (f, ty_f) in struct_def.fields.iter().zip(ty_variant.fields.iter()) {
-                    convert_field(ccx, &scheme.generics, &predicates, f, ty_f)
-                }
-            }
-        };
+        for (f, ty_f) in variant.node.data.fields().zip(ty_variant.fields.iter()) {
+            convert_field(ccx, &scheme.generics, &predicates, f, ty_f)
+        }
 
         // Convert the ctor, if any. This also registers the variant as
         // an item.
         convert_variant_ctor(
-            tcx,
-            variant.node.id,
+            ccx.tcx,
+            variant.node.data.id(),
             ty_variant,
             scheme.clone(),
             predicates.clone()
@@ -1102,9 +1087,9 @@ fn convert_struct_variant<'tcx>(tcx: &ty::ctxt<'tcx>,
                                 did: DefId,
                                 name: ast::Name,
                                 disr_val: ty::Disr,
-                                def: &hir::StructDef) -> ty::VariantDefData<'tcx, 'tcx> {
+                                def: &hir::VariantData) -> ty::VariantDefData<'tcx, 'tcx> {
     let mut seen_fields: FnvHashMap<ast::Name, Span> = FnvHashMap();
-    let fields = def.fields.iter().map(|f| {
+    let fields = def.fields().map(|f| {
         let fid = tcx.map.local_def_id(f.node.id);
         match f.node.kind {
             hir::NamedField(name, vis) => {
@@ -1135,13 +1120,16 @@ fn convert_struct_variant<'tcx>(tcx: &ty::ctxt<'tcx>,
 
 fn convert_struct_def<'tcx>(tcx: &ty::ctxt<'tcx>,
                             it: &hir::Item,
-                            def: &hir::StructDef)
+                            def: &hir::VariantData)
                             -> ty::AdtDefMaster<'tcx>
 {
 
     let did = tcx.map.local_def_id(it.id);
-    let ctor_id = def.ctor_id.map_or(did,
-        |ctor_id| tcx.map.local_def_id(ctor_id));
+    let ctor_id = if !def.is_struct() {
+        tcx.map.local_def_id(def.id())
+    } else {
+        did
+    };
     tcx.intern_adt_def(
         did,
         ty::AdtKind::Struct,
@@ -1221,27 +1209,9 @@ fn convert_enum_variant<'tcx>(tcx: &ty::ctxt<'tcx>,
                                   disr: ty::Disr)
                                   -> ty::VariantDefData<'tcx, 'tcx>
     {
-        let did = tcx.map.local_def_id(v.node.id);
+        let did = tcx.map.local_def_id(v.node.data.id());
         let name = v.node.name;
-        match v.node.kind {
-            hir::TupleVariantKind(ref va) => {
-                ty::VariantDefData {
-                    did: did,
-                    name: name,
-                    disr_val: disr,
-                    fields: va.iter().map(|&hir::VariantArg { id, .. }| {
-                        ty::FieldDefData::new(
-                            tcx.map.local_def_id(id),
-                            special_idents::unnamed_field.name,
-                            hir::Visibility::Public
-                        )
-                    }).collect()
-                }
-            }
-            hir::StructVariantKind(ref def) => {
-                convert_struct_variant(tcx, did, name, disr, &def)
-            }
-        }
+        convert_struct_variant(tcx, did, name, disr, &v.node.data)
     }
     let did = tcx.map.local_def_id(it.id);
     let repr_hints = tcx.lookup_repr_hints(did);
index 160c7e7d754d9d12cb253719329e0010f8487ab9..e4420d0dd92fa0ce11cf0994497aa3f6a2d9481c 100644 (file)
@@ -1805,11 +1805,11 @@ pub struct VariantStruct {
     pub fields_stripped: bool,
 }
 
-impl Clean<VariantStruct> for ::rustc_front::hir::StructDef {
+impl Clean<VariantStruct> for ::rustc_front::hir::VariantData {
     fn clean(&self, cx: &DocContext) -> VariantStruct {
         VariantStruct {
             struct_type: doctree::struct_type_from_def(self),
-            fields: self.fields.clean(cx),
+            fields: self.fields().map(|x| x.clean(cx)).collect(),
             fields_stripped: false,
         }
     }
@@ -1853,9 +1853,9 @@ fn clean(&self, cx: &DocContext) -> Item {
             source: self.whence.clean(cx),
             visibility: None,
             stability: self.stab.clean(cx),
-            def_id: cx.map.local_def_id(self.id),
+            def_id: cx.map.local_def_id(self.def.id()),
             inner: VariantItem(Variant {
-                kind: self.kind.clean(cx),
+                kind: struct_def_to_variant_kind(&self.def, cx),
             }),
         }
     }
@@ -1871,7 +1871,7 @@ fn clean(&self, cx: &DocContext) -> Item {
                     self.fields.iter().map(|f| f.unsubst_ty().clean(cx)).collect()
                 )
             }
-            ty::VariantKind::Dict => {
+            ty::VariantKind::Struct => {
                 StructVariant(VariantStruct {
                     struct_type: doctree::Plain,
                     fields_stripped: false,
@@ -1917,18 +1917,13 @@ pub enum VariantKind {
     StructVariant(VariantStruct),
 }
 
-impl Clean<VariantKind> for hir::VariantKind {
-    fn clean(&self, cx: &DocContext) -> VariantKind {
-        match self {
-            &hir::TupleVariantKind(ref args) => {
-                if args.is_empty() {
-                    CLikeVariant
-                } else {
-                    TupleVariant(args.iter().map(|x| x.ty.clean(cx)).collect())
-                }
-            },
-            &hir::StructVariantKind(ref sd) => StructVariant(sd.clean(cx)),
-        }
+fn struct_def_to_variant_kind(struct_def: &hir::VariantData, cx: &DocContext) -> VariantKind {
+    if struct_def.is_struct() {
+        StructVariant(struct_def.clean(cx))
+    } else if struct_def.is_unit() {
+        CLikeVariant
+    } else {
+        TupleVariant(struct_def.fields().map(|x| x.node.ty.clean(cx)).collect())
     }
 }
 
index c234ec01b88698d37dac2a510ff72241c5894d19..47cc007f605ebd1e10b8579652c24bcab86e0976 100644 (file)
@@ -119,8 +119,7 @@ pub struct Enum {
 pub struct Variant {
     pub name: Name,
     pub attrs: Vec<ast::Attribute>,
-    pub kind: hir::VariantKind,
-    pub id: ast::NodeId,
+    pub def: P<hir::VariantData>,
     pub stab: Option<attr::Stability>,
     pub whence: Span,
 }
@@ -234,10 +233,10 @@ pub struct Import {
     pub whence: Span,
 }
 
-pub fn struct_type_from_def(sd: &hir::StructDef) -> StructType {
-    if sd.ctor_id.is_some() {
+pub fn struct_type_from_def(sd: &hir::VariantData) -> StructType {
+    if !sd.is_struct() {
         // We are in a tuple-struct
-        match sd.fields.len() {
+        match sd.fields().count() {
             0 => Unit,
             1 => Newtype,
             _ => Tuple
index 264656835a384a649e7f1a157f94c70c1ab6df9a..1487c1668aac74a64211bb90074c8c02e6867885 100644 (file)
@@ -84,8 +84,8 @@ pub fn visit(&mut self, krate: &hir::Crate) {
         self.module.is_crate = true;
     }
 
-    pub fn visit_struct_def(&mut self, item: &hir::Item,
-                            name: ast::Name, sd: &hir::StructDef,
+    pub fn visit_variant_data(&mut self, item: &hir::Item,
+                            name: ast::Name, sd: &hir::VariantData,
                             generics: &hir::Generics) -> Struct {
         debug!("Visiting struct");
         let struct_type = struct_type_from_def(&*sd);
@@ -97,7 +97,7 @@ pub fn visit_struct_def(&mut self, item: &hir::Item,
             stab: self.stability(item.id),
             attrs: item.attrs.clone(),
             generics: generics.clone(),
-            fields: sd.fields.clone(),
+            fields: sd.fields().cloned().collect(),
             whence: item.span
         }
     }
@@ -111,9 +111,8 @@ pub fn visit_enum_def(&mut self, it: &hir::Item,
             variants: def.variants.iter().map(|v| Variant {
                 name: v.node.name,
                 attrs: v.node.attrs.clone(),
-                stab: self.stability(v.node.id),
-                id: v.node.id,
-                kind: v.node.kind.clone(),
+                stab: self.stability(v.node.data.id()),
+                def: v.node.data.clone(),
                 whence: v.span,
             }).collect(),
             vis: it.vis,
@@ -299,7 +298,7 @@ pub fn visit_item(&mut self, item: &hir::Item,
             hir::ItemEnum(ref ed, ref gen) =>
                 om.enums.push(self.visit_enum_def(item, name, ed, gen)),
             hir::ItemStruct(ref sd, ref gen) =>
-                om.structs.push(self.visit_struct_def(item, name, &**sd, gen)),
+                om.structs.push(self.visit_variant_data(item, name, &**sd, gen)),
             hir::ItemFn(ref fd, ref unsafety, constness, ref abi, ref gen, _) =>
                 om.fns.push(self.visit_fn(item, name, &**fd, unsafety,
                                           constness, abi, gen)),
index 4ad8fce8120aa2318db78c476b2aad8c3f46bf03..0b7c5b0d840227313ded8c74dce1679b0938080d 100644 (file)
@@ -207,7 +207,7 @@ fn test_resize_policy() {
 /// The hashes are all keyed by the thread-local random number generator
 /// on creation by default. This means that the ordering of the keys is
 /// randomized, but makes the tables more resistant to
-/// denial-of-service attacks (Hash DoS). This behaviour can be
+/// denial-of-service attacks (Hash DoS). This behavior can be
 /// overridden with one of the constructors.
 ///
 /// It is required that the keys implement the `Eq` and `Hash` traits, although
@@ -324,7 +324,7 @@ fn search_hashed<K, V, M, F>(table: M,
     F: FnMut(&K) -> bool,
 {
     // This is the only function where capacity can be zero. To avoid
-    // undefined behaviour when Bucket::new gets the raw bucket in this
+    // undefined behavior when Bucket::new gets the raw bucket in this
     // case, immediately return the appropriate search result.
     if table.capacity() == 0 {
         return TableRef(table);
index 3447d1683a800347fbc7fc5fa79d35583096cb1c..518c67bbe7f5858ff36d26fe3c7d409c5b8ee452 100644 (file)
@@ -416,7 +416,10 @@ fn description(&self) -> &str { self.inner.description() }
 /// Returns the value of the 'HOME' environment variable if it is
 /// set and not equal to the empty string. Otherwise, returns the value of the
 /// 'USERPROFILE' environment variable if it is set and not equal to the empty
-/// string.
+/// string. If both do not exist, [`GetUserProfileDirectory`][msdn] is used to
+/// return the appropriate path.
+///
+/// [msdn]: https://msdn.microsoft.com/en-us/library/windows/desktop/bb762280(v=vs.85).aspx
 ///
 /// # Examples
 ///
@@ -442,7 +445,11 @@ pub fn home_dir() -> Option<PathBuf> {
 ///
 /// On Windows, returns the value of, in order, the 'TMP', 'TEMP',
 /// 'USERPROFILE' environment variable  if any are set and not the empty
-/// string. Otherwise, tmpdir returns the path to the Windows directory.
+/// string. Otherwise, tmpdir returns the path to the Windows directory. This
+/// behavior is identical to that of [GetTempPath][msdn], which this function
+/// uses internally.
+///
+/// [msdn]: https://msdn.microsoft.com/en-us/library/windows/desktop/aa364992(v=vs.85).aspx
 ///
 /// ```
 /// use std::env;
index 16bf534563ecb8a9232d3c2711451e272bf784ef..0669f545a83325853b8f912af1b86d6f98d85cb9 100644 (file)
@@ -60,6 +60,7 @@ pub struct File {
 /// represents known metadata about a file such as its permissions, size,
 /// modification times, etc.
 #[stable(feature = "rust1", since = "1.0.0")]
+#[derive(Clone)]
 pub struct Metadata(fs_imp::FileAttr);
 
 /// Iterator over the entries in a directory.
index 773f9ac6a12a7bc4aa34f4141deda13c08c0071d..6f18aad623574d5db6a7c0caae262a86ed2ce69b 100644 (file)
@@ -17,9 +17,8 @@
 use result;
 use sys;
 
-/// A specialized [`Result`][result] type for I/O operations.
-///
-/// [result]: ../result/enum.Result.html
+/// A specialized [`Result`](../result/enum.Result.html) type for I/O
+/// operations.
 ///
 /// This type is broadly used across `std::io` for any operation which may
 /// produce an error.
index 79013000fe3b591c32ce1f65fd7632ddc191e5db..5b587dd921bb7e62e2213fbad35eeadab17cf33e 100644 (file)
@@ -238,7 +238,7 @@ fn bench_read_slice(b: &mut test::Bencher) {
 
         b.iter(|| {
             let mut rd = &buf[..];
-            for _ in (0 .. 8) {
+            for _ in 0..8 {
                 let _ = rd.read(&mut dst);
                 test::black_box(&dst);
             }
@@ -252,7 +252,7 @@ fn bench_write_slice(b: &mut test::Bencher) {
 
         b.iter(|| {
             let mut wr = &mut buf[..];
-            for _ in (0 .. 8) {
+            for _ in 0..8 {
                 let _ = wr.write_all(&src);
                 test::black_box(&wr);
             }
@@ -266,7 +266,7 @@ fn bench_read_vec(b: &mut test::Bencher) {
 
         b.iter(|| {
             let mut rd = &buf[..];
-            for _ in (0 .. 8) {
+            for _ in 0..8 {
                 let _ = rd.read(&mut dst);
                 test::black_box(&dst);
             }
@@ -280,7 +280,7 @@ fn bench_write_vec(b: &mut test::Bencher) {
 
         b.iter(|| {
             let mut wr = &mut buf[..];
-            for _ in (0 .. 8) {
+            for _ in 0..8 {
                 let _ = wr.write_all(&src);
                 test::black_box(&wr);
             }
index 9af766ad2af3595452a21801f8e9794ba255f1f3..a624b3521267af94106476098105af3f16a78ac6 100644 (file)
 //! not.
 //!
 //! Slices can only be handled through some kind of *pointer*, and as
-//! such come in many flavours such as:
+//! such come in many flavors such as:
 //!
 //! * `&[T]` - *shared slice*
 //! * `&mut [T]` - *mutable slice*
index 5c17ffb9c218af7a8e907fab73648f3006541cb3..c6499687304ecdf0dca93d59879eb44d78eb7532 100644 (file)
@@ -235,7 +235,7 @@ impl TcpListener {
     /// to this listener. The port allocated can be queried via the
     /// `socket_addr` function.
     ///
-    /// The address type can be any implementer of `ToSocketAddrs` trait. See
+    /// The address type can be any implementor of `ToSocketAddrs` trait. See
     /// its documentation for concrete examples.
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn bind<A: ToSocketAddrs>(addr: A) -> io::Result<TcpListener> {
index cad80c55140c793322e11099093c4b99e1dcdbb5..391ca16f6923aa7e46b7b1dfc73ff72a98d35c2b 100644 (file)
@@ -39,6 +39,7 @@ mod arch {
     pub type time_t = i32;
 
     #[repr(C)]
+    #[derive(Clone)]
     #[stable(feature = "raw_ext", since = "1.1.0")]
     pub struct stat {
         #[stable(feature = "raw_ext", since = "1.1.0")]
@@ -108,6 +109,7 @@ mod arch {
     pub type time_t = i64;
 
     #[repr(C)]
+    #[derive(Clone)]
     #[stable(feature = "raw_ext", since = "1.1.0")]
     pub struct stat {
         #[stable(feature = "raw_ext", since = "1.1.0")]
index 2427a4e409251914d7ed6762e55d1589ba1f0286..45e46b252a4abfc2cd2e386367685813edea72b5 100644 (file)
@@ -26,6 +26,7 @@
 #[stable(feature = "raw_ext", since = "1.1.0")] pub type time_t = i64;
 
 #[repr(C)]
+#[derive(Clone)]
 #[stable(feature = "raw_ext", since = "1.1.0")]
 pub struct stat {
     #[stable(feature = "raw_ext", since = "1.1.0")]
index 1c265fa62f19cb59ab36bb6c8bdd8a99987b6254..cb692b0662aad5e0bc63f5e47b251e98f55fa010 100644 (file)
@@ -26,6 +26,7 @@
 #[stable(feature = "raw_ext", since = "1.1.0")] pub type time_t = i64;
 
 #[repr(C)]
+#[derive(Clone)]
 #[stable(feature = "raw_ext", since = "1.1.0")]
 pub struct stat {
     #[stable(feature = "raw_ext", since = "1.1.0")]
index 761e6c96ab738a74a6b2cdd1a24afaf74afe3d31..2dc9a026153ac82301070349b74a0f2e351a9e3b 100644 (file)
@@ -33,6 +33,7 @@ mod arch {
     #[stable(feature = "raw_ext", since = "1.1.0")] pub type time_t = i32;
 
     #[repr(C)]
+    #[derive(Clone)]
     #[stable(feature = "raw_ext", since = "1.1.0")]
     pub struct stat {
         #[stable(feature = "raw_ext", since = "1.1.0")]
@@ -91,6 +92,7 @@ mod arch {
     #[stable(feature = "raw_ext", since = "1.1.0")] pub type time_t = i64;
 
     #[repr(C)]
+    #[derive(Clone)]
     #[stable(feature = "raw_ext", since = "1.1.0")]
     pub struct stat {
         #[stable(feature = "raw_ext", since = "1.1.0")]
index a9803f50b7b67b7e390fa1078de3d78512868be0..aeb3e993a72f4fd8e856978ade5a27f3ecc3d23c 100644 (file)
@@ -25,6 +25,7 @@
 #[stable(feature = "raw_ext", since = "1.1.0")] pub type time_t = c_long;
 
 #[repr(C)]
+#[derive(Clone)]
 #[stable(feature = "raw_ext", since = "1.1.0")]
 pub struct stat {
     #[stable(feature = "raw_ext", since = "1.1.0")]
index 3275ce07b48ab04d6073e3e3c31ff8268e664ec6..d7abdef6b038f936006d2c3f5e38501098bae3d3 100644 (file)
@@ -35,6 +35,7 @@ mod arch {
     #[stable(feature = "raw_ext", since = "1.1.0")] pub type time_t = i32;
 
     #[repr(C)]
+    #[derive(Clone)]
     #[stable(feature = "raw_ext", since = "1.1.0")]
     pub struct stat {
         #[stable(feature = "raw_ext", since = "1.1.0")]
@@ -95,6 +96,7 @@ mod arch {
     #[stable(feature = "raw_ext", since = "1.1.0")] pub type time_t = i32;
 
     #[repr(C)]
+    #[derive(Clone)]
     #[stable(feature = "raw_ext", since = "1.1.0")]
     pub struct stat {
         #[stable(feature = "raw_ext", since = "1.1.0")]
@@ -154,6 +156,7 @@ mod arch {
     #[stable(feature = "raw_ext", since = "1.1.0")] pub type time_t = i64;
 
     #[repr(C)]
+    #[derive(Clone)]
     #[stable(feature = "raw_ext", since = "1.1.0")]
     pub struct stat {
         #[stable(feature = "raw_ext", since = "1.1.0")]
@@ -211,6 +214,7 @@ mod arch {
     #[stable(feature = "raw_ext", since = "1.1.0")] pub type time_t = i64;
 
     #[repr(C)]
+    #[derive(Clone)]
     #[stable(feature = "raw_ext", since = "1.1.0")]
     pub struct stat {
         #[stable(feature = "raw_ext", since = "1.1.0")]
index dbc1b8c726bfe70b00e25f2f5535fca7d31a7b5e..4abd6f2d4dea3507946dd77b0d30beb7374442b9 100644 (file)
@@ -25,6 +25,7 @@
 #[stable(feature = "raw_ext", since = "1.1.0")] pub type time_t = c_long;
 
 #[repr(C)]
+#[derive(Clone)]
 #[stable(feature = "raw_ext", since = "1.1.0")]
 pub struct stat {
     #[stable(feature = "raw_ext", since = "1.1.0")]
index d811b94c847b3d6947746039c165190c9f4794da..82898437687b9bb233c95cd87f9ff455203a1bb3 100644 (file)
@@ -34,6 +34,7 @@ mod arch {
     #[stable(feature = "raw_ext", since = "1.1.0")] pub type time_t = i32;
 
     #[repr(C)]
+    #[derive(Clone)]
     #[stable(feature = "raw_ext", since = "1.1.0")]
     pub struct stat {
         #[stable(feature = "raw_ext", since = "1.1.0")]
@@ -94,6 +95,7 @@ mod arch {
     #[stable(feature = "raw_ext", since = "1.1.0")] pub type time_t = i32;
 
     #[repr(C)]
+    #[derive(Clone)]
     #[stable(feature = "raw_ext", since = "1.1.0")]
     pub struct stat {
         #[stable(feature = "raw_ext", since = "1.1.0")]
@@ -153,6 +155,7 @@ mod arch {
     #[stable(feature = "raw_ext", since = "1.1.0")] pub type time_t = i64;
 
     #[repr(C)]
+    #[derive(Clone)]
     #[stable(feature = "raw_ext", since = "1.1.0")]
     pub struct stat {
         #[stable(feature = "raw_ext", since = "1.1.0")]
@@ -210,6 +213,7 @@ mod arch {
     #[stable(feature = "raw_ext", since = "1.1.0")] pub type time_t = i64;
 
     #[repr(C)]
+    #[derive(Clone)]
     #[stable(feature = "raw_ext", since = "1.1.0")]
     pub struct stat {
         #[stable(feature = "raw_ext", since = "1.1.0")]
index 09adc1d05a60915c1f2c3fe2c7cb924d0c7a53a4..882d08c66065e7b631c92189eaa6669cb869df57 100644 (file)
@@ -26,6 +26,7 @@
 #[stable(feature = "raw_ext", since = "1.1.0")] pub type time_t = i64;
 
 #[repr(C)]
+#[derive(Clone)]
 #[stable(feature = "raw_ext", since = "1.1.0")]
 pub struct stat {
     #[stable(feature = "raw_ext", since = "1.1.0")]
index 79ca901ade7b50dd45263c271280affbb3714026..1cc0eedfcd050a6c6cf38aa7879b8014a797f6ef 100644 (file)
@@ -26,6 +26,7 @@
 #[stable(feature = "raw_ext", since = "1.1.0")] pub type time_t = i64;
 
 #[repr(C)]
+#[derive(Clone)]
 #[stable(feature = "raw_ext", since = "1.1.0")]
 pub struct stat {
     #[stable(feature = "raw_ext", since = "1.1.0")]
index f1c626cc16576efb4a17f19f99ea5d182d08cd26..08227cfb35322f00ead40d813010b853168bb206 100644 (file)
@@ -84,7 +84,7 @@
 //!   }.
 //!   Generic conversions, used by savvy API authors to create
 //!   overloaded methods.
-//! * `std::default::`[`Default`](../default/trait.Default).
+//! * `std::default::`[`Default`](../default/trait.Default.html).
 //!   Types that have default values.
 //! * `std::iter::`{
 //!     [`Iterator`](../iter/trait.Iterator.html),
index 0be751be9504e6b50599f5d8c0459e09112d326a..4e80fb2ceb09ed4ae4b1caac7cd88c0ddb2020ff 100644 (file)
@@ -75,7 +75,7 @@ impl IntoInner<imp::Process> for Child {
     fn into_inner(self) -> imp::Process { self.handle }
 }
 
-/// A handle to a child procesess's stdin
+/// A handle to a child process's stdin
 #[stable(feature = "process", since = "1.0.0")]
 pub struct ChildStdin {
     inner: AnonPipe
index f1d264b38a0c7b18245cb46af66cfc66b351e6a5..aabc06b1986f5d1de6d822030f9f3d8c55528863 100644 (file)
@@ -13,7 +13,9 @@
 use cell::UnsafeCell;
 use fmt;
 use marker;
+use mem;
 use ops::{Deref, DerefMut};
+use ptr;
 use sys_common::mutex as sys;
 use sys_common::poison::{self, TryLockError, TryLockResult, LockResult};
 
@@ -243,6 +245,50 @@ pub fn try_lock(&self) -> TryLockResult<MutexGuard<T>> {
     pub fn is_poisoned(&self) -> bool {
         self.inner.poison.get()
     }
+
+    /// Consumes this mutex, returning the underlying data.
+    ///
+    /// # Failure
+    ///
+    /// If another user of this mutex panicked while holding the mutex, then
+    /// this call will return an error instead.
+    #[unstable(feature = "mutex_into_inner", reason = "recently added", issue = "28968")]
+    pub fn into_inner(self) -> LockResult<T> where T: Sized {
+        // We know statically that there are no outstanding references to
+        // `self` so there's no need to lock the inner StaticMutex.
+        //
+        // To get the inner value, we'd like to call `data.into_inner()`,
+        // but because `Mutex` impl-s `Drop`, we can't move out of it, so
+        // we'll have to destructure it manually instead.
+        unsafe {
+            // Like `let Mutex { inner, data } = self`.
+            let (inner, data) = {
+                let Mutex { ref inner, ref data } = self;
+                (ptr::read(inner), ptr::read(data))
+            };
+            mem::forget(self);
+            inner.lock.destroy();  // Keep in sync with the `Drop` impl.
+
+            poison::map_result(inner.poison.borrow(), |_| data.into_inner())
+        }
+    }
+
+    /// Returns a mutable reference to the underlying data.
+    ///
+    /// Since this call borrows the `Mutex` mutably, no actual locking needs to
+    /// take place---the mutable borrow statically guarantees no locks exist.
+    ///
+    /// # Failure
+    ///
+    /// If another user of this mutex panicked while holding the mutex, then
+    /// this call will return an error instead.
+    #[unstable(feature = "mutex_get_mut", reason = "recently added", issue = "28968")]
+    pub fn get_mut(&mut self) -> LockResult<&mut T> {
+        // We know statically that there are no other references to `self`, so
+        // there's no need to lock the inner StaticMutex.
+        let data = unsafe { &mut *self.data.get() };
+        poison::map_result(self.inner.poison.borrow(), |_| data )
+    }
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
@@ -251,6 +297,8 @@ fn drop(&mut self) {
         // This is actually safe b/c we know that there is no further usage of
         // this mutex (it's up to the user to arrange for a mutex to get
         // dropped, that's not our job)
+        //
+        // IMPORTANT: This code must be kept in sync with `Mutex::into_inner`.
         unsafe { self.inner.lock.destroy() }
     }
 }
@@ -371,10 +419,14 @@ mod tests {
 
     use sync::mpsc::channel;
     use sync::{Arc, Mutex, StaticMutex, Condvar};
+    use sync::atomic::{AtomicUsize, Ordering};
     use thread;
 
     struct Packet<T>(Arc<(Mutex<T>, Condvar)>);
 
+    #[derive(Eq, PartialEq, Debug)]
+    struct NonCopy(i32);
+
     unsafe impl<T: Send> Send for Packet<T> {}
     unsafe impl<T> Sync for Packet<T> {}
 
@@ -435,6 +487,69 @@ fn try_lock() {
         *m.try_lock().unwrap() = ();
     }
 
+    #[test]
+    fn test_into_inner() {
+        let m = Mutex::new(NonCopy(10));
+        assert_eq!(m.into_inner().unwrap(), NonCopy(10));
+    }
+
+    #[test]
+    fn test_into_inner_drop() {
+        struct Foo(Arc<AtomicUsize>);
+        impl Drop for Foo {
+            fn drop(&mut self) {
+                self.0.fetch_add(1, Ordering::SeqCst);
+            }
+        }
+        let num_drops = Arc::new(AtomicUsize::new(0));
+        let m = Mutex::new(Foo(num_drops.clone()));
+        assert_eq!(num_drops.load(Ordering::SeqCst), 0);
+        {
+            let _inner = m.into_inner().unwrap();
+            assert_eq!(num_drops.load(Ordering::SeqCst), 0);
+        }
+        assert_eq!(num_drops.load(Ordering::SeqCst), 1);
+    }
+
+    #[test]
+    fn test_into_inner_poison() {
+        let m = Arc::new(Mutex::new(NonCopy(10)));
+        let m2 = m.clone();
+        let _ = thread::spawn(move || {
+            let _lock = m2.lock().unwrap();
+            panic!("test panic in inner thread to poison mutex");
+        }).join();
+
+        assert!(m.is_poisoned());
+        match Arc::try_unwrap(m).unwrap().into_inner() {
+            Err(e) => assert_eq!(e.into_inner(), NonCopy(10)),
+            Ok(x) => panic!("into_inner of poisoned Mutex is Ok: {:?}", x),
+        }
+    }
+
+    #[test]
+    fn test_get_mut() {
+        let mut m = Mutex::new(NonCopy(10));
+        *m.get_mut().unwrap() = NonCopy(20);
+        assert_eq!(m.into_inner().unwrap(), NonCopy(20));
+    }
+
+    #[test]
+    fn test_get_mut_poison() {
+        let m = Arc::new(Mutex::new(NonCopy(10)));
+        let m2 = m.clone();
+        let _ = thread::spawn(move || {
+            let _lock = m2.lock().unwrap();
+            panic!("test panic in inner thread to poison mutex");
+        }).join();
+
+        assert!(m.is_poisoned());
+        match Arc::try_unwrap(m).unwrap().get_mut() {
+            Err(e) => assert_eq!(*e.into_inner(), NonCopy(10)),
+            Ok(x) => panic!("get_mut of poisoned Mutex is Ok: {:?}", x),
+        }
+    }
+
     #[test]
     fn test_mutex_arc_condvar() {
         let packet = Packet(Arc::new((Mutex::new(false), Condvar::new())));
index 04ad47082464ec133e8f8e11ed8f180118db08e1..9278481f2d62b194f715329b0b7164810a98e4f5 100644 (file)
@@ -13,7 +13,9 @@
 use cell::UnsafeCell;
 use fmt;
 use marker;
+use mem;
 use ops::{Deref, DerefMut};
+use ptr;
 use sys_common::poison::{self, LockResult, TryLockError, TryLockResult};
 use sys_common::rwlock as sys;
 
@@ -260,11 +262,60 @@ pub fn try_write(&self) -> TryLockResult<RwLockWriteGuard<T>> {
     pub fn is_poisoned(&self) -> bool {
         self.inner.poison.get()
     }
+
+    /// Consumes this `RwLock`, returning the underlying data.
+    ///
+    /// # Failure
+    ///
+    /// This function will return an error if the RwLock is poisoned. An RwLock
+    /// is poisoned whenever a writer panics while holding an exclusive lock. An
+    /// error will only be returned if the lock would have otherwise been
+    /// acquired.
+    #[unstable(feature = "rwlock_into_inner", reason = "recently added", issue = "28968")]
+    pub fn into_inner(self) -> LockResult<T> where T: Sized {
+        // We know statically that there are no outstanding references to
+        // `self` so there's no need to lock the inner StaticRwLock.
+        //
+        // To get the inner value, we'd like to call `data.into_inner()`,
+        // but because `RwLock` impl-s `Drop`, we can't move out of it, so
+        // we'll have to destructure it manually instead.
+        unsafe {
+            // Like `let RwLock { inner, data } = self`.
+            let (inner, data) = {
+                let RwLock { ref inner, ref data } = self;
+                (ptr::read(inner), ptr::read(data))
+            };
+            mem::forget(self);
+            inner.lock.destroy();  // Keep in sync with the `Drop` impl.
+
+            poison::map_result(inner.poison.borrow(), |_| data.into_inner())
+        }
+    }
+
+    /// Returns a mutable reference to the underlying data.
+    ///
+    /// Since this call borrows the `RwLock` mutably, no actual locking needs to
+    /// take place---the mutable borrow statically guarantees no locks exist.
+    ///
+    /// # Failure
+    ///
+    /// This function will return an error if the RwLock is poisoned. An RwLock
+    /// is poisoned whenever a writer panics while holding an exclusive lock. An
+    /// error will only be returned if the lock would have otherwise been
+    /// acquired.
+    #[unstable(feature = "rwlock_get_mut", reason = "recently added", issue = "28968")]
+    pub fn get_mut(&mut self) -> LockResult<&mut T> {
+        // We know statically that there are no other references to `self`, so
+        // there's no need to lock the inner StaticRwLock.
+        let data = unsafe { &mut *self.data.get() };
+        poison::map_result(self.inner.poison.borrow(), |_| data )
+    }
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<T: ?Sized> Drop for RwLock<T> {
     fn drop(&mut self) {
+        // IMPORTANT: This code needs to be kept in sync with `RwLock::into_inner`.
         unsafe { self.inner.lock.destroy() }
     }
 }
@@ -426,6 +477,10 @@ mod tests {
     use sync::mpsc::channel;
     use thread;
     use sync::{Arc, RwLock, StaticRwLock, TryLockError};
+    use sync::atomic::{AtomicUsize, Ordering};
+
+    #[derive(Eq, PartialEq, Debug)]
+    struct NonCopy(i32);
 
     #[test]
     fn smoke() {
@@ -606,4 +661,67 @@ fn test_rwlock_try_write() {
 
         drop(read_guard);
     }
+
+    #[test]
+    fn test_into_inner() {
+        let m = RwLock::new(NonCopy(10));
+        assert_eq!(m.into_inner().unwrap(), NonCopy(10));
+    }
+
+    #[test]
+    fn test_into_inner_drop() {
+        struct Foo(Arc<AtomicUsize>);
+        impl Drop for Foo {
+            fn drop(&mut self) {
+                self.0.fetch_add(1, Ordering::SeqCst);
+            }
+        }
+        let num_drops = Arc::new(AtomicUsize::new(0));
+        let m = RwLock::new(Foo(num_drops.clone()));
+        assert_eq!(num_drops.load(Ordering::SeqCst), 0);
+        {
+            let _inner = m.into_inner().unwrap();
+            assert_eq!(num_drops.load(Ordering::SeqCst), 0);
+        }
+        assert_eq!(num_drops.load(Ordering::SeqCst), 1);
+    }
+
+    #[test]
+    fn test_into_inner_poison() {
+        let m = Arc::new(RwLock::new(NonCopy(10)));
+        let m2 = m.clone();
+        let _ = thread::spawn(move || {
+            let _lock = m2.write().unwrap();
+            panic!("test panic in inner thread to poison RwLock");
+        }).join();
+
+        assert!(m.is_poisoned());
+        match Arc::try_unwrap(m).unwrap().into_inner() {
+            Err(e) => assert_eq!(e.into_inner(), NonCopy(10)),
+            Ok(x) => panic!("into_inner of poisoned RwLock is Ok: {:?}", x),
+        }
+    }
+
+    #[test]
+    fn test_get_mut() {
+        let mut m = RwLock::new(NonCopy(10));
+        *m.get_mut().unwrap() = NonCopy(20);
+        assert_eq!(m.into_inner().unwrap(), NonCopy(20));
+    }
+
+    #[test]
+    fn test_get_mut_poison() {
+        let m = Arc::new(RwLock::new(NonCopy(10)));
+        let m2 = m.clone();
+        let _ = thread::spawn(move || {
+            let _lock = m2.write().unwrap();
+            panic!("test panic in inner thread to poison RwLock");
+        }).join();
+
+        assert!(m.is_poisoned());
+        match Arc::try_unwrap(m).unwrap().get_mut() {
+            Err(e) => assert_eq!(*e.into_inner(), NonCopy(10)),
+            Ok(x) => panic!("get_mut of poisoned RwLock is Ok: {:?}", x),
+        }
+    }
 }
index 0eebe5af9197dc07601845769e924ef1071f60e4..d0c027ddad65fb01f65fdd6b6fd4583a1c0a8563 100644 (file)
@@ -27,6 +27,7 @@
 
 pub struct File(FileDesc);
 
+#[derive(Clone)]
 pub struct FileAttr {
     stat: raw::stat,
 }
index c0e75368f745970906ad5673328c10ec794390e2..59b385b94810bedefe5d3e3b29c81488f116008e 100644 (file)
@@ -187,10 +187,10 @@ pub fn current_exe() -> io::Result<PathBuf> {
     unsafe {
         use libc::funcs::bsd44::*;
         use libc::consts::os::extra::*;
-        let mut mib = vec![CTL_KERN as c_int,
-                           KERN_PROC as c_int,
-                           KERN_PROC_PATHNAME as c_int,
-                           -1 as c_int];
+        let mut mib = [CTL_KERN as c_int,
+                       KERN_PROC as c_int,
+                       KERN_PROC_PATHNAME as c_int,
+                       -1 as c_int];
         let mut sz: libc::size_t = 0;
         let err = sysctl(mib.as_mut_ptr(), mib.len() as ::libc::c_uint,
                          ptr::null_mut(), &mut sz, ptr::null_mut(),
@@ -343,7 +343,7 @@ pub fn args() -> Args {
         let args = objc_msgSend(info, arguments_sel);
 
         let cnt: usize = mem::transmute(objc_msgSend(args, count_sel));
-        for i in (0..cnt) {
+        for i in 0..cnt {
             let tmp = objc_msgSend(args, object_at_sel, i);
             let utf_c_str: *const libc::c_char =
                 mem::transmute(objc_msgSend(tmp, utf8_sel));
index 30c7e5a52b7c776e688e183d5ec21a88014e4d52..bac5b47eb1a6228e660f3511a34e61f3c49fbd01 100644 (file)
@@ -182,6 +182,7 @@ pub struct CONSOLE_SCREEN_BUFFER_INFO {
 pub type PCONSOLE_SCREEN_BUFFER_INFO = *mut CONSOLE_SCREEN_BUFFER_INFO;
 
 #[repr(C)]
+#[derive(Clone)]
 pub struct WIN32_FILE_ATTRIBUTE_DATA {
     pub dwFileAttributes: libc::DWORD,
     pub ftCreationTime: libc::FILETIME,
index 721e259823ad6c146e2cfbd664a37a29e26fe61e..fb2456564eb8d4fbb7b6d81d1428c98f0eda4029 100644 (file)
@@ -27,6 +27,7 @@
 
 pub struct File { handle: Handle }
 
+#[derive(Clone)]
 pub struct FileAttr {
     data: c::WIN32_FILE_ATTRIBUTE_DATA,
     reparse_tag: libc::DWORD,
index 34b99ab8cce1c062a2e604554f8f72e0ac6d6c35..a45f5c9048c652ac2b7f09dbd80d6b52d355e719 100644 (file)
@@ -44,7 +44,6 @@
 pub use self::UintTy::*;
 pub use self::UnOp::*;
 pub use self::UnsafeSource::*;
-pub use self::VariantKind::*;
 pub use self::ViewPath_::*;
 pub use self::Visibility::*;
 pub use self::PathParameters::*;
@@ -66,6 +65,7 @@
 use std::rc::Rc;
 use std::borrow::Cow;
 use std::hash::{Hash, Hasher};
+use std::{iter, option, slice};
 use serialize::{Encodable, Decodable, Encoder, Decoder};
 
 /// A name is a part of an identifier, representing a string or gensym. It's
@@ -765,8 +765,6 @@ pub struct Field {
 pub enum BlockCheckMode {
     DefaultBlock,
     UnsafeBlock(UnsafeSource),
-    PushUnsafeBlock(UnsafeSource),
-    PopUnsafeBlock(UnsafeSource),
 }
 
 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
@@ -1571,20 +1569,6 @@ pub struct ForeignMod {
     pub items: Vec<P<ForeignItem>>,
 }
 
-#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
-pub struct VariantArg {
-    pub ty: P<Ty>,
-    pub id: NodeId,
-}
-
-#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
-pub enum VariantKind {
-    /// Tuple variant, e.g. `Foo(A, B)`
-    TupleVariantKind(Vec<VariantArg>),
-    /// Struct variant, e.g. `Foo {x: A, y: B}`
-    StructVariantKind(P<StructDef>),
-}
-
 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
 pub struct EnumDef {
     pub variants: Vec<P<Variant>>,
@@ -1594,8 +1578,7 @@ pub struct EnumDef {
 pub struct Variant_ {
     pub name: Ident,
     pub attrs: Vec<Attribute>,
-    pub kind: VariantKind,
-    pub id: NodeId,
+    pub data: P<VariantData>,
     /// Explicit discriminant, eg `Foo = 1`
     pub disr_expr: Option<P<Expr>>,
 }
@@ -1756,13 +1739,50 @@ pub fn is_unnamed(&self) -> bool {
     }
 }
 
+/// Fields and Ids of enum variants and structs
+///
+/// For enum variants: `NodeId` represents both an Id of the variant itself (relevant for all
+/// variant kinds) and an Id of the variant's constructor (not relevant for `Struct`-variants).
+/// One shared Id can be successfully used for these two purposes.
+/// Id of the whole enum lives in `Item`.
+///
+/// For structs: `NodeId` represents an Id of the structure's constructor, so it is not actually
+/// used for `Struct`-structs (but still presents). Structures don't have an analogue of "Id of
+/// the variant itself" from enum variants.
+/// Id of the whole struct lives in `Item`.
 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
-pub struct StructDef {
-    /// Fields, not including ctor
-    pub fields: Vec<StructField>,
-    /// ID of the constructor. This is only used for tuple- or enum-like
-    /// structs.
-    pub ctor_id: Option<NodeId>,
+pub enum VariantData {
+    Struct(Vec<StructField>, NodeId),
+    Tuple(Vec<StructField>, NodeId),
+    Unit(NodeId),
+}
+
+pub type FieldIter<'a> = iter::FlatMap<option::IntoIter<&'a Vec<StructField>>,
+                                       slice::Iter<'a, StructField>,
+                                       fn(&Vec<StructField>) -> slice::Iter<StructField>>;
+
+impl VariantData {
+    pub fn fields(&self) -> FieldIter {
+        fn vec_iter<T>(v: &Vec<T>) -> slice::Iter<T> { v.iter() }
+        match *self {
+            VariantData::Struct(ref fields, _) | VariantData::Tuple(ref fields, _) => Some(fields),
+            _ => None,
+        }.into_iter().flat_map(vec_iter)
+    }
+    pub fn id(&self) -> NodeId {
+        match *self {
+            VariantData::Struct(_, id) | VariantData::Tuple(_, id) | VariantData::Unit(id) => id
+        }
+    }
+    pub fn is_struct(&self) -> bool {
+        if let VariantData::Struct(..) = *self { true } else { false }
+    }
+    pub fn is_tuple(&self) -> bool {
+        if let VariantData::Tuple(..) = *self { true } else { false }
+    }
+    pub fn is_unit(&self) -> bool {
+        if let VariantData::Unit(..) = *self { true } else { false }
+    }
 }
 
 /*
@@ -1806,7 +1826,7 @@ pub enum Item_ {
     /// An enum definition, e.g. `enum Foo<A, B> {C<A>, D<B>}`
     ItemEnum(EnumDef, Generics),
     /// A struct definition, e.g. `struct Foo<A> {x: A}`
-    ItemStruct(P<StructDef>, Generics),
+    ItemStruct(P<VariantData>, Generics),
     /// Represents a Trait Declaration
     ItemTrait(Unsafety,
               Generics,
index 905a83b050ed73fa8dde0892efee4f791532a2ea..8c3360512d512f632880670a7929f42bfabae4b4 100644 (file)
@@ -360,11 +360,6 @@ fn visit_item(&mut self, item: &Item) {
                     }
                 }
             }
-            ItemEnum(ref enum_definition, _) => {
-                for variant in &enum_definition.variants {
-                    self.operation.visit_id(variant.node.id)
-                }
-            }
             _ => {}
         }
 
@@ -457,13 +452,13 @@ fn visit_struct_field(&mut self, struct_field: &StructField) {
         visit::walk_struct_field(self, struct_field)
     }
 
-    fn visit_struct_def(&mut self,
-                        struct_def: &StructDef,
+    fn visit_variant_data(&mut self,
+                        struct_def: &VariantData,
                         _: ast::Ident,
                         _: &ast::Generics,
-                        id: NodeId) {
-        self.operation.visit_id(id);
-        struct_def.ctor_id.map(|ctor_id| self.operation.visit_id(ctor_id));
+                        _: NodeId,
+                        _: Span) {
+        self.operation.visit_id(struct_def.id());
         visit::walk_struct_def(self, struct_def);
     }
 
@@ -529,12 +524,6 @@ pub fn compute_id_range_for_fn_body(fk: FnKind,
     id_visitor.operation.result
 }
 
-/// Returns true if the given struct def is tuple-like; i.e. that its fields
-/// are unnamed.
-pub fn struct_def_is_tuple_like(struct_def: &ast::StructDef) -> bool {
-    struct_def.ctor_id.is_some()
-}
-
 /// Returns true if the given pattern consists solely of an identifier
 /// and false otherwise.
 pub fn pat_is_ident(pat: P<ast::Pat>) -> bool {
index 2d266be3242a57c3743157f413f0fe17a867148d..0ca110c5b1ed2cf1a490e7f3f9f782b91a8a5c53 100644 (file)
@@ -140,19 +140,13 @@ fn fold_item_underscore<F>(cx: &mut Context<F>, item: ast::Item_) -> ast::Item_
                 if !(cx.in_cfg)(&v.node.attrs) {
                     None
                 } else {
-                    Some(v.map(|Spanned {node: ast::Variant_ {id, name, attrs, kind,
+                    Some(v.map(|Spanned {node: ast::Variant_ {name, attrs, data,
                                                               disr_expr}, span}| {
                         Spanned {
                             node: ast::Variant_ {
-                                id: id,
                                 name: name,
                                 attrs: attrs,
-                                kind: match kind {
-                                    ast::TupleVariantKind(..) => kind,
-                                    ast::StructVariantKind(def) => {
-                                        ast::StructVariantKind(fold_struct(cx, def))
-                                    }
-                                },
+                                data: fold_struct(cx, data),
                                 disr_expr: disr_expr,
                             },
                             span: span
@@ -170,15 +164,22 @@ fn fold_item_underscore<F>(cx: &mut Context<F>, item: ast::Item_) -> ast::Item_
     fold::noop_fold_item_underscore(item, cx)
 }
 
-fn fold_struct<F>(cx: &mut Context<F>, def: P<ast::StructDef>) -> P<ast::StructDef> where
+fn fold_struct<F>(cx: &mut Context<F>, def: P<ast::VariantData>) -> P<ast::VariantData> where
     F: FnMut(&[ast::Attribute]) -> bool
 {
-    def.map(|ast::StructDef { fields, ctor_id }| {
-        ast::StructDef {
-            fields: fields.into_iter().filter(|m| {
-                (cx.in_cfg)(&m.node.attrs)
-            }).collect(),
-            ctor_id: ctor_id,
+    def.map(|vdata| {
+        match vdata {
+            ast::VariantData::Struct(fields, id) => {
+                ast::VariantData::Struct(fields.into_iter().filter(|m| {
+                    (cx.in_cfg)(&m.node.attrs)
+                }).collect(), id)
+            }
+            ast::VariantData::Tuple(fields, id) => {
+                ast::VariantData::Tuple(fields.into_iter().filter(|m| {
+                    (cx.in_cfg)(&m.node.attrs)
+                }).collect(), id)
+            }
+            ast::VariantData::Unit(id) => ast::VariantData::Unit(id)
         }
     })
 }
index 6196062b08af15e2e02963d8150b5c2d37c14ee3..ef26c1deae7c9e7be5420235691b30ca66822550 100644 (file)
@@ -544,12 +544,6 @@ fn builtin_normal_expander(f: MacroExpanderFn) -> SyntaxExtension {
     syntax_expanders.insert(intern("cfg"),
                             builtin_normal_expander(
                                     ext::cfg::expand_cfg));
-    syntax_expanders.insert(intern("push_unsafe"),
-                            builtin_normal_expander(
-                                ext::pushpop_safe::expand_push_unsafe));
-    syntax_expanders.insert(intern("pop_unsafe"),
-                            builtin_normal_expander(
-                                ext::pushpop_safe::expand_pop_unsafe));
     syntax_expanders.insert(intern("trace_macros"),
                             builtin_normal_expander(
                                     ext::trace_macros::expand_trace_macros));
index efea85f916252e3ba7679e3d0bb78d4e65b90ad0..9b06fbd0a0b858ef73b6615bbed3849be0b7ee4f 100644 (file)
@@ -247,9 +247,9 @@ fn item_enum_poly(&self,
     fn item_struct_poly(&self,
                         span: Span,
                         name: Ident,
-                        struct_def: ast::StructDef,
+                        struct_def: ast::VariantData,
                         generics: Generics) -> P<ast::Item>;
-    fn item_struct(&self, span: Span, name: Ident, struct_def: ast::StructDef) -> P<ast::Item>;
+    fn item_struct(&self, span: Span, name: Ident, struct_def: ast::VariantData) -> P<ast::Item>;
 
     fn item_mod(&self, span: Span, inner_span: Span,
                 name: Ident, attrs: Vec<ast::Attribute>,
@@ -993,16 +993,26 @@ fn item_fn(&self,
     }
 
     fn variant(&self, span: Span, name: Ident, tys: Vec<P<ast::Ty>> ) -> ast::Variant {
-        let args = tys.into_iter().map(|ty| {
-            ast::VariantArg { ty: ty, id: ast::DUMMY_NODE_ID }
+        let fields: Vec<_> = tys.into_iter().map(|ty| {
+            Spanned { span: ty.span, node: ast::StructField_ {
+                ty: ty,
+                kind: ast::UnnamedField(ast::Inherited),
+                attrs: Vec::new(),
+                id: ast::DUMMY_NODE_ID,
+            }}
         }).collect();
 
+        let vdata = if fields.is_empty() {
+            ast::VariantData::Unit(ast::DUMMY_NODE_ID)
+        } else {
+            ast::VariantData::Tuple(fields, ast::DUMMY_NODE_ID)
+        };
+
         respan(span,
                ast::Variant_ {
                    name: name,
                    attrs: Vec::new(),
-                   kind: ast::TupleVariantKind(args),
-                   id: ast::DUMMY_NODE_ID,
+                   data: P(vdata),
                    disr_expr: None,
                })
     }
@@ -1020,7 +1030,7 @@ fn item_enum(&self, span: Span, name: Ident,
     }
 
     fn item_struct(&self, span: Span, name: Ident,
-                   struct_def: ast::StructDef) -> P<ast::Item> {
+                   struct_def: ast::VariantData) -> P<ast::Item> {
         self.item_struct_poly(
             span,
             name,
@@ -1030,7 +1040,7 @@ fn item_struct(&self, span: Span, name: Ident,
     }
 
     fn item_struct_poly(&self, span: Span, name: Ident,
-        struct_def: ast::StructDef, generics: Generics) -> P<ast::Item> {
+        struct_def: ast::VariantData, generics: Generics) -> P<ast::Item> {
         self.item(span, name, Vec::new(), ast::ItemStruct(P(struct_def), generics))
     }
 
index 9fc2745cf929a568b1db266ecebad403932796e2..2a5c4993112a992e54edaafb8c94b6e7f5d2d1a7 100644 (file)
 //! A static method on the types above would result in,
 //!
 //! ```{.text}
-//! StaticStruct(<ast::StructDef of A>, Named(vec![(<ident of x>, <span of x>)]))
+//! StaticStruct(<ast::VariantData of A>, Named(vec![(<ident of x>, <span of x>)]))
 //!
-//! StaticStruct(<ast::StructDef of B>, Unnamed(vec![<span of x>]))
+//! StaticStruct(<ast::VariantData of B>, Unnamed(vec![<span of x>]))
 //!
 //! StaticEnum(<ast::EnumDef of C>,
 //!            vec![(<ident of C0>, <span of C0>, Unnamed(vec![<span of i32>])),
 use abi::Abi;
 use abi;
 use ast;
-use ast::{EnumDef, Expr, Ident, Generics, StructDef};
+use ast::{EnumDef, Expr, Ident, Generics, VariantData};
 use ast_util;
 use attr;
 use attr::AttrMetaMethods;
@@ -317,7 +317,7 @@ pub enum SubstructureFields<'a> {
     EnumNonMatchingCollapsed(Vec<Ident>, &'a [P<ast::Variant>], &'a [Ident]),
 
     /// A static method where `Self` is a struct.
-    StaticStruct(&'a ast::StructDef, StaticFields),
+    StaticStruct(&'a ast::VariantData, StaticFields),
     /// A static method where `Self` is an enum.
     StaticEnum(&'a ast::EnumDef, Vec<(Ident, Span, StaticFields)>),
 }
@@ -649,10 +649,10 @@ fn create_derived_impl(&self,
 
     fn expand_struct_def(&self,
                          cx: &mut ExtCtxt,
-                         struct_def: &'a StructDef,
+                         struct_def: &'a VariantData,
                          type_ident: Ident,
                          generics: &Generics) -> P<ast::Item> {
-        let field_tys: Vec<P<ast::Ty>> = struct_def.fields.iter()
+        let field_tys: Vec<P<ast::Ty>> = struct_def.fields()
             .map(|field| field.node.ty.clone())
             .collect();
 
@@ -700,16 +700,8 @@ fn expand_enum_def(&self,
         let mut field_tys = Vec::new();
 
         for variant in &enum_def.variants {
-            match variant.node.kind {
-                ast::VariantKind::TupleVariantKind(ref args) => {
-                    field_tys.extend(args.iter()
-                        .map(|arg| arg.ty.clone()));
-                }
-                ast::VariantKind::StructVariantKind(ref args) => {
-                    field_tys.extend(args.fields.iter()
-                        .map(|field| field.node.ty.clone()));
-                }
-            }
+            field_tys.extend(variant.node.data.fields()
+                .map(|field| field.node.ty.clone()));
         }
 
         let methods = self.methods.iter().map(|method_def| {
@@ -935,7 +927,7 @@ fn create_method(&self,
     fn expand_struct_method_body<'b>(&self,
                                  cx: &mut ExtCtxt,
                                  trait_: &TraitDef<'b>,
-                                 struct_def: &'b StructDef,
+                                 struct_def: &'b VariantData,
                                  type_ident: Ident,
                                  self_args: &[P<Expr>],
                                  nonself_args: &[P<Expr>])
@@ -1004,7 +996,7 @@ fn expand_struct_method_body<'b>(&self,
     fn expand_static_struct_method_body(&self,
                                         cx: &mut ExtCtxt,
                                         trait_: &TraitDef,
-                                        struct_def: &StructDef,
+                                        struct_def: &VariantData,
                                         type_ident: Ident,
                                         self_args: &[P<Expr>],
                                         nonself_args: &[P<Expr>])
@@ -1413,14 +1405,7 @@ fn expand_static_enum_method_body(&self,
         -> P<Expr> {
         let summary = enum_def.variants.iter().map(|v| {
             let ident = v.node.name;
-            let summary = match v.node.kind {
-                ast::TupleVariantKind(ref args) => {
-                    Unnamed(args.iter().map(|va| trait_.set_expn_info(cx, va.ty.span)).collect())
-                }
-                ast::StructVariantKind(ref struct_def) => {
-                    trait_.summarise_struct(cx, &**struct_def)
-                }
-            };
+            let summary = trait_.summarise_struct(cx, &v.node.data);
             (ident, v.span, summary)
         }).collect();
         self.call_substructure_method(cx, trait_, type_ident,
@@ -1456,10 +1441,10 @@ fn set_expn_info(&self,
 
     fn summarise_struct(&self,
                         cx: &mut ExtCtxt,
-                        struct_def: &StructDef) -> StaticFields {
+                        struct_def: &VariantData) -> StaticFields {
         let mut named_idents = Vec::new();
         let mut just_spans = Vec::new();
-        for field in struct_def.fields.iter(){
+        for field in struct_def.fields(){
             let sp = self.set_expn_info(cx, field.span);
             match field.node.kind {
                 ast::NamedField(ident, _) => named_idents.push((ident, sp)),
@@ -1492,13 +1477,13 @@ fn create_subpatterns(&self,
     fn create_struct_pattern(&self,
                              cx: &mut ExtCtxt,
                              struct_path: ast::Path,
-                             struct_def: &'a StructDef,
+                             struct_def: &'a VariantData,
                              prefix: &str,
                              mutbl: ast::Mutability)
                              -> (P<ast::Pat>, Vec<(Span, Option<Ident>,
                                                    P<Expr>,
                                                    &'a [ast::Attribute])>) {
-        if struct_def.fields.is_empty() {
+        if struct_def.fields().count() == 0 {
             return (cx.pat_enum(self.span, struct_path, vec![]), vec![]);
         }
 
@@ -1506,7 +1491,7 @@ fn create_struct_pattern(&self,
         let mut ident_expr = Vec::new();
         let mut struct_type = Unknown;
 
-        for (i, struct_field) in struct_def.fields.iter().enumerate() {
+        for (i, struct_field) in struct_def.fields().enumerate() {
             let sp = self.set_expn_info(cx, struct_field.span);
             let opt_id = match struct_field.node.kind {
                 ast::NamedField(ident, _) if (struct_type == Unknown ||
@@ -1560,34 +1545,7 @@ fn create_enum_variant_pattern(&self,
         -> (P<ast::Pat>, Vec<(Span, Option<Ident>, P<Expr>, &'a [ast::Attribute])>) {
         let variant_ident = variant.node.name;
         let variant_path = cx.path(variant.span, vec![enum_ident, variant_ident]);
-        match variant.node.kind {
-            ast::TupleVariantKind(ref variant_args) => {
-                if variant_args.is_empty() {
-                    return (cx.pat_enum(variant.span, variant_path, vec![]), vec![]);
-                }
-
-                let mut paths = Vec::new();
-                let mut ident_expr: Vec<(_, _, _, &'a [ast::Attribute])> = Vec::new();
-                for (i, va) in variant_args.iter().enumerate() {
-                    let sp = self.set_expn_info(cx, va.ty.span);
-                    let ident = cx.ident_of(&format!("{}_{}", prefix, i));
-                    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, &[]));
-                }
-
-                let subpats = self.create_subpatterns(cx, paths, mutbl);
-
-                (cx.pat_enum(variant.span, variant_path, subpats),
-                 ident_expr)
-            }
-            ast::StructVariantKind(ref struct_def) => {
-                self.create_struct_pattern(cx, variant_path, &**struct_def,
-                                           prefix, mutbl)
-            }
-        }
+        self.create_struct_pattern(cx, variant_path, &variant.node.data, prefix, mutbl)
     }
 }
 
index 5d3cc50557cde8445fe6b3c14c411275b23e5590..07b587783583e699d1bd6e0c5187999100aa172f 100644 (file)
@@ -94,45 +94,35 @@ fn cs_from(name: &str, cx: &mut ExtCtxt, trait_span: Span, substr: &Substructure
             let mut arms = Vec::new();
 
             for variant in &enum_def.variants {
-                match variant.node.kind {
-                    ast::TupleVariantKind(ref args) => {
-                        if !args.is_empty() {
-                            cx.span_err(trait_span,
-                                        "`FromPrimitive` cannot be derived for \
-                                        enum variants with arguments");
-                            return cx.expr_fail(trait_span,
-                                                InternedString::new(""));
-                        }
-                        let span = variant.span;
+                let def = &variant.node.data;
+                if !def.is_unit() {
+                    cx.span_err(trait_span, "`FromPrimitive` cannot be derived \
+                                             for enums with non-unit variants");
+                    return cx.expr_fail(trait_span,
+                                        InternedString::new(""));
+                }
 
-                        // expr for `$n == $variant as $name`
-                        let path = cx.path(span, vec![substr.type_ident, variant.node.name]);
-                        let variant = cx.expr_path(path);
-                        let ty = cx.ty_ident(span, cx.ident_of(name));
-                        let cast = cx.expr_cast(span, variant.clone(), ty);
-                        let guard = cx.expr_binary(span, ast::BiEq, n.clone(), cast);
+                let span = variant.span;
 
-                        // expr for `Some($variant)`
-                        let body = cx.expr_some(span, variant);
+                // expr for `$n == $variant as $name`
+                let path = cx.path(span, vec![substr.type_ident, variant.node.name]);
+                let variant = cx.expr_path(path);
+                let ty = cx.ty_ident(span, cx.ident_of(name));
+                let cast = cx.expr_cast(span, variant.clone(), ty);
+                let guard = cx.expr_binary(span, ast::BiEq, n.clone(), cast);
 
-                        // arm for `_ if $guard => $body`
-                        let arm = ast::Arm {
-                            attrs: vec!(),
-                            pats: vec!(cx.pat_wild(span)),
-                            guard: Some(guard),
-                            body: body,
-                        };
+                // expr for `Some($variant)`
+                let body = cx.expr_some(span, variant);
 
-                        arms.push(arm);
-                    }
-                    ast::StructVariantKind(_) => {
-                        cx.span_err(trait_span,
-                                    "`FromPrimitive` cannot be derived for enums \
-                                    with struct variants");
-                        return cx.expr_fail(trait_span,
-                                            InternedString::new(""));
-                    }
-                }
+                // arm for `_ if $guard => $body`
+                let arm = ast::Arm {
+                    attrs: vec!(),
+                    pats: vec!(cx.pat_wild(span)),
+                    guard: Some(guard),
+                    body: body,
+                };
+
+                arms.push(arm);
             }
 
             // arm for `_ => None`
diff --git a/src/libsyntax/ext/pushpop_safe.rs b/src/libsyntax/ext/pushpop_safe.rs
deleted file mode 100644 (file)
index a67d550..0000000
+++ /dev/null
@@ -1,94 +0,0 @@
-// Copyright 2015 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.
-
-/*
- * The compiler code necessary to support the `push_unsafe!` and
- * `pop_unsafe!` macros.
- *
- * This is a hack to allow a kind of "safety hygiene", where a macro
- * can generate code with an interior expression that inherits the
- * safety of some outer context.
- *
- * For example, in:
- *
- * ```rust
- * fn foo() { push_unsafe!( { EXPR_1; pop_unsafe!( EXPR_2 ) } ) }
- * ```
- *
- * the `EXPR_1` is considered to be in an `unsafe` context,
- * but `EXPR_2` is considered to be in a "safe" (i.e. checked) context.
- *
- * For comparison, in:
- *
- * ```rust
- * fn foo() { unsafe { push_unsafe!( { EXPR_1; pop_unsafe!( EXPR_2 ) } ) } }
- * ```
- *
- * both `EXPR_1` and `EXPR_2` are considered to be in `unsafe`
- * contexts.
- *
- */
-
-use ast;
-use codemap::Span;
-use ext::base::*;
-use ext::base;
-use ext::build::AstBuilder;
-use feature_gate;
-use ptr::P;
-
-enum PushPop { Push, Pop }
-
-pub fn expand_push_unsafe<'cx>(cx: &'cx mut ExtCtxt, sp: Span, tts: &[ast::TokenTree])
-                               -> Box<base::MacResult+'cx> {
-    expand_pushpop_unsafe(cx, sp, tts, PushPop::Push)
-}
-
-pub fn expand_pop_unsafe<'cx>(cx: &'cx mut ExtCtxt, sp: Span, tts: &[ast::TokenTree])
-                               -> Box<base::MacResult+'cx> {
-    expand_pushpop_unsafe(cx, sp, tts, PushPop::Pop)
-}
-
-fn expand_pushpop_unsafe<'cx>(cx: &'cx mut ExtCtxt, sp: Span, tts: &[ast::TokenTree],
-                                  pp: PushPop) -> Box<base::MacResult+'cx> {
-    feature_gate::check_for_pushpop_syntax(
-        cx.ecfg.features, &cx.parse_sess.span_diagnostic, sp);
-
-    let mut exprs = match get_exprs_from_tts(cx, sp, tts) {
-        Some(exprs) => exprs.into_iter(),
-        None => return DummyResult::expr(sp),
-    };
-
-    let expr = match (exprs.next(), exprs.next()) {
-        (Some(expr), None) => expr,
-        _ => {
-            let msg = match pp {
-                PushPop::Push => "push_unsafe! takes 1 arguments",
-                PushPop::Pop => "pop_unsafe! takes 1 arguments",
-            };
-            cx.span_err(sp, msg);
-            return DummyResult::expr(sp);
-        }
-    };
-
-    let source = ast::UnsafeSource::CompilerGenerated;
-    let check_mode = match pp {
-        PushPop::Push => ast::BlockCheckMode::PushUnsafeBlock(source),
-        PushPop::Pop => ast::BlockCheckMode::PopUnsafeBlock(source),
-    };
-
-    MacEager::expr(cx.expr_block(P(ast::Block {
-        stmts: vec![],
-        expr: Some(expr),
-        id: ast::DUMMY_NODE_ID,
-        rules: check_mode,
-        span: sp
-    })))
-}
index 1d545268e57d760965cd7ef7995a89a167353feb..be6ad9311114af434c797aec0120439faca7f03d 100644 (file)
     // allow `#[unwind]`
     ("unwind_attributes", "1.4.0", None, Active),
 
-    // allow empty structs/enum variants with braces
+    // allow empty structs and enum variants with braces
     ("braced_empty_structs", "1.5.0", None, Active),
 
     // allow overloading augmented assignment operations like `a += b`
@@ -486,6 +486,7 @@ pub struct Features {
     pub cfg_target_feature: bool,
     pub cfg_target_vendor: bool,
     pub augmented_assignments: bool,
+    pub braced_empty_structs: bool,
 }
 
 impl Features {
@@ -516,6 +517,7 @@ pub fn new() -> Features {
             cfg_target_feature: false,
             cfg_target_vendor: false,
             augmented_assignments: false,
+            braced_empty_structs: false,
         }
     }
 }
@@ -809,7 +811,7 @@ fn visit_item(&mut self, i: &ast::Item) {
                 }
             }
 
-            ast::ItemStruct(ref def, _) => {
+            ast::ItemStruct(..) => {
                 if attr::contains_name(&i.attrs[..], "simd") {
                     self.gate_feature("simd", i.span,
                                       "SIMD types are experimental and possibly buggy");
@@ -828,10 +830,6 @@ fn visit_item(&mut self, i: &ast::Item) {
                         }
                     }
                 }
-                if def.fields.is_empty() && def.ctor_id.is_none() {
-                    self.gate_feature("braced_empty_structs", i.span,
-                                      "empty structs with braces are unstable");
-                }
             }
 
             ast::ItemDefaultImpl(..) => {
@@ -859,6 +857,21 @@ fn visit_item(&mut self, i: &ast::Item) {
         visit::walk_item(self, i);
     }
 
+    fn visit_variant_data(&mut self, s: &'v ast::VariantData, _: ast::Ident,
+                        _: &'v ast::Generics, _: ast::NodeId, span: Span) {
+        if s.fields().count() == 0 {
+            if s.is_struct() {
+                self.gate_feature("braced_empty_structs", span,
+                                  "empty structs and enum variants with braces are unstable");
+            } else if s.is_tuple() {
+                self.context.span_handler.span_err(span, "empty tuple structs and enum variants \
+                                                          are not allowed, use unit structs and \
+                                                          enum variants instead");
+            }
+        }
+        visit::walk_struct_def(self, s)
+    }
+
     fn visit_foreign_item(&mut self, i: &ast::ForeignItem) {
         let links_to_llvm = match attr::first_attr_value_str_by_name(&i.attrs,
                                                                      "link_name") {
@@ -881,12 +894,6 @@ fn visit_expr(&mut self, e: &ast::Expr) {
                                   "box expression syntax is experimental; \
                                    you can call `Box::new` instead.");
             }
-            ast::ExprStruct(_, ref fields, ref expr) => {
-                if fields.is_empty() && expr.is_none() {
-                    self.gate_feature("braced_empty_structs", e.span,
-                                      "empty structs with braces are unstable");
-                }
-            }
             _ => {}
         }
         visit::walk_expr(self, e);
@@ -911,12 +918,6 @@ fn visit_pat(&mut self, pattern: &ast::Pat) {
                                   pattern.span,
                                   "box pattern syntax is experimental");
             }
-            ast::PatStruct(_, ref fields, dotdot) => {
-                if fields.is_empty() && !dotdot {
-                    self.gate_feature("braced_empty_structs", pattern.span,
-                                      "empty structs with braces are unstable");
-                }
-            }
             _ => {}
         }
         visit::walk_pat(self, pattern)
@@ -1086,6 +1087,7 @@ fn check_crate_inner<F>(cm: &CodeMap, span_handler: &SpanHandler,
         cfg_target_feature: cx.has_feature("cfg_target_feature"),
         cfg_target_vendor: cx.has_feature("cfg_target_vendor"),
         augmented_assignments: cx.has_feature("augmented_assignments"),
+        braced_empty_structs: cx.has_feature("braced_empty_structs"),
     }
 }
 
index 3c1aa992a3c16aa77fda64e1982cd8f4c5c58a48..219a4649339dd753d9093a4dee2060f52c3febc3 100644 (file)
@@ -231,7 +231,7 @@ fn fold_poly_trait_ref(&mut self, p: PolyTraitRef) -> PolyTraitRef {
         noop_fold_poly_trait_ref(p, self)
     }
 
-    fn fold_struct_def(&mut self, struct_def: P<StructDef>) -> P<StructDef> {
+    fn fold_variant_data(&mut self, struct_def: P<VariantData>) -> P<VariantData> {
         noop_fold_struct_def(struct_def, self)
     }
 
@@ -271,10 +271,6 @@ fn fold_opt_lifetime(&mut self, o_lt: Option<Lifetime>) -> Option<Lifetime> {
         noop_fold_opt_lifetime(o_lt, self)
     }
 
-    fn fold_variant_arg(&mut self, va: VariantArg) -> VariantArg {
-        noop_fold_variant_arg(va, self)
-    }
-
     fn fold_opt_bounds(&mut self, b: Option<OwnedSlice<TyParamBound>>)
                        -> Option<OwnedSlice<TyParamBound>> {
         noop_fold_opt_bounds(b, self)
@@ -450,20 +446,11 @@ pub fn noop_fold_foreign_mod<T: Folder>(ForeignMod {abi, items}: ForeignMod,
 }
 
 pub fn noop_fold_variant<T: Folder>(v: P<Variant>, fld: &mut T) -> P<Variant> {
-    v.map(|Spanned {node: Variant_ {id, name, attrs, kind, disr_expr}, span}| Spanned {
+    v.map(|Spanned {node: Variant_ {name, attrs, data, disr_expr}, span}| Spanned {
         node: Variant_ {
-            id: fld.new_id(id),
             name: name,
             attrs: fold_attrs(attrs, fld),
-            kind: match kind {
-                TupleVariantKind(variant_args) => {
-                    TupleVariantKind(variant_args.move_map(|x|
-                        fld.fold_variant_arg(x)))
-                }
-                StructVariantKind(struct_def) => {
-                    StructVariantKind(fld.fold_struct_def(struct_def))
-                }
-            },
+            data: fld.fold_variant_data(data),
             disr_expr: disr_expr.map(|e| fld.fold_expr(e)),
         },
         span: fld.new_span(span),
@@ -827,10 +814,19 @@ pub fn noop_fold_where_predicate<T: Folder>(
     }
 }
 
-pub fn noop_fold_struct_def<T: Folder>(struct_def: P<StructDef>, fld: &mut T) -> P<StructDef> {
-    struct_def.map(|StructDef { fields, ctor_id }| StructDef {
-        fields: fields.move_map(|f| fld.fold_struct_field(f)),
-        ctor_id: ctor_id.map(|cid| fld.new_id(cid)),
+pub fn noop_fold_struct_def<T: Folder>(struct_def: P<VariantData>, fld: &mut T) -> P<VariantData> {
+    struct_def.map(|vdata| {
+        match vdata {
+            ast::VariantData::Struct(fields, id) => {
+                ast::VariantData::Struct(fields.move_map(|f| fld.fold_struct_field(f)),
+                                         fld.new_id(id))
+            }
+            ast::VariantData::Tuple(fields, id) => {
+                ast::VariantData::Tuple(fields.move_map(|f| fld.fold_struct_field(f)),
+                                        fld.new_id(id))
+            }
+            ast::VariantData::Unit(id) => ast::VariantData::Unit(fld.new_id(id))
+        }
     })
 }
 
@@ -892,14 +888,6 @@ fn noop_fold_bounds<T: Folder>(bounds: TyParamBounds, folder: &mut T)
     bounds.move_map(|bound| folder.fold_ty_param_bound(bound))
 }
 
-fn noop_fold_variant_arg<T: Folder>(VariantArg {id, ty}: VariantArg, folder: &mut T)
-                                    -> VariantArg {
-    VariantArg {
-        id: folder.new_id(id),
-        ty: folder.fold_ty(ty)
-    }
-}
-
 pub fn noop_fold_block<T: Folder>(b: P<Block>, folder: &mut T) -> P<Block> {
     b.map(|Block {id, stmts, expr, rules, span}| Block {
         id: folder.new_id(id),
@@ -945,7 +933,7 @@ pub fn noop_fold_item_underscore<T: Folder>(i: Item_, folder: &mut T) -> Item_ {
                 folder.fold_generics(generics))
         }
         ItemStruct(struct_def, generics) => {
-            let struct_def = folder.fold_struct_def(struct_def);
+            let struct_def = folder.fold_variant_data(struct_def);
             ItemStruct(struct_def, folder.fold_generics(generics))
         }
         ItemDefaultImpl(unsafety, ref trait_ref) => {
index d1c862ad40b2526866fd0e52be4cd2a626ee04c7..f3b2c79a7dd0485400871348efd914f41ae55c39 100644 (file)
@@ -121,7 +121,6 @@ pub mod ext {
     pub mod log_syntax;
     pub mod mtwt;
     pub mod quote;
-    pub mod pushpop_safe;
     pub mod source_util;
     pub mod trace_macros;
 
index 443cea696b682150af3e30ed48b7fc90db1f02ed..b4c052eb1817f38352f43e306fe30bdb143289dc 100644 (file)
 use ast::PatWildSingle;
 use ast::{PolyTraitRef, QSelf};
 use ast::{Return, BiShl, BiShr, Stmt, StmtDecl};
-use ast::{StmtExpr, StmtSemi, StmtMac, StructDef, StructField};
-use ast::{StructVariantKind, BiSub, StrStyle};
+use ast::{StmtExpr, StmtSemi, StmtMac, VariantData, StructField};
+use ast::{BiSub, StrStyle};
 use ast::{SelfExplicit, SelfRegion, SelfStatic, SelfValue};
 use ast::{Delimited, SequenceRepetition, TokenTree, TraitItem, TraitRef};
 use ast::{TtDelimited, TtSequence, TtToken};
-use ast::{TupleVariantKind, Ty, Ty_, TypeBinding};
+use ast::{Ty, Ty_, TypeBinding};
 use ast::{TyMac};
 use ast::{TyFixedLengthVec, TyBareFn, TyTypeof, TyInfer};
 use ast::{TyParam, TyParamBound, TyParen, TyPath, TyPolyTraitRef, TyPtr};
@@ -4380,11 +4380,11 @@ pub fn is_const_item(&mut self) -> bool {
     /// - `extern fn`
     /// - etc
     pub fn parse_fn_front_matter(&mut self) -> PResult<(ast::Constness, ast::Unsafety, abi::Abi)> {
+        let unsafety = try!(self.parse_unsafety());
         let is_const_fn = try!(self.eat_keyword(keywords::Const));
         let (constness, unsafety, abi) = if is_const_fn {
-            (Constness::Const, Unsafety::Normal, abi::Rust)
+            (Constness::Const, unsafety, abi::Rust)
         } else {
-            let unsafety = try!(self.parse_unsafety());
             let abi = if try!(self.eat_keyword(keywords::Extern)) {
                 try!(self.parse_opt_abi()).unwrap_or(abi::C)
             } else {
@@ -4640,26 +4640,25 @@ fn parse_item_struct(&mut self) -> PResult<ItemInfo> {
         // Otherwise if we look ahead and see a paren we parse a tuple-style
         // struct.
 
-        let (fields, ctor_id) = if self.token.is_keyword(keywords::Where) {
+        let vdata = if self.token.is_keyword(keywords::Where) {
             generics.where_clause = try!(self.parse_where_clause());
             if try!(self.eat(&token::Semi)) {
                 // If we see a: `struct Foo<T> where T: Copy;` style decl.
-                (Vec::new(), Some(ast::DUMMY_NODE_ID))
+                VariantData::Unit(ast::DUMMY_NODE_ID)
             } else {
                 // If we see: `struct Foo<T> where T: Copy { ... }`
-                (try!(self.parse_record_struct_body()), None)
+                VariantData::Struct(try!(self.parse_record_struct_body()), ast::DUMMY_NODE_ID)
             }
         // No `where` so: `struct Foo<T>;`
         } else if try!(self.eat(&token::Semi) ){
-            (Vec::new(), Some(ast::DUMMY_NODE_ID))
+            VariantData::Unit(ast::DUMMY_NODE_ID)
         // Record-style struct definition
         } else if self.token == token::OpenDelim(token::Brace) {
-            let fields = try!(self.parse_record_struct_body());
-            (fields, None)
+            VariantData::Struct(try!(self.parse_record_struct_body()), ast::DUMMY_NODE_ID)
         // Tuple-style struct definition with optional where-clause.
         } else if self.token == token::OpenDelim(token::Paren) {
-            let fields = try!(self.parse_tuple_struct_body(class_name, &mut generics));
-            (fields, Some(ast::DUMMY_NODE_ID))
+            VariantData::Tuple(try!(self.parse_tuple_struct_body(&mut generics)),
+                               ast::DUMMY_NODE_ID)
         } else {
             let token_str = self.this_token_to_string();
             return Err(self.fatal(&format!("expected `where`, `{{`, `(`, or `;` after struct \
@@ -4667,11 +4666,8 @@ fn parse_item_struct(&mut self) -> PResult<ItemInfo> {
         };
 
         Ok((class_name,
-         ItemStruct(P(ast::StructDef {
-             fields: fields,
-             ctor_id: ctor_id,
-         }), generics),
-         None))
+            ItemStruct(P(vdata), generics),
+            None))
     }
 
     pub fn parse_record_struct_body(&mut self) -> PResult<Vec<StructField>> {
@@ -4693,7 +4689,6 @@ pub fn parse_record_struct_body(&mut self) -> PResult<Vec<StructField>> {
     }
 
     pub fn parse_tuple_struct_body(&mut self,
-                                   class_name: ast::Ident,
                                    generics: &mut ast::Generics)
                                    -> PResult<Vec<StructField>> {
         // This is the case where we find `struct Foo<T>(T) where T: Copy;`
@@ -4714,12 +4709,6 @@ pub fn parse_tuple_struct_body(&mut self,
                 Ok(spanned(lo, p.span.hi, struct_field_))
             }));
 
-        if fields.is_empty() {
-            return Err(self.fatal(&format!("unit-like struct definition should be \
-                                            written as `struct {};`",
-                                           class_name)));
-        }
-
         generics.where_clause = try!(self.parse_where_clause());
         try!(self.expect(&token::Semi));
         Ok(fields)
@@ -5109,17 +5098,14 @@ fn parse_item_type(&mut self) -> PResult<ItemInfo> {
 
     /// Parse a structure-like enum variant definition
     /// this should probably be renamed or refactored...
-    fn parse_struct_def(&mut self) -> PResult<P<StructDef>> {
+    fn parse_struct_def(&mut self) -> PResult<P<VariantData>> {
         let mut fields: Vec<StructField> = Vec::new();
         while self.token != token::CloseDelim(token::Brace) {
             fields.push(try!(self.parse_struct_decl_field(false)));
         }
         try!(self.bump());
 
-        Ok(P(StructDef {
-            fields: fields,
-            ctor_id: None,
-        }))
+        Ok(P(VariantData::Struct(fields, ast::DUMMY_NODE_ID)))
     }
 
     /// Parse the part of an "enum" decl following the '{'
@@ -5131,22 +5117,13 @@ fn parse_enum_def(&mut self, _generics: &ast::Generics) -> PResult<EnumDef> {
             let variant_attrs = self.parse_outer_attributes();
             let vlo = self.span.lo;
 
-            let kind;
-            let mut args = Vec::new();
+            let struct_def;
             let mut disr_expr = None;
             let ident = try!(self.parse_ident());
             if try!(self.eat(&token::OpenDelim(token::Brace)) ){
                 // Parse a struct variant.
                 all_nullary = false;
-                let start_span = self.span;
-                let struct_def = try!(self.parse_struct_def());
-                if struct_def.fields.is_empty() {
-                    self.span_err(start_span,
-                        &format!("unit-like struct variant should be written \
-                                 without braces, as `{},`",
-                                ident));
-                }
-                kind = StructVariantKind(struct_def);
+                struct_def = try!(self.parse_struct_def());
             } else if self.check(&token::OpenDelim(token::Paren)) {
                 all_nullary = false;
                 let arg_tys = try!(self.parse_enum_variant_seq(
@@ -5155,26 +5132,28 @@ fn parse_enum_def(&mut self, _generics: &ast::Generics) -> PResult<EnumDef> {
                     seq_sep_trailing_allowed(token::Comma),
                     |p| p.parse_ty_sum()
                 ));
+                let mut fields = Vec::new();
                 for ty in arg_tys {
-                    args.push(ast::VariantArg {
+                    fields.push(Spanned { span: ty.span, node: ast::StructField_ {
                         ty: ty,
+                        kind: ast::UnnamedField(ast::Inherited),
+                        attrs: Vec::new(),
                         id: ast::DUMMY_NODE_ID,
-                    });
+                    }});
                 }
-                kind = TupleVariantKind(args);
+                struct_def = P(ast::VariantData::Tuple(fields, ast::DUMMY_NODE_ID));
             } else if try!(self.eat(&token::Eq) ){
                 disr_expr = Some(try!(self.parse_expr_nopanic()));
                 any_disr = disr_expr.as_ref().map(|expr| expr.span);
-                kind = TupleVariantKind(args);
+                struct_def = P(ast::VariantData::Unit(ast::DUMMY_NODE_ID));
             } else {
-                kind = TupleVariantKind(Vec::new());
+                struct_def = P(ast::VariantData::Unit(ast::DUMMY_NODE_ID));
             }
 
             let vr = ast::Variant_ {
                 name: ident,
                 attrs: variant_attrs,
-                kind: kind,
-                id: ast::DUMMY_NODE_ID,
+                data: struct_def,
                 disr_expr: disr_expr,
             };
             variants.push(P(spanned(vlo, self.last_span.hi, vr)));
@@ -5399,9 +5378,14 @@ fn parse_item_(&mut self, attrs: Vec<Attribute>,
             } else {
                 abi::Rust
             };
+            let constness = if abi == abi::Rust && try!(self.eat_keyword(keywords::Const) ){
+                Constness::Const
+            } else {
+                Constness::NotConst
+            };
             try!(self.expect_keyword(keywords::Fn));
             let (ident, item_, extra_attrs) =
-                try!(self.parse_item_fn(Unsafety::Unsafe, Constness::NotConst, abi));
+                try!(self.parse_item_fn(Unsafety::Unsafe, constness, abi));
             let last_span = self.last_span;
             let item = self.mk_item(lo,
                                     last_span.hi,
index f5f3907a4e6c874decdd62d738e7bd4fc49f6eb3..7b5aabde231ce44f4b2ab8a451e0551ad4537009 100644 (file)
@@ -520,6 +520,18 @@ fn commasep<T, F>(&mut self, b: Breaks, elts: &[T], mut op: F) -> io::Result<()>
         self.end()
     }
 
+    fn commasep_iter<'it, T: 'it, F, I>(&mut self, b: Breaks, elts: I, mut op: F) -> io::Result<()>
+        where F: FnMut(&mut Self, &T) -> io::Result<()>,
+              I: Iterator<Item=&'it T>,
+    {
+        try!(self.rbox(0, b));
+        let mut first = true;
+        for elt in elts {
+            if first { first = false; } else { try!(self.word_space(",")); }
+            try!(op(self, elt));
+        }
+        self.end()
+    }
 
     fn next_lit(&mut self, pos: BytePos) -> Option<comments::Literal> {
         let mut cur_lit = self.cur_cmnt_and_lit().cur_lit;
@@ -1223,7 +1235,7 @@ pub fn print_item(&mut self, item: &ast::Item) -> io::Result<()> {
             }
             ast::ItemStruct(ref struct_def, ref generics) => {
                 try!(self.head(&visibility_qualified(item.vis,"struct")));
-                try!(self.print_struct(&**struct_def, generics, item.ident, item.span));
+                try!(self.print_struct(&struct_def, generics, item.ident, item.span, true));
             }
 
             ast::ItemDefaultImpl(unsafety, ref trait_ref) => {
@@ -1385,17 +1397,18 @@ pub fn print_visibility(&mut self, vis: ast::Visibility) -> io::Result<()> {
     }
 
     pub fn print_struct(&mut self,
-                        struct_def: &ast::StructDef,
+                        struct_def: &ast::VariantData,
                         generics: &ast::Generics,
                         ident: ast::Ident,
-                        span: codemap::Span) -> io::Result<()> {
+                        span: codemap::Span,
+                        print_finalizer: bool) -> io::Result<()> {
         try!(self.print_ident(ident));
         try!(self.print_generics(generics));
-        if ast_util::struct_def_is_tuple_like(struct_def) {
-            if !struct_def.fields.is_empty() {
+        if !struct_def.is_struct() {
+            if struct_def.is_tuple() {
                 try!(self.popen());
-                try!(self.commasep(
-                    Inconsistent, &struct_def.fields,
+                try!(self.commasep_iter(
+                    Inconsistent, struct_def.fields(),
                     |s, field| {
                         match field.node.kind {
                             ast::NamedField(..) => panic!("unexpected named field"),
@@ -1410,7 +1423,9 @@ pub fn print_struct(&mut self,
                 try!(self.pclose());
             }
             try!(self.print_where_clause(&generics.where_clause));
-            try!(word(&mut self.s, ";"));
+            if print_finalizer {
+                try!(word(&mut self.s, ";"));
+            }
             try!(self.end());
             self.end() // close the outer-box
         } else {
@@ -1419,7 +1434,7 @@ pub fn print_struct(&mut self,
             try!(self.bopen());
             try!(self.hardbreak_if_not_bol());
 
-            for field in &struct_def.fields {
+            for field in struct_def.fields() {
                 match field.node.kind {
                     ast::UnnamedField(..) => panic!("unexpected unnamed field"),
                     ast::NamedField(ident, visibility) => {
@@ -1505,23 +1520,9 @@ pub fn print_tts(&mut self, tts: &[ast::TokenTree]) -> io::Result<()> {
     }
 
     pub fn print_variant(&mut self, v: &ast::Variant) -> io::Result<()> {
-        match v.node.kind {
-            ast::TupleVariantKind(ref args) => {
-                try!(self.print_ident(v.node.name));
-                if !args.is_empty() {
-                    try!(self.popen());
-                    try!(self.commasep(Consistent,
-                                       &args[..],
-                                       |s, arg| s.print_type(&*arg.ty)));
-                    try!(self.pclose());
-                }
-            }
-            ast::StructVariantKind(ref struct_def) => {
-                try!(self.head(""));
-                let generics = ast_util::empty_generics();
-                try!(self.print_struct(&**struct_def, &generics, v.node.name, v.span));
-            }
-        }
+        try!(self.head(""));
+        let generics = ast_util::empty_generics();
+        try!(self.print_struct(&v.node.data, &generics, v.node.name, v.span, false));
         match v.node.disr_expr {
             Some(ref d) => {
                 try!(space(&mut self.s));
@@ -1671,8 +1672,8 @@ pub fn print_block_maybe_unclosed(&mut self,
                                       attrs: &[ast::Attribute],
                                       close_box: bool) -> io::Result<()> {
         match blk.rules {
-            ast::UnsafeBlock(..) | ast::PushUnsafeBlock(..) => try!(self.word_space("unsafe")),
-            ast::DefaultBlock    | ast::PopUnsafeBlock(..) => ()
+            ast::UnsafeBlock(..) => try!(self.word_space("unsafe")),
+            ast::DefaultBlock => ()
         }
         try!(self.maybe_print_comment(blk.span.lo));
         try!(self.ann.pre(self, NodeBlock(blk)));
@@ -3103,6 +3104,7 @@ mod tests {
     use ast_util;
     use codemap;
     use parse::token;
+    use ptr::P;
 
     #[test]
     fn test_fun_to_string() {
@@ -3129,8 +3131,7 @@ fn test_variant_to_string() {
             name: ident,
             attrs: Vec::new(),
             // making this up as I go.... ?
-            kind: ast::TupleVariantKind(Vec::new()),
-            id: 0,
+            data: P(ast::VariantData::Unit(ast::DUMMY_NODE_ID)),
             disr_expr: None,
         });
 
index 091580b9bd837c1318a4d9d6b46e75ca93c852ed..b7d202804c5a42553c8adf8207279604f00c6700 100644 (file)
@@ -80,17 +80,18 @@ fn visit_ty_param_bound(&mut self, bounds: &'v TyParamBound) {
     fn visit_poly_trait_ref(&mut self, t: &'v PolyTraitRef, m: &'v TraitBoundModifier) {
         walk_poly_trait_ref(self, t, m)
     }
-    fn visit_struct_def(&mut self, s: &'v StructDef, _: Ident, _: &'v Generics, _: NodeId) {
+    fn visit_variant_data(&mut self, s: &'v VariantData, _: Ident,
+                        _: &'v Generics, _: NodeId, _: Span) {
         walk_struct_def(self, s)
     }
     fn visit_struct_field(&mut self, s: &'v StructField) { walk_struct_field(self, s) }
     fn visit_enum_def(&mut self, enum_definition: &'v EnumDef,
-                      generics: &'v Generics) {
-        walk_enum_def(self, enum_definition, generics)
+                      generics: &'v Generics, item_id: NodeId) {
+        walk_enum_def(self, enum_definition, generics, item_id)
+    }
+    fn visit_variant(&mut self, v: &'v Variant, g: &'v Generics, item_id: NodeId) {
+        walk_variant(self, v, g, item_id)
     }
-
-    fn visit_variant(&mut self, v: &'v Variant, g: &'v Generics) { walk_variant(self, v, g) }
-
     fn visit_lifetime(&mut self, lifetime: &'v Lifetime) {
         walk_lifetime(self, lifetime)
     }
@@ -271,7 +272,7 @@ pub fn walk_item<'v, V: Visitor<'v>>(visitor: &mut V, item: &'v Item) {
         }
         ItemEnum(ref enum_definition, ref type_parameters) => {
             visitor.visit_generics(type_parameters);
-            visitor.visit_enum_def(enum_definition, type_parameters)
+            visitor.visit_enum_def(enum_definition, type_parameters, item.id)
         }
         ItemDefaultImpl(_, ref trait_ref) => {
             visitor.visit_trait_ref(trait_ref)
@@ -288,10 +289,8 @@ pub fn walk_item<'v, V: Visitor<'v>>(visitor: &mut V, item: &'v Item) {
         }
         ItemStruct(ref struct_definition, ref generics) => {
             visitor.visit_generics(generics);
-            visitor.visit_struct_def(struct_definition,
-                                     item.ident,
-                                     generics,
-                                     item.id)
+            visitor.visit_variant_data(struct_definition, item.ident,
+                                     generics, item.id, item.span);
         }
         ItemTrait(_, ref generics, ref bounds, ref methods) => {
             visitor.visit_generics(generics);
@@ -305,30 +304,20 @@ pub fn walk_item<'v, V: Visitor<'v>>(visitor: &mut V, item: &'v Item) {
 
 pub fn walk_enum_def<'v, V: Visitor<'v>>(visitor: &mut V,
                                          enum_definition: &'v EnumDef,
-                                         generics: &'v Generics) {
+                                         generics: &'v Generics,
+                                         item_id: NodeId) {
     for variant in &enum_definition.variants {
-        visitor.visit_variant(variant, generics);
+        visitor.visit_variant(variant, generics, item_id);
     }
 }
 
 pub fn walk_variant<'v, V: Visitor<'v>>(visitor: &mut V,
                                         variant: &'v Variant,
-                                        generics: &'v Generics) {
+                                        generics: &'v Generics,
+                                        item_id: NodeId) {
     visitor.visit_ident(variant.span, variant.node.name);
-
-    match variant.node.kind {
-        TupleVariantKind(ref variant_arguments) => {
-            for variant_argument in variant_arguments {
-                visitor.visit_ty(&variant_argument.ty)
-            }
-        }
-        StructVariantKind(ref struct_definition) => {
-            visitor.visit_struct_def(struct_definition,
-                                     variant.node.name,
-                                     generics,
-                                     variant.node.id)
-        }
-    }
+    visitor.visit_variant_data(&variant.node.data, variant.node.name,
+                             generics, item_id, variant.span);
     walk_list!(visitor, visit_expr, &variant.node.disr_expr);
     walk_list!(visitor, visit_attribute, &variant.node.attrs);
 }
@@ -614,8 +603,8 @@ pub fn walk_impl_item<'v, V: Visitor<'v>>(visitor: &mut V, impl_item: &'v ImplIt
 }
 
 pub fn walk_struct_def<'v, V: Visitor<'v>>(visitor: &mut V,
-                                           struct_definition: &'v StructDef) {
-    walk_list!(visitor, visit_struct_field, &struct_definition.fields);
+                                           struct_definition: &'v VariantData) {
+    walk_list!(visitor, visit_struct_field, struct_definition.fields());
 }
 
 pub fn walk_struct_field<'v, V: Visitor<'v>>(visitor: &mut V,
index 8824cef2a816c153ea468796cebea190d99a91f6..f7895d694c8246923e15c57a8839c0811ff62ff6 100644 (file)
@@ -218,3 +218,7 @@ uint64_t get_y(struct S s) {
 uint64_t get_z(struct S s) {
     return s.z;
 }
+
+uint64_t get_c_many_params(void *a, void *b, void *c, void *d, struct quad f) {
+    return f.c;
+}
index 4308023a9a535e84a77afc1e99f5a044ebffc718..16c35970bfe77724bc744222ae84d910d33df228 100644 (file)
@@ -335,8 +335,7 @@ LLVMRustSetDataLayoutFromTargetMachine(LLVMModuleRef Module,
                                        LLVMTargetMachineRef TMR) {
     TargetMachine *Target = unwrap(TMR);
 #if LLVM_VERSION_MINOR >= 7
-    if (const DataLayout *DL = Target->getDataLayout())
-        unwrap(Module)->setDataLayout(*DL);
+    unwrap(Module)->setDataLayout(Target->createDataLayout());
 #elif LLVM_VERSION_MINOR >= 6
     if (const DataLayout *DL = Target->getSubtargetImpl()->getDataLayout())
         unwrap(Module)->setDataLayout(DL);
index 64d6a8109888eb50c5cf33882310644609beaab1..1a9ea8bff08b3ea99d5f6244bbde5a8614d61ec6 100644 (file)
@@ -225,7 +225,7 @@ fn main() {
     offset_momentum(&mut bodies);
     println!("{:.9}", energy(&bodies));
 
-    for _ in (0..n) {
+    for _ in 0..n {
         advance(&mut bodies, 0.01, &mut diff, &mut mag);
     }
 
index 0aca9a5c7ee04fc1793e95122650c6a838ed88f6..c26d6cf4fe6d7c96a042ad1663bc13cfc4b4f2ec 100644 (file)
@@ -21,5 +21,5 @@ fn main() {
     let mut x = Int(0);
     x += 1;
     //~^ error: overloaded augmented assignments are not stable
-    // | help: add #![feature(augmented_assignments)] to the crate features to enable
+    // | help: add #![feature(augmented_assignments)] to the crate root to enable
 }
index 66c3014c7a97020c6319a5117580deaa6532eb39..0db8f9858f9dbc335b9437d58ea7111597305ee3 100644 (file)
@@ -22,5 +22,5 @@ fn main() {
     let mut x = Int(0);
     x += 1;
     //~^ error: overloaded augmented assignments are not stable
-    // | help: add #![feature(augmented_assignments)] to the crate features to enable
+    // | help: add #![feature(augmented_assignments)] to the crate root to enable
 }
index 6e9b120aa69b5a6b27a173b69a5ec41cc7535969..e8e37d8804986b60894687371c1fa997363475de 100644 (file)
@@ -23,12 +23,12 @@ struct A { x: isize }
 
 #[derive(FromPrimitive)]
 enum C { Foo(isize), Bar(usize) }
-//~^^ ERROR `FromPrimitive` cannot be derived for enum variants with arguments
-//~^^^ ERROR `FromPrimitive` cannot be derived for enum variants with arguments
+//~^^ ERROR `FromPrimitive` cannot be derived for enums with non-unit variants
+//~^^^ ERROR `FromPrimitive` cannot be derived for enums with non-unit variants
 
 #[derive(FromPrimitive)]
 enum D { Baz { x: isize } }
-//~^^ ERROR `FromPrimitive` cannot be derived for enums with struct variants
-//~^^^ ERROR `FromPrimitive` cannot be derived for enums with struct variants
+//~^^ ERROR `FromPrimitive` cannot be derived for enums with non-unit variants
+//~^^^ ERROR `FromPrimitive` cannot be derived for enums with non-unit variants
 
 pub fn main() {}
diff --git a/src/test/compile-fail/empty-struct-braces-expr.rs b/src/test/compile-fail/empty-struct-braces-expr.rs
new file mode 100644 (file)
index 0000000..6716708
--- /dev/null
@@ -0,0 +1,26 @@
+// Copyright 2015 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.
+
+// Can't use empty braced struct as constant or constructor function
+
+#![feature(braced_empty_structs)]
+
+struct Empty1 {}
+
+enum E {
+    Empty2 {}
+}
+
+fn main() {
+    let e1 = Empty1; //~ ERROR `Empty1` is the name of a struct or struct variant
+    let e1 = Empty1(); //~ ERROR `Empty1` is the name of a struct or struct variant
+    let e2 = E::Empty2; //~ ERROR `E::Empty2` is the name of a struct or struct variant
+    let e2 = E::Empty2(); //~ ERROR `E::Empty2` is the name of a struct or struct variant
+}
diff --git a/src/test/compile-fail/empty-struct-braces-gate-1.rs b/src/test/compile-fail/empty-struct-braces-gate-1.rs
new file mode 100644 (file)
index 0000000..a131b46
--- /dev/null
@@ -0,0 +1,23 @@
+// Copyright 2015 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.
+
+// Feature gate test for empty struct with braces
+// Can't define an empty braced struct
+
+struct Empty1 {} //~ ERROR empty structs and enum variants with braces are unstable
+struct Empty2;
+
+enum E {
+    Empty4 {}, //~ ERROR empty structs and enum variants with braces are unstable
+    Empty5,
+}
+
+fn main() {
+}
diff --git a/src/test/compile-fail/empty-struct-braces-gate-2.rs b/src/test/compile-fail/empty-struct-braces-gate-2.rs
new file mode 100644 (file)
index 0000000..c1b73bd
--- /dev/null
@@ -0,0 +1,49 @@
+// Copyright 2015 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.
+
+// Feature gate test for empty struct with braces
+// Can't use braced expressions and patterns with structs defined without braces
+
+struct Empty2;
+
+enum E {
+    Empty5,
+}
+
+fn main() {
+    let e2: Empty2 = Empty2 {}; //~ ERROR empty structs and enum variants with braces are unstable
+    let e2: Empty2 = Empty2;
+    // Issue #28692
+    // let e5: E = E::Empty5 {}; // ERROR empty structs and enum variants with braces are unstable
+    let e5: E = E::Empty5;
+
+    match e2 {
+        Empty2 {} => {} //~ ERROR empty structs and enum variants with braces are unstable
+    }
+    match e2 {
+        Empty2 => {}
+    }
+    match e2 {
+        Empty2 { .. } => {} //~ ERROR empty structs and enum variants with braces are unstable
+    }
+    // Issue #28692
+    // match e5 {
+    //     E::Empty5 {} => {} // ERROR empty structs and enum variants with braces are unstable
+    // }
+    match e5 {
+        E::Empty5 => {}
+    }
+    // Issue #28692
+    // match e5 {
+    //     E::Empty5 { .. } => {} // ERROR empty structs and enum variants with braces are unstable
+    // }
+
+    let e22 = Empty2 { ..e2 }; //~ ERROR empty structs and enum variants with braces are unstable
+}
diff --git a/src/test/compile-fail/empty-struct-braces-pat-1.rs b/src/test/compile-fail/empty-struct-braces-pat-1.rs
new file mode 100644 (file)
index 0000000..e095f69
--- /dev/null
@@ -0,0 +1,33 @@
+// Copyright 2015 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.
+
+// Can't use empty braced struct as constant pattern
+
+#![deny(warnings)]
+#![feature(braced_empty_structs)]
+
+struct Empty1 {}
+
+enum E {
+    Empty2 {}
+}
+
+fn main() {
+    let e1 = Empty1 {};
+    let e2 = E::Empty2 {};
+
+    // Issue #28692
+    // match e1 {
+    //     Empty1 => () // ERROR incorrect error
+    // }
+    match e2 {
+        E::Empty2 => () //~ ERROR `E::Empty2` does not name a non-struct variant or a tuple struct
+    }
+}
diff --git a/src/test/compile-fail/empty-struct-braces-pat-2.rs b/src/test/compile-fail/empty-struct-braces-pat-2.rs
new file mode 100644 (file)
index 0000000..0e7152e
--- /dev/null
@@ -0,0 +1,39 @@
+// Copyright 2015 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.
+
+// Can't use empty braced struct as enum pattern
+
+#![feature(braced_empty_structs)]
+
+struct Empty1 {}
+
+enum E {
+    Empty2 {}
+}
+
+fn main() {
+    let e1 = Empty1 {};
+    let e2 = E::Empty2 {};
+
+    // Rejected by parser as yet
+    // match e1 {
+    //     Empty1() => () // ERROR unresolved enum variant, struct or const `Empty1`
+    // }
+    match e1 {
+        Empty1(..) => () //~ ERROR unresolved enum variant, struct or const `Empty1`
+    }
+    // Issue #28692
+    // match e2 {
+    //     E::Empty2() => () // ERROR unresolved enum variant, struct or const `Empty2`
+    // }
+    // match e2 {
+    //     E::Empty2(..) => () // ERROR unresolved enum variant, struct or const `Empty2`
+    // }
+}
diff --git a/src/test/compile-fail/empty-struct-unit-expr.rs b/src/test/compile-fail/empty-struct-unit-expr.rs
new file mode 100644 (file)
index 0000000..1990656
--- /dev/null
@@ -0,0 +1,24 @@
+// Copyright 2015 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.
+
+// Can't use unit struct as constructor function
+
+#![feature(braced_empty_structs)]
+
+struct Empty1;
+
+enum E {
+    Empty2
+}
+
+fn main() {
+    let e1 = Empty1(); //~ ERROR expected function, found `Empty1`
+    let e2 = E::Empty2(); //~ ERROR expected function, found `E`
+}
diff --git a/src/test/compile-fail/empty-struct-unit-pat.rs b/src/test/compile-fail/empty-struct-unit-pat.rs
new file mode 100644 (file)
index 0000000..966a278
--- /dev/null
@@ -0,0 +1,40 @@
+// Copyright 2015 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.
+
+// Can't use unit struct as enum pattern
+
+#![feature(braced_empty_structs)]
+
+FIXME //~ ERROR expected item, found `FIXME`
+
+struct Empty1;
+
+enum E {
+    Empty2
+}
+
+fn main() {
+    let e1 = Empty1;
+    let e2 = E::Empty2;
+
+    // Issue #28692
+    // match e1 {
+    //     Empty1() => () // ERROR variable `Empty1` should have a snake case name
+    // }
+    // match e1 {
+    //     Empty1(..) => () // ERROR variable `Empty1` should have a snake case name
+    // }
+    // match e2 {
+    //     E::Empty2() => () // ERROR variable `Empty2` should have a snake case name
+    // }
+    // match e2 {
+    //     E::Empty2(..) => () // ERROR variable `Empty2` should have a snake case name
+    // }
+}
diff --git a/src/test/compile-fail/empty-struct-with-braces-1.rs b/src/test/compile-fail/empty-struct-with-braces-1.rs
deleted file mode 100644 (file)
index ad41225..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-// Copyright 2015 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.
-
-// Empty struct defined with braces shouldn't add names into value namespace
-
-#![feature(braced_empty_structs)]
-
-struct Empty {}
-
-fn main() {
-    let e = Empty; //~ ERROR `Empty` is the name of a struct or struct variant
-}
diff --git a/src/test/compile-fail/empty-struct-with-braces-2.rs b/src/test/compile-fail/empty-struct-with-braces-2.rs
deleted file mode 100644 (file)
index 0e72e7d..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-// Copyright 2015 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.
-
-// Empty struct defined with braces shouldn't add names into value namespace
-
-#![feature(braced_empty_structs)]
-#![deny(warnings)]
-
-struct Empty {}
-
-fn main() {
-    let e = Empty {};
-
-    match e {
-        Empty => () //~ ERROR unused variable: `Empty`
-        //~^ ERROR variable `Empty` should have a snake case name such as `empty`
-    }
-}
diff --git a/src/test/compile-fail/empty-struct-with-braces-3.rs b/src/test/compile-fail/empty-struct-with-braces-3.rs
deleted file mode 100644 (file)
index e6f20ba..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-// Copyright 2015 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.
-
-// Feature gate test for empty struct with braces
-
-struct Empty {} //~ ERROR empty structs with braces are unstable
-
-fn main() {
-    let e = Empty {}; //~ ERROR empty structs with braces are unstable
-
-    match e {
-        Empty {} => {} //~ ERROR empty structs with braces are unstable
-    }
-}
diff --git a/src/test/compile-fail/feature-gate-pushpop-unsafe.rs b/src/test/compile-fail/feature-gate-pushpop-unsafe.rs
deleted file mode 100644 (file)
index e317b4c..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-// Copyright 2015 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.
-
-fn main() {
-    let c = push_unsafe!('c'); //~ ERROR push/pop_unsafe macros are experimental
-    let c = pop_unsafe!('c'); //~ ERROR push/pop_unsafe macros are experimental
-}
diff --git a/src/test/compile-fail/issue-16819.rs b/src/test/compile-fail/issue-16819.rs
new file mode 100644 (file)
index 0000000..065b29d
--- /dev/null
@@ -0,0 +1,18 @@
+// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+struct TS ( //~ ERROR empty tuple structs and enum variants are not allowed
+    #[cfg(untrue)]
+    int,
+);
+
+fn main() {
+    let s = S;
+}
index 533387c576008c5d3e0f73e77cfd44b0ada09f11..3cdb370f0e94c9156e62c52061ab7bb6a5c00601 100644 (file)
@@ -22,8 +22,8 @@ fn main() {
     let Foo { .. } = x; //~ ERROR `Foo` does not name a struct
 
     let x = Bar;
-    Bar { ..x };
-    let Bar { .. } = x;
+    Bar { ..x }; //~ ERROR empty structs and enum variants with braces are unstable
+    let Bar { .. } = x; //~ ERROR empty structs and enum variants with braces are unstable
 
     match Enum::Bar {
         Enum::Bar { .. } //~ ERROR `Enum::Bar` does not name a struct
diff --git a/src/test/compile-fail/pushpop-unsafe-rejects.rs b/src/test/compile-fail/pushpop-unsafe-rejects.rs
deleted file mode 100644 (file)
index 72c065a..0000000
+++ /dev/null
@@ -1,74 +0,0 @@
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <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.
-
-// Basic sanity check for `push_unsafe!(EXPR)` and
-// `pop_unsafe!(EXPR)`: we can call unsafe code when there are a
-// positive number of pushes in the stack, or if we are within a
-// normal `unsafe` block, but otherwise cannot.
-
-#![feature(pushpop_unsafe)]
-
-static mut X: i32 = 0;
-
-unsafe fn f() { X += 1; return; }
-fn g() { unsafe { X += 1_000; } return; }
-
-fn main() {
-    push_unsafe!( {
-        f(); pop_unsafe!({
-            f() //~ ERROR: call to unsafe function
-        })
-    } );
-
-    push_unsafe!({
-        f();
-        pop_unsafe!({
-            g();
-            f(); //~ ERROR: call to unsafe function
-        })
-    } );
-
-    push_unsafe!({
-        g(); pop_unsafe!({
-            unsafe {
-                f();
-            }
-            f(); //~ ERROR: call to unsafe function
-        })
-    });
-
-
-    // Note: For implementation simplicity the compiler just
-    // ICE's if you underflow the push_unsafe stack.
-    //
-    // Thus all of the following cases cause an ICE.
-    //
-    // (The "ERROR" notes are from an earlier version
-    //  that used saturated arithmetic rather than checked
-    //  arithmetic.)
-
-    //    pop_unsafe!{ g() };
-    //
-    //    push_unsafe!({
-    //        pop_unsafe!(pop_unsafe!{ g() })
-    //    });
-    //
-    //    push_unsafe!({
-    //        g();
-    //        pop_unsafe!(pop_unsafe!({
-    //            f() // ERROR: call to unsafe function
-    //        }))
-    //    });
-    //
-    //    pop_unsafe!({
-    //        f(); // ERROR: call to unsafe function
-    //    })
-
-}
diff --git a/src/test/compile-fail/struct-no-fields-enumlike.rs b/src/test/compile-fail/struct-no-fields-enumlike.rs
new file mode 100644 (file)
index 0000000..6bdbae1
--- /dev/null
@@ -0,0 +1,13 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+struct Foo(); //~ ERROR empty tuple structs and enum variants are not allowed
+
+fn main() {}
diff --git a/src/test/compile-fail/unsafe-const-fn.rs b/src/test/compile-fail/unsafe-const-fn.rs
new file mode 100644 (file)
index 0000000..0bbfe4c
--- /dev/null
@@ -0,0 +1,24 @@
+// Copyright 2015 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.
+
+// A quick test of 'unsafe const fn' functionality
+
+#![feature(const_fn)]
+
+unsafe const fn dummy(v: u32) -> u32 {
+    !v
+}
+
+const VAL: u32 = dummy(0xFFFF); //~ ERROR E0133
+
+fn main() {
+    assert_eq!(VAL, 0xFFFF0000);
+}
+
diff --git a/src/test/parse-fail/struct-no-fields-enumlike.rs b/src/test/parse-fail/struct-no-fields-enumlike.rs
deleted file mode 100644 (file)
index 19a3958..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-// 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.
-
-// compile-flags: -Z parse-only
-
-struct Foo(); //~ ERROR unit-like struct definition should be written as `struct Foo;`
-
-fn main() {}
diff --git a/src/test/parse-fail/struct-variant-no-fields.rs b/src/test/parse-fail/struct-variant-no-fields.rs
deleted file mode 100644 (file)
index 68cf661..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-// 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.
-
-// compile-flags: -Z parse-only
-
-enum Foo {
-    Bar {} //~ ERROR unit-like struct variant should be written without braces, as `Bar,`
-}
diff --git a/src/test/run-make/extern-fn-struct-passing-abi/Makefile b/src/test/run-make/extern-fn-struct-passing-abi/Makefile
new file mode 100644 (file)
index 0000000..042048e
--- /dev/null
@@ -0,0 +1,5 @@
+-include ../tools.mk
+
+all: $(call NATIVE_STATICLIB,test)
+       $(RUSTC) test.rs
+       $(call RUN,test) || exit 1
diff --git a/src/test/run-make/extern-fn-struct-passing-abi/test.c b/src/test/run-make/extern-fn-struct-passing-abi/test.c
new file mode 100644 (file)
index 0000000..1a7e338
--- /dev/null
@@ -0,0 +1,238 @@
+// Copyright 2015 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.
+
+#include <assert.h>
+#include <stdint.h>
+
+struct Rect {
+    int32_t a;
+    int32_t b;
+    int32_t c;
+    int32_t d;
+};
+
+struct BiggerRect {
+    struct Rect s;
+    int32_t a;
+    int32_t b;
+};
+
+struct FloatRect {
+    int32_t a;
+    int32_t b;
+    double c;
+};
+
+struct Huge {
+    int32_t a;
+    int32_t b;
+    int32_t c;
+    int32_t d;
+    int32_t e;
+};
+
+// System V x86_64 ABI:
+// a, b, c, d, e should be in registers
+// s should be byval pointer
+//
+// Win64 ABI:
+// a, b, c, d should be in registers
+// e should be on the stack
+// s should be byval pointer
+void byval_rect(int32_t a, int32_t b, int32_t c, int32_t d, int32_t e, struct Rect s) {
+    assert(a == 1);
+    assert(b == 2);
+    assert(c == 3);
+    assert(d == 4);
+    assert(e == 5);
+    assert(s.a == 553);
+    assert(s.b == 554);
+    assert(s.c == 555);
+    assert(s.d == 556);
+}
+
+// System V x86_64 ABI:
+// a, b, c, d, e, f, g should be in sse registers
+// s should be split across 2 registers
+// t should be byval pointer
+//
+// Win64 ABI:
+// a, b, c, d should be in sse registers
+// e, f, g should be on the stack
+// s should be on the stack (treated as 2 i64's)
+// t should be on the stack (treated as an i64 and a double)
+void byval_rect_floats(float a, float b, double c, float d, float e,
+                       float f, double g, struct Rect s, struct FloatRect t) {
+    assert(a == 1.);
+    assert(b == 2.);
+    assert(c == 3.);
+    assert(d == 4.);
+    assert(e == 5.);
+    assert(f == 6.);
+    assert(g == 7.);
+    assert(s.a == 553);
+    assert(s.b == 554);
+    assert(s.c == 555);
+    assert(s.d == 556);
+    assert(t.a == 3489);
+    assert(t.b == 3490);
+    assert(t.c == 8.);
+}
+
+// System V x86_64 ABI:
+// a, b, d, e, f should be in registers
+// c passed via sse registers
+// s should be byval pointer
+//
+// Win64 ABI:
+// a, b, d should be in registers
+// c passed via sse registers
+// e, f should be on the stack
+// s should be byval pointer
+void byval_rect_with_float(int32_t a, int32_t b, float c, int32_t d,
+                           int32_t e, int32_t f, struct Rect s) {
+    assert(a == 1);
+    assert(b == 2);
+    assert(c == 3.);
+    assert(d == 4);
+    assert(e == 5);
+    assert(f == 6);
+    assert(s.a == 553);
+    assert(s.b == 554);
+    assert(s.c == 555);
+    assert(s.d == 556);
+}
+
+// System V x86_64 & Win64 ABI:
+// a, b should be in registers
+// s should be split across 2 integer registers
+void split_rect(int32_t a, int32_t b, struct Rect s) {
+    assert(a == 1);
+    assert(b == 2);
+    assert(s.a == 553);
+    assert(s.b == 554);
+    assert(s.c == 555);
+    assert(s.d == 556);
+}
+
+// System V x86_64 & Win64 ABI:
+// a, b should be in sse registers
+// s should be split across integer & sse registers
+void split_rect_floats(float a, float b, struct FloatRect s) {
+    assert(a == 1.);
+    assert(b == 2.);
+    assert(s.a == 3489);
+    assert(s.b == 3490);
+    assert(s.c == 8.);
+}
+
+// System V x86_64 ABI:
+// a, b, d, f should be in registers
+// c, e passed via sse registers
+// s should be split across 2 registers
+//
+// Win64 ABI:
+// a, b, d should be in registers
+// c passed via sse registers
+// e, f should be on the stack
+// s should be on the stack (treated as 2 i64's)
+void split_rect_with_floats(int32_t a, int32_t b, float c,
+                            int32_t d, float e, int32_t f, struct Rect s) {
+    assert(a == 1);
+    assert(b == 2);
+    assert(c == 3.);
+    assert(d == 4);
+    assert(e == 5.);
+    assert(f == 6);
+    assert(s.a == 553);
+    assert(s.b == 554);
+    assert(s.c == 555);
+    assert(s.d == 556);
+}
+
+// System V x86_64 & Win64 ABI:
+// a, b, c should be in registers
+// s should be split across 2 registers
+// t should be a byval pointer
+void split_and_byval_rect(int32_t a, int32_t b, int32_t c, struct Rect s, struct Rect t) {
+    assert(a == 1);
+    assert(b == 2);
+    assert(c == 3);
+    assert(s.a == 553);
+    assert(s.b == 554);
+    assert(s.c == 555);
+    assert(s.d == 556);
+    assert(t.a == 553);
+    assert(t.b == 554);
+    assert(t.c == 555);
+    assert(t.d == 556);
+}
+
+// System V x86_64 & Win64 ABI:
+// a, b should in registers
+// s and return should be split across 2 registers
+struct Rect split_ret_byval_struct(int32_t a, int32_t b, struct Rect s) {
+    assert(a == 1);
+    assert(b == 2);
+    assert(s.a == 553);
+    assert(s.b == 554);
+    assert(s.c == 555);
+    assert(s.d == 556);
+    return s;
+}
+
+// System V x86_64 & Win64 ABI:
+// a, b, c, d should be in registers
+// return should be in a hidden sret pointer
+// s should be a byval pointer
+struct BiggerRect sret_byval_struct(int32_t a, int32_t b, int32_t c, int32_t d, struct Rect s) {
+    assert(a == 1);
+    assert(b == 2);
+    assert(c == 3);
+    assert(d == 4);
+    assert(s.a == 553);
+    assert(s.b == 554);
+    assert(s.c == 555);
+    assert(s.d == 556);
+
+    struct BiggerRect t;
+    t.s = s; t.a = 27834; t.b = 7657;
+    return t;
+}
+
+// System V x86_64 & Win64 ABI:
+// a, b should be in registers
+// return should be in a hidden sret pointer
+// s should be split across 2 registers
+struct BiggerRect sret_split_struct(int32_t a, int32_t b, struct Rect s) {
+    assert(a == 1);
+    assert(b == 2);
+    assert(s.a == 553);
+    assert(s.b == 554);
+    assert(s.c == 555);
+    assert(s.d == 556);
+
+    struct BiggerRect t;
+    t.s = s; t.a = 27834; t.b = 7657;
+    return t;
+}
+
+// System V x86_64 & Win64 ABI:
+// s should be byval pointer (since sizeof(s) > 16)
+// return should in a hidden sret pointer
+struct Huge huge_struct(struct Huge s) {
+    assert(s.a == 5647);
+    assert(s.b == 5648);
+    assert(s.c == 5649);
+    assert(s.d == 5650);
+    assert(s.e == 5651);
+
+    return s;
+}
diff --git a/src/test/run-make/extern-fn-struct-passing-abi/test.rs b/src/test/run-make/extern-fn-struct-passing-abi/test.rs
new file mode 100644 (file)
index 0000000..f223a8d
--- /dev/null
@@ -0,0 +1,95 @@
+// Copyright 2015 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.
+
+// Passing structs via FFI should work regardless of whether
+// they get passed in multiple registers, byval pointers or the stack
+
+#[derive(Clone, Copy, Debug, PartialEq)]
+#[repr(C)]
+struct Rect {
+    a: i32,
+    b: i32,
+    c: i32,
+    d: i32
+}
+
+#[derive(Clone, Copy, Debug, PartialEq)]
+#[repr(C)]
+struct BiggerRect {
+    s: Rect,
+    a: i32,
+    b: i32
+}
+
+#[derive(Clone, Copy, Debug, PartialEq)]
+#[repr(C)]
+struct FloatRect {
+    a: i32,
+    b: i32,
+    c: f64
+}
+
+#[derive(Clone, Copy, Debug, PartialEq)]
+#[repr(C)]
+struct Huge {
+    a: i32,
+    b: i32,
+    c: i32,
+    d: i32,
+    e: i32
+}
+
+#[link(name = "test", kind = "static")]
+extern {
+    fn byval_rect(a: i32, b: i32, c: i32, d: i32, e: i32, s: Rect);
+
+    fn byval_rect_floats(a: f32, b: f32, c: f64, d: f32, e: f32,
+                         f: f32, g: f64, s: Rect, t: FloatRect);
+
+    fn byval_rect_with_float(a: i32, b: i32, c: f32, d: i32, e: i32, f: i32, s: Rect);
+
+    fn split_rect(a: i32, b: i32, s: Rect);
+
+    fn split_rect_floats(a: f32, b: f32, s: FloatRect);
+
+    fn split_rect_with_floats(a: i32, b: i32, c: f32, d: i32, e: f32, f: i32, s: Rect);
+
+    fn split_and_byval_rect(a: i32, b: i32, c: i32, s: Rect, t: Rect);
+
+    fn split_ret_byval_struct(a: i32, b: i32, s: Rect) -> Rect;
+
+    fn sret_byval_struct(a: i32, b: i32, c: i32, d: i32, s: Rect) -> BiggerRect;
+
+    fn sret_split_struct(a: i32, b: i32, s: Rect) -> BiggerRect;
+
+    fn huge_struct(s: Huge) -> Huge;
+}
+
+fn main() {
+    let s = Rect { a: 553, b: 554, c: 555, d: 556 };
+    let t = BiggerRect { s: s, a: 27834, b: 7657 };
+    let u = FloatRect { a: 3489, b: 3490, c: 8. };
+    let v = Huge { a: 5647, b: 5648, c: 5649, d: 5650, e: 5651 };
+
+    unsafe {
+        byval_rect(1, 2, 3, 4, 5, s);
+        byval_rect_floats(1., 2., 3., 4., 5., 6., 7., s, u);
+        byval_rect_with_float(1, 2, 3.0, 4, 5, 6, s);
+        split_rect(1, 2, s);
+        split_rect_floats(1., 2., u);
+        split_rect_with_floats(1, 2, 3.0, 4, 5.0, 6, s);
+        split_and_byval_rect(1, 2, 3, s, s);
+        split_rect(1, 2, s);
+        assert_eq!(huge_struct(v), v);
+        assert_eq!(split_ret_byval_struct(1, 2, s), s);
+        assert_eq!(sret_byval_struct(1, 2, 3, 4, s), t);
+        assert_eq!(sret_split_struct(1, 2, s), t);
+    }
+}
diff --git a/src/test/run-pass/empty-struct-braces.rs b/src/test/run-pass/empty-struct-braces.rs
new file mode 100644 (file)
index 0000000..f2fbf2d
--- /dev/null
@@ -0,0 +1,88 @@
+// Copyright 2015 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.
+
+// Empty struct defined with braces add names into type namespace
+// Empty struct defined without braces add names into both type and value namespaces
+
+#![feature(braced_empty_structs)]
+
+struct Empty1 {}
+struct Empty2;
+struct Empty3 {}
+const Empty3: Empty3 = Empty3 {};
+
+enum E {
+    Empty4 {},
+    Empty5,
+}
+
+fn main() {
+    let e1: Empty1 = Empty1 {};
+    let e2: Empty2 = Empty2 {};
+    let e2: Empty2 = Empty2;
+    let e3: Empty3 = Empty3 {};
+    let e3: Empty3 = Empty3;
+    let e4: E = E::Empty4 {};
+    // let e5: E = E::Empty5 {}; // Issue #28692
+    let e5: E = E::Empty5;
+
+    match e1 {
+        Empty1 {} => {}
+    }
+    match e2 {
+        Empty2 {} => {}
+    }
+    match e3 {
+        Empty3 {} => {}
+    }
+    match e4 {
+        E::Empty4 {} => {}
+        _ => {}
+    }
+    // Issue #28692
+    // match e5 {
+    //     E::Empty5 {} => {}
+    //     _ => {}
+    // }
+
+    match e1 {
+        Empty1 { .. } => {}
+    }
+    match e2 {
+        Empty2 { .. } => {}
+    }
+    match e3 {
+        Empty3 { .. } => {}
+    }
+    match e4 {
+        E::Empty4 { .. } => {}
+        _ => {}
+    }
+    // Issue #28692
+    // match e5 {
+    //     E::Empty5 { .. } => {}
+    //     _ => {}
+    // }
+
+    match e2 {
+        Empty2 => {}
+    }
+    match e3 {
+        Empty3 => {}
+    }
+    match e5 {
+        E::Empty5 => {}
+        _ => {}
+    }
+
+    let e11: Empty1 = Empty1 { ..e1 };
+    let e22: Empty2 = Empty2 { ..e2 };
+    let e33: Empty3 = Empty3 { ..e3 };
+}
diff --git a/src/test/run-pass/empty-struct-with-braces.rs b/src/test/run-pass/empty-struct-with-braces.rs
deleted file mode 100644 (file)
index dc806ac..0000000
+++ /dev/null
@@ -1,56 +0,0 @@
-// Copyright 2015 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.
-
-// Empty struct defined with braces add names into type namespace
-// Empty struct defined without braces add names into both type and value namespaces
-
-#![feature(braced_empty_structs)]
-
-struct Empty1 {}
-struct Empty2;
-struct Empty3 {}
-const Empty3: Empty3 = Empty3 {};
-
-fn main() {
-    let e1: Empty1 = Empty1 {};
-    let e2: Empty2 = Empty2 {};
-    let e2: Empty2 = Empty2;
-    let e3: Empty3 = Empty3 {};
-    let e3: Empty3 = Empty3;
-
-    match e1 {
-        Empty1 {} => ()
-    }
-    match e2 {
-        Empty2 {} => ()
-    }
-    match e2 {
-        Empty2 => ()
-    }
-    match e3 {
-        Empty3 {} => ()
-    }
-    match e3 {
-        Empty3 => ()
-    }
-    match e1 {
-        Empty1 { .. } => ()
-    }
-    match e2 {
-        Empty2 { .. } => ()
-    }
-    match e3 {
-        Empty3 { .. } => ()
-    }
-
-    let e11 = Empty1 { ..e1 };
-    let e22 = Empty2 { ..e2 };
-    let e33 = Empty3 { ..e3 };
-}
diff --git a/src/test/run-pass/issue-17336.rs b/src/test/run-pass/issue-17336.rs
new file mode 100644 (file)
index 0000000..ce04237
--- /dev/null
@@ -0,0 +1,17 @@
+// Copyright 2015 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.
+
+#[allow(dead_code)]
+fn check(a: &str) {
+    let x = a as *const str;
+    x == x;
+}
+
+fn main() {}
diff --git a/src/test/run-pass/issue-22814.rs b/src/test/run-pass/issue-22814.rs
new file mode 100644 (file)
index 0000000..6afcd77
--- /dev/null
@@ -0,0 +1,22 @@
+// Copyright 2015 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.
+
+trait Test {}
+
+macro_rules! test {
+( $($name:ident)+) => (
+    impl<$($name: Test),*> Test for ($($name,)*) {
+    }
+)
+}
+
+test!(A B C);
+
+fn main() {}
diff --git a/src/test/run-pass/issue-28676.rs b/src/test/run-pass/issue-28676.rs
new file mode 100644 (file)
index 0000000..b8d43c3
--- /dev/null
@@ -0,0 +1,40 @@
+// Copyright 2012-2015 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.
+//
+
+#[derive(Copy, Clone)]
+pub struct Quad { a: u64, b: u64, c: u64, d: u64 }
+
+mod rustrt {
+    use super::Quad;
+
+    #[link(name = "rust_test_helpers")]
+    extern {
+        pub fn get_c_many_params(_: *const (), _: *const (),
+                                 _: *const (), _: *const (), f: Quad) -> u64;
+    }
+}
+
+fn test() {
+    unsafe {
+        let null = std::ptr::null();
+        let q = Quad {
+            a: 1,
+            b: 2,
+            c: 3,
+            d: 4
+        };
+        assert_eq!(rustrt::get_c_many_params(null, null, null, null, q), q.c);
+    }
+}
+
+pub fn main() {
+    test();
+}
diff --git a/src/test/run-pass/issue-28983.rs b/src/test/run-pass/issue-28983.rs
new file mode 100644 (file)
index 0000000..658e9e1
--- /dev/null
@@ -0,0 +1,31 @@
+// Copyright 2015 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.
+
+trait Test { type T; }
+
+impl Test for u32 {
+    type T = i32;
+}
+
+pub mod export {
+    #[no_mangle]
+    pub extern "C" fn issue_28983(t: <u32 as ::Test>::T) -> i32 { t*3 }
+}
+
+// to test both exporting and importing functions, import
+// a function from ourselves.
+extern "C" {
+    fn issue_28983(t: <u32 as Test>::T) -> i32;
+}
+
+fn main() {
+    assert_eq!(export::issue_28983(2), 6);
+    assert_eq!(unsafe { issue_28983(3) }, 9);
+}
diff --git a/src/test/run-pass/issue-28999.rs b/src/test/run-pass/issue-28999.rs
new file mode 100644 (file)
index 0000000..87112ef
--- /dev/null
@@ -0,0 +1,20 @@
+// Copyright 2015 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.
+
+pub struct Xyz<'a, V> {
+    pub v: (V, &'a u32),
+}
+
+pub fn eq<'a, 's, 't, V>(this: &'s Xyz<'a, V>, other: &'t Xyz<'a, V>) -> bool
+        where V: PartialEq {
+    this.v == other.v
+}
+
+fn main() {}
diff --git a/src/test/run-pass/pushpop-unsafe-okay.rs b/src/test/run-pass/pushpop-unsafe-okay.rs
deleted file mode 100644 (file)
index fc402d4..0000000
+++ /dev/null
@@ -1,56 +0,0 @@
-// Copyright 2015 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.
-
-// Basic sanity check for `push_unsafe!(EXPR)` and
-// `pop_unsafe!(EXPR)`: we can call unsafe code when there are a
-// positive number of pushes in the stack, or if we are within a
-// normal `unsafe` block, but otherwise cannot.
-
-// ignore-pretty because the `push_unsafe!` and `pop_unsafe!` macros
-// are not integrated with the pretty-printer.
-
-#![feature(pushpop_unsafe)]
-
-static mut X: i32 = 0;
-
-unsafe fn f() { X += 1; return; }
-fn g() { unsafe { X += 1_000; } return; }
-
-fn check_reset_x(x: i32) -> bool {
-    #![allow(unused_parens)] // dont you judge my style choices!
-    unsafe {
-        let ret = (x == X);
-        X = 0;
-        ret
-    }
-}
-
-fn main() {
-    // double-check test infrastructure
-    assert!(check_reset_x(0));
-    unsafe { f(); }
-    assert!(check_reset_x(1));
-    assert!(check_reset_x(0));
-    { g(); }
-    assert!(check_reset_x(1000));
-    assert!(check_reset_x(0));
-    unsafe { f(); g(); g(); }
-    assert!(check_reset_x(2001));
-
-    push_unsafe!( { f(); pop_unsafe!( g() ) } );
-    assert!(check_reset_x(1_001));
-    push_unsafe!( { g(); pop_unsafe!( unsafe { f(); f(); } ) } );
-    assert!(check_reset_x(1_002));
-
-    unsafe { push_unsafe!( { f(); pop_unsafe!( { f(); f(); } ) } ); }
-    assert!(check_reset_x(3));
-    push_unsafe!( { f(); push_unsafe!( { pop_unsafe!( { f(); f(); f(); } ) } ); } );
-    assert!(check_reset_x(4));
-}
diff --git a/src/test/run-pass/unsafe-const-fn.rs b/src/test/run-pass/unsafe-const-fn.rs
new file mode 100644 (file)
index 0000000..2ba1131
--- /dev/null
@@ -0,0 +1,31 @@
+// Copyright 2015 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.
+
+// A quick test of 'unsafe const fn' functionality
+
+#![feature(const_fn)]
+
+unsafe const fn dummy(v: u32) -> u32 {
+    !v
+}
+
+struct Type;
+impl Type {
+    unsafe const fn new() -> Type {
+        Type
+    }
+}
+
+const VAL: u32 = unsafe { dummy(0xFFFF) };
+const TYPE_INST: Type = unsafe { Type::new() };
+
+fn main() {
+    assert_eq!(VAL, 0xFFFF0000);
+}