]> git.lizzy.rs Git - rust.git/commitdiff
Rollup merge of #50342 - fkjogu:euclidean, r=BurntSushi
authorkennytm <kennytm@gmail.com>
Wed, 27 Jun 2018 22:15:38 +0000 (06:15 +0800)
committerGitHub <noreply@github.com>
Wed, 27 Jun 2018 22:15:38 +0000 (06:15 +0800)
Document round-off error in `.mod_euc()`-method, see issue #50179

Due to a round-off error the method `.mod_euc()` of both `f32` and `f64` can produce mathematical invalid outputs. If `self` in magnitude is much small than the modulus `rhs` and negative, `self + rhs` in the first branch cannot be represented in the given precision and results into `rhs`. In the mathematical strict sense, this breaks the definition. But given the limitation of floating point arithmetic it can be thought of the closest representable value to the true result, although it is not strictly in the domain `[0.0, rhs)` of the function. It is rather the left side asymptotical limit. It would be desirable that it produces the mathematical more sound approximation of `0.0`, the right side asymptotical limit. But this breaks the property, that `self == self.div_euc(rhs) * rhs + a.mod_euc(rhs)`.

The discussion in issue #50179 did not find an satisfying conclusion to which property is deemed more important. But at least we can document the behaviour. Which this pull request does.

239 files changed:
src/Cargo.lock
src/bootstrap/tool.rs
src/doc/unstable-book/src/language-features/irrefutable-let-patterns.md [new file with mode: 0644]
src/liballoc/boxed.rs
src/liballoc/lib.rs
src/liballoc/str.rs
src/libcore/ascii.rs
src/libcore/char/decode.rs
src/libcore/char/methods.rs
src/libcore/fmt/num.rs
src/libcore/mem.rs
src/libcore/num/mod.rs
src/libcore/option.rs
src/libcore/slice/mod.rs
src/libcore/str/lossy.rs
src/libcore/str/mod.rs
src/libcore/task.rs [deleted file]
src/libcore/task/context.rs [new file with mode: 0644]
src/libcore/task/executor.rs [new file with mode: 0644]
src/libcore/task/mod.rs [new file with mode: 0644]
src/libcore/task/poll.rs [new file with mode: 0644]
src/libcore/task/task.rs [new file with mode: 0644]
src/libcore/task/wake.rs [new file with mode: 0644]
src/libcore/tests/slice.rs
src/libcore/tests/time.rs
src/libcore/time.rs
src/librustc/hir/lowering.rs
src/librustc/hir/mod.rs
src/librustc/ich/fingerprint.rs
src/librustc/ich/impls_syntax.rs
src/librustc/infer/canonical.rs
src/librustc/infer/higher_ranked/mod.rs
src/librustc/infer/lexical_region_resolve/README.md
src/librustc/infer/region_constraints/README.md
src/librustc/lint/builtin.rs
src/librustc/lint/context.rs
src/librustc/lint/mod.rs
src/librustc/middle/region.rs
src/librustc/middle/resolve_lifetime.rs
src/librustc/mir/mod.rs
src/librustc/traits/coherence.rs
src/librustc/traits/error_reporting.rs
src/librustc/traits/mod.rs
src/librustc/traits/select.rs
src/librustc/traits/specialize/mod.rs
src/librustc/ty/codec.rs
src/librustc/ty/query/on_disk_cache.rs
src/librustc/ty/sty.rs
src/librustc/util/ppaux.rs
src/librustc_allocator/expand.rs
src/librustc_apfloat/ieee.rs
src/librustc_borrowck/borrowck/README.md
src/librustc_codegen_llvm/back/wasm.rs
src/librustc_codegen_llvm/diagnostics.rs
src/librustc_codegen_utils/symbol_names.rs
src/librustc_incremental/persist/file_format.rs
src/librustc_incremental/persist/save.rs
src/librustc_lint/builtin.rs
src/librustc_lint/lib.rs
src/librustc_metadata/encoder.rs
src/librustc_metadata/index.rs
src/librustc_mir/build/scope.rs
src/librustc_mir/diagnostics.rs
src/librustc_mir/hair/pattern/check_match.rs
src/librustc_mir/hair/pattern/mod.rs
src/librustc_mir/interpret/const_eval.rs
src/librustc_plugin/registry.rs
src/librustc_resolve/macros.rs
src/librustc_target/abi/call/mod.rs
src/librustc_target/abi/mod.rs
src/librustc_typeck/check/mod.rs
src/librustc_typeck/collect.rs
src/librustc_typeck/diagnostics.rs
src/librustdoc/Cargo.toml
src/librustdoc/clean/auto_trait.rs
src/librustdoc/clean/mod.rs
src/librustdoc/core.rs
src/librustdoc/html/render.rs
src/librustdoc/lib.rs
src/libserialize/hex.rs
src/libserialize/json.rs
src/libserialize/leb128.rs
src/libserialize/lib.rs
src/libserialize/opaque.rs
src/libstd/future.rs
src/libstd/macros.rs
src/libstd/panic.rs
src/libstd/sys/mod.rs
src/libstd/sys/unix/fs.rs
src/libstd/sys/unix/rand.rs
src/libstd/sys_common/backtrace.rs
src/libstd/sys_common/wtf8.rs
src/libsyntax/ast.rs
src/libsyntax/ext/base.rs
src/libsyntax/ext/derive.rs
src/libsyntax/ext/expand.rs
src/libsyntax/ext/tt/macro_rules.rs
src/libsyntax/feature_gate.rs
src/libsyntax/fold.rs
src/libsyntax/parse/lexer/mod.rs
src/libsyntax/parse/parser.rs
src/libsyntax/print/pprust.rs
src/libsyntax/std_inject.rs
src/libsyntax/test.rs
src/libsyntax_ext/format_foreign.rs
src/libsyntax_ext/lib.rs
src/libsyntax_ext/proc_macro_registrar.rs
src/libsyntax_pos/hygiene.rs
src/libsyntax_pos/lib.rs
src/libterm/terminfo/parm.rs
src/test/compile-fail/associated-path-shl.rs
src/test/compile-fail/cross-borrow-trait.rs
src/test/compile-fail/destructure-trait-ref.rs
src/test/compile-fail/dst-bad-assign-3.rs
src/test/compile-fail/dst-bad-assign.rs
src/test/compile-fail/feature-gate-without_gate_irrefutable_pattern.rs [new file with mode: 0644]
src/test/compile-fail/fn-trait-formatting.rs
src/test/compile-fail/issue-13033.rs
src/test/compile-fail/issue-20939.rs
src/test/compile-fail/issue-27895.rs
src/test/compile-fail/issue-32963.rs
src/test/compile-fail/issue-41139.rs
src/test/compile-fail/issue-41255.rs
src/test/compile-fail/issue-5153.rs
src/test/compile-fail/kindck-send-object.rs
src/test/compile-fail/kindck-send-object1.rs
src/test/compile-fail/kindck-send-object2.rs
src/test/compile-fail/map-types.rs
src/test/compile-fail/match-range-fail-2.rs
src/test/compile-fail/match-range-fail.rs
src/test/compile-fail/non-constant-in-const-path.rs
src/test/compile-fail/non-interger-atomic.rs
src/test/compile-fail/object-does-not-impl-trait.rs
src/test/compile-fail/object-safety-by-value-self-use.rs
src/test/compile-fail/patkind-litrange-no-expr.rs
src/test/compile-fail/privacy/associated-item-privacy-type-binding.rs
src/test/compile-fail/private-inferred-type.rs
src/test/compile-fail/qualified-path-params.rs
src/test/compile-fail/refutable-pattern-errors.rs
src/test/compile-fail/should-fail-no_gate_irrefutable_if_let_pattern.rs [new file with mode: 0644]
src/test/compile-fail/should-fail-with_gate_irrefutable_pattern_deny.rs [new file with mode: 0644]
src/test/compile-fail/trait-item-privacy.rs
src/test/compile-fail/traits-repeated-supertrait-ambig.rs
src/test/compile-fail/trivial_casts.rs
src/test/compile-fail/type-mismatch-same-crate-name.rs
src/test/compile-fail/type-parameter-defaults-referencing-Self-ppaux.rs
src/test/mir-opt/end_region_6.rs
src/test/mir-opt/end_region_7.rs
src/test/mir-opt/validate_1.rs
src/test/mir-opt/validate_5.rs
src/test/run-pass-fulldeps/ast_stmt_expr_attr.rs
src/test/run-pass-fulldeps/auxiliary/plugin_args.rs
src/test/run-pass-fulldeps/issue-11881.rs
src/test/run-pass/allow_irrefutable_let_patterns.rs [new file with mode: 0644]
src/test/run-pass/byte-literals.rs
src/test/run-pass/inferred-suffix-in-pattern-range.rs
src/test/run-pass/issue-12582.rs
src/test/run-pass/issue-13027.rs
src/test/run-pass/issue-13867.rs
src/test/run-pass/issue-18060.rs
src/test/run-pass/issue-18464.rs
src/test/run-pass/issue-21058.rs
src/test/run-pass/issue-21475.rs
src/test/run-pass/issue-26251.rs
src/test/run-pass/issue-35423.rs
src/test/run-pass/issue-7222.rs
src/test/run-pass/macro-literal.rs
src/test/run-pass/match-range-infer.rs
src/test/run-pass/match-range-static.rs
src/test/run-pass/match-range.rs
src/test/run-pass/rfc-2005-default-binding-mode/range.rs
src/test/ui/anonymous-higher-ranked-lifetime.stderr
src/test/ui/arbitrary-self-types-not-object-safe.stderr
src/test/ui/cast-to-unsized-trait-object-suggestion.stderr
src/test/ui/check_match/issue-43253.rs
src/test/ui/check_match/issue-43253.stderr
src/test/ui/closure-array-break-length.rs [new file with mode: 0644]
src/test/ui/closure-array-break-length.stderr [new file with mode: 0644]
src/test/ui/const-eval/const_signed_pat.rs
src/test/ui/const-eval/ice-generic-assoc-const.rs [new file with mode: 0644]
src/test/ui/const-eval/ref_to_int_match.rs
src/test/ui/const-eval/ref_to_int_match.stderr
src/test/ui/const-unsized.stderr
src/test/ui/did_you_mean/bad-assoc-ty.stderr
src/test/ui/error-codes/E0029-teach.rs
src/test/ui/error-codes/E0029-teach.stderr
src/test/ui/error-codes/E0029.rs
src/test/ui/error-codes/E0029.stderr
src/test/ui/error-codes/E0030-teach.rs
src/test/ui/error-codes/E0030-teach.stderr
src/test/ui/error-codes/E0030.rs
src/test/ui/error-codes/E0030.stderr
src/test/ui/error-codes/E0033-teach.stderr
src/test/ui/error-codes/E0033.stderr
src/test/ui/error-codes/E0308-4.rs
src/test/ui/error-codes/E0308-4.stderr
src/test/ui/error-codes/E0558.stderr
src/test/ui/error-codes/E0648.rs [new file with mode: 0644]
src/test/ui/error-codes/E0648.stderr [new file with mode: 0644]
src/test/ui/error-codes/E0657.rs
src/test/ui/error-codes/E0657.stderr
src/test/ui/fat-ptr-cast.stderr
src/test/ui/feature-gate-trivial_bounds.stderr
src/test/ui/fmt/send-sync.stderr
src/test/ui/hygiene/auxiliary/local_inner_macros.rs [new file with mode: 0644]
src/test/ui/hygiene/local_inner_macros.rs [new file with mode: 0644]
src/test/ui/hygiene/local_inner_macros_disabled.rs [new file with mode: 0644]
src/test/ui/hygiene/local_inner_macros_disabled.stderr [new file with mode: 0644]
src/test/ui/impl-trait/auto-trait-leak.rs
src/test/ui/impl-trait/auto-trait-leak.stderr
src/test/ui/impl_trait_projections.rs
src/test/ui/impl_trait_projections.stderr
src/test/ui/in-band-lifetimes/impl/dyn-trait.stderr
src/test/ui/in-band-lifetimes/mismatched_trait_impl-2.stderr
src/test/ui/issue-17441.rs
src/test/ui/issue-17441.stderr
src/test/ui/issue-20692.stderr
src/test/ui/issue-50577.rs [new file with mode: 0644]
src/test/ui/issue-50577.stderr [new file with mode: 0644]
src/test/ui/lint-ctypes.rs
src/test/ui/lint-ctypes.stderr
src/test/ui/lint/inclusive-range-pattern-syntax.fixed [new file with mode: 0644]
src/test/ui/lint/inclusive-range-pattern-syntax.rs [new file with mode: 0644]
src/test/ui/lint/inclusive-range-pattern-syntax.stderr [new file with mode: 0644]
src/test/ui/lub-glb/old-lub-glb-object.stderr
src/test/ui/mismatched_types/cast-rfc0401.stderr
src/test/ui/mismatched_types/issue-19109.stderr
src/test/ui/mismatched_types/trait-bounds-cant-coerce.stderr
src/test/ui/nll/ty-outlives/projection-no-regions-closure.stderr
src/test/ui/nll/ty-outlives/ty-param-closure-outlives-from-return-type.stderr
src/test/ui/range-inclusive-pattern-precedence.rs
src/test/ui/range-inclusive-pattern-precedence.stderr
src/test/ui/resolve/issue-5035-2.stderr
src/test/ui/span/borrowck-object-mutability.nll.stderr
src/test/ui/suggestions/confuse-field-and-method/issue-2392.stderr
src/test/ui/trivial-bounds-inconsistent-sized.stderr
src/test/ui/trivial-bounds-inconsistent.stderr
src/test/ui/underscore-lifetime/dyn-trait-underscore.stderr
src/test/ui/unsized-enum2.stderr

index 64eea50e3e07e54bc04d2a2e9b54ea76b9341d27..b74587e566210aabb4878f9d67285590465753b5 100644 (file)
@@ -1220,7 +1220,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "minifier"
-version = "0.0.11"
+version = "0.0.14"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "regex 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -2426,7 +2426,7 @@ dependencies = [
 name = "rustdoc"
 version = "0.0.0"
 dependencies = [
- "minifier 0.0.11 (registry+https://github.com/rust-lang/crates.io-index)",
+ "minifier 0.0.14 (registry+https://github.com/rust-lang/crates.io-index)",
  "pulldown-cmark 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "tempfile 3.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
@@ -3263,7 +3263,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 "checksum mdbook 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "90b5a8d7e341ceee5db3882a06078d42661ddcfa2b3687319cc5da76ec4e782f"
 "checksum memchr 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "796fba70e76612589ed2ce7f45282f5af869e0fdd7cc6199fa1aa1f1d591ba9d"
 "checksum memoffset 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0f9dc261e2b62d7a622bf416ea3c5245cdd5d9a7fcc428c0d06804dfce1775b3"
-"checksum minifier 0.0.11 (registry+https://github.com/rust-lang/crates.io-index)" = "26f3e36a4db1981b16567e4abfd6ddc3641bc9b950bdc868701f656bf9b74bdd"
+"checksum minifier 0.0.14 (registry+https://github.com/rust-lang/crates.io-index)" = "78cb57f9a385530d60f2d67f6e108050b478b7a0ffd0bb9c350803e1356535dd"
 "checksum miniz-sys 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "609ce024854aeb19a0ef7567d348aaa5a746b32fb72e336df7fcc16869d7e2b4"
 "checksum miow 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9224c91f82b3c47cf53dcf78dfaa20d6888fbcc5d272d5f2fcdf8a697f3c987d"
 "checksum nibble_vec 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "c8d77f3db4bce033f4d04db08079b2ef1c3d02b44e86f25d08886fafa7756ffa"
index 0c164d86332a815cd215b77d99c12dc6596a538e..0a428a61d120299354400223834a0eacfa0e1501 100644 (file)
@@ -273,7 +273,7 @@ pub fn get_mode(&self) -> Mode {
             /// Whether this tool requires LLVM to run
             pub fn uses_llvm_tools(&self) -> bool {
                 match self {
-                    $(Tool::$name => true $(&& $llvm)*,)+
+                    $(Tool::$name => false $(|| $llvm)*,)+
                 }
             }
         }
@@ -340,9 +340,6 @@ fn run(self, builder: &Builder) -> PathBuf {
     }
 }
 
-// FIXME(#51459): We have only checked that RustInstaller does not require
-// the LLVM binaries when running. We should go through all tools to determine
-// if they really need LLVM binaries, and make `llvm_tools` a required argument.
 tool!(
     Rustbook, "src/tools/rustbook", "rustbook", Mode::ToolRustc;
     ErrorIndex, "src/tools/error_index_generator", "error_index_generator", Mode::ToolRustc;
@@ -350,10 +347,10 @@ fn run(self, builder: &Builder) -> PathBuf {
     Tidy, "src/tools/tidy", "tidy", Mode::ToolStd;
     Linkchecker, "src/tools/linkchecker", "linkchecker", Mode::ToolStd;
     CargoTest, "src/tools/cargotest", "cargotest", Mode::ToolStd;
-    Compiletest, "src/tools/compiletest", "compiletest", Mode::ToolTest;
+    Compiletest, "src/tools/compiletest", "compiletest", Mode::ToolTest, llvm_tools = true;
     BuildManifest, "src/tools/build-manifest", "build-manifest", Mode::ToolStd;
     RemoteTestClient, "src/tools/remote-test-client", "remote-test-client", Mode::ToolStd;
-    RustInstaller, "src/tools/rust-installer", "fabricate", Mode::ToolStd, llvm_tools = false;
+    RustInstaller, "src/tools/rust-installer", "fabricate", Mode::ToolStd;
     RustdocTheme, "src/tools/rustdoc-themes", "rustdoc-themes", Mode::ToolStd;
 );
 
diff --git a/src/doc/unstable-book/src/language-features/irrefutable-let-patterns.md b/src/doc/unstable-book/src/language-features/irrefutable-let-patterns.md
new file mode 100644 (file)
index 0000000..46b8437
--- /dev/null
@@ -0,0 +1,28 @@
+# `irrefutable_let_patterns`
+
+The tracking issue for this feature is: [#44495]
+
+[#44495]: https://github.com/rust-lang/rust/issues/44495
+
+------------------------
+
+This feature changes the way that "irrefutable patterns" are handled
+in the `if let` and `while let` forms. An *irrefutable pattern* is one
+that cannot fail to match -- for example, the `_` pattern matches any
+value, and hence it is "irrefutable". Without this feature, using an
+irrefutable pattern in an `if let` gives a hard error (since often
+this indicates programmer error). But when the feature is enabled, the
+error becomes a lint (since in some cases irrefutable patterns are
+expected). This means you can use `#[allow]` to silence the lint:
+
+```rust
+#![feature(irrefutable_let_patterns)]
+
+#[allow(irrefutable_let_patterns)]
+fn main() {
+    // These two examples used to be errors, but now they
+    // trigger a lint (that is allowed):
+    if let _ = 5 {}
+    while let _ = 5 { break; }
+}
+```
index ea60c7775af59f6881a77a6c59824acfc2db6f5f..6a05ef680889aeb4d12ba634a4234e164f6a2523 100644 (file)
@@ -66,7 +66,7 @@
 use core::mem::{self, PinMut};
 use core::ops::{CoerceUnsized, Deref, DerefMut, Generator, GeneratorState};
 use core::ptr::{self, NonNull, Unique};
-use core::task::{Context, Poll, UnsafeTask, TaskObj};
+use core::task::{Context, Poll, UnsafeTask, TaskObj, LocalTaskObj};
 use core::convert::From;
 
 use raw_vec::RawVec;
@@ -933,7 +933,7 @@ fn poll(mut self: PinMut<Self>, cx: &mut Context) -> Poll<Self::Output> {
 }
 
 #[unstable(feature = "futures_api", issue = "50547")]
-unsafe impl<F: Future<Output = ()> + Send + 'static> UnsafeTask for PinBox<F> {
+unsafe impl<F: Future<Output = ()> + 'static> UnsafeTask for PinBox<F> {
     fn into_raw(self) -> *mut () {
         PinBox::into_raw(self) as *mut ()
     }
@@ -962,3 +962,17 @@ fn from(boxed: Box<F>) -> Self {
         TaskObj::new(PinBox::from(boxed))
     }
 }
+
+#[unstable(feature = "futures_api", issue = "50547")]
+impl<F: Future<Output = ()> + 'static> From<PinBox<F>> for LocalTaskObj {
+    fn from(boxed: PinBox<F>) -> Self {
+        LocalTaskObj::new(boxed)
+    }
+}
+
+#[unstable(feature = "futures_api", issue = "50547")]
+impl<F: Future<Output = ()> + 'static> From<Box<F>> for LocalTaskObj {
+    fn from(boxed: Box<F>) -> Self {
+        LocalTaskObj::new(PinBox::from(boxed))
+    }
+}
index e25742a4a61eb5f709c4d56bfabe7ccaa3cf7366..ec9b5eba561060a21efc741df7d0d9867d40796a 100644 (file)
 #![cfg_attr(stage0, feature(repr_transparent))]
 #![feature(rustc_attrs)]
 #![feature(specialization)]
+#![feature(split_ascii_whitespace)]
 #![feature(staged_api)]
 #![feature(str_internals)]
 #![feature(trusted_len)]
index 32ca8d1fa5eba835c83378ac15c52589310e72d5..ec9c39c916c4720badead169b96ad7a321588696 100644 (file)
@@ -78,6 +78,8 @@
 pub use core::str::pattern;
 #[stable(feature = "encode_utf16", since = "1.8.0")]
 pub use core::str::EncodeUtf16;
+#[unstable(feature = "split_ascii_whitespace", issue = "48656")]
+pub use core::str::SplitAsciiWhitespace;
 
 #[unstable(feature = "slice_concat_ext",
            reason = "trait should not have to exist",
index e6b0569281f89b219433d3e1826014009edfa268..6ee91e0b22ff09bd9b0879df889d634f06bad365 100644 (file)
@@ -108,7 +108,7 @@ pub fn escape_default(c: u8) -> EscapeDefault {
         b'\\' => ([b'\\', b'\\', 0, 0], 2),
         b'\'' => ([b'\\', b'\'', 0, 0], 2),
         b'"' => ([b'\\', b'"', 0, 0], 2),
-        b'\x20' ... b'\x7e' => ([c, 0, 0, 0], 1),
+        b'\x20' ..= b'\x7e' => ([c, 0, 0, 0], 1),
         _ => ([b'\\', b'x', hexify(c >> 4), hexify(c & 0xf)], 4),
     };
 
@@ -116,7 +116,7 @@ pub fn escape_default(c: u8) -> EscapeDefault {
 
     fn hexify(b: u8) -> u8 {
         match b {
-            0 ... 9 => b'0' + b,
+            0 ..= 9 => b'0' + b,
             _ => b'a' + b - 10,
         }
     }
index 45a73191db2f2cfc0004644c2fdd2954c716d31f..0b8dce19dffa1c053437ce55f3da3cd36760a027 100644 (file)
@@ -64,7 +64,7 @@ macro_rules! first_byte {
                 }
             }
             macro_rules! continuation_byte {
-                () => { continuation_byte!(0x80...0xBF) };
+                () => { continuation_byte!(0x80..=0xBF) };
                 ($range: pat) => {
                     match self.0.peek() {
                         Some(&byte @ $range) => {
@@ -77,35 +77,35 @@ macro_rules! continuation_byte {
             }
 
             match first_byte {
-                0x00...0x7F => {
+                0x00..=0x7F => {
                     first_byte!(0b1111_1111);
                 }
-                0xC2...0xDF => {
+                0xC2..=0xDF => {
                     first_byte!(0b0001_1111);
                     continuation_byte!();
                 }
                 0xE0 => {
                     first_byte!(0b0000_1111);
-                    continuation_byte!(0xA0...0xBF);  // 0x80...0x9F here are overlong
+                    continuation_byte!(0xA0..=0xBF);  // 0x80..=0x9F here are overlong
                     continuation_byte!();
                 }
-                0xE1...0xEC | 0xEE...0xEF => {
+                0xE1..=0xEC | 0xEE..=0xEF => {
                     first_byte!(0b0000_1111);
                     continuation_byte!();
                     continuation_byte!();
                 }
                 0xED => {
                     first_byte!(0b0000_1111);
-                    continuation_byte!(0x80...0x9F);  // 0xA0..0xBF here are surrogates
+                    continuation_byte!(0x80..=0x9F);  // 0xA0..0xBF here are surrogates
                     continuation_byte!();
                 }
                 0xF0 => {
                     first_byte!(0b0000_0111);
-                    continuation_byte!(0x90...0xBF);  // 0x80..0x8F here are overlong
+                    continuation_byte!(0x90..=0xBF);  // 0x80..0x8F here are overlong
                     continuation_byte!();
                     continuation_byte!();
                 }
-                0xF1...0xF3 => {
+                0xF1..=0xF3 => {
                     first_byte!(0b0000_0111);
                     continuation_byte!();
                     continuation_byte!();
@@ -113,7 +113,7 @@ macro_rules! continuation_byte {
                 }
                 0xF4 => {
                     first_byte!(0b0000_0111);
-                    continuation_byte!(0x80...0x8F);  // 0x90..0xBF here are beyond char::MAX
+                    continuation_byte!(0x80..=0x8F);  // 0x90..0xBF here are beyond char::MAX
                     continuation_byte!();
                     continuation_byte!();
                 }
index f6b201fe06dea429e44b9b6e8006bb5b500db179..eee78de903628cee1514f40a0dc86315637dc210 100644 (file)
@@ -125,9 +125,9 @@ pub fn to_digit(self, radix: u32) -> Option<u32> {
             panic!("to_digit: radix is too high (maximum 36)");
         }
         let val = match self {
-          '0' ... '9' => self as u32 - '0' as u32,
-          'a' ... 'z' => self as u32 - 'a' as u32 + 10,
-          'A' ... 'Z' => self as u32 - 'A' as u32 + 10,
+          '0' ..= '9' => self as u32 - '0' as u32,
+          'a' ..= 'z' => self as u32 - 'a' as u32 + 10,
+          'A' ..= 'Z' => self as u32 - 'A' as u32 + 10,
           _ => return None,
         };
         if val < radix { Some(val) }
@@ -305,7 +305,7 @@ pub fn escape_default(self) -> EscapeDefault {
             '\r' => EscapeDefaultState::Backslash('r'),
             '\n' => EscapeDefaultState::Backslash('n'),
             '\\' | '\'' | '"' => EscapeDefaultState::Backslash(self),
-            '\x20' ... '\x7e' => EscapeDefaultState::Char(self),
+            '\x20' ..= '\x7e' => EscapeDefaultState::Char(self),
             _ => EscapeDefaultState::Unicode(self.escape_unicode())
         };
         EscapeDefault { state: init_state }
@@ -543,7 +543,7 @@ pub fn encode_utf16(self, dst: &mut [u16]) -> &mut [u16] {
     #[inline]
     pub fn is_alphabetic(self) -> bool {
         match self {
-            'a'...'z' | 'A'...'Z' => true,
+            'a'..='z' | 'A'..='Z' => true,
             c if c > '\x7f' => derived_property::Alphabetic(c),
             _ => false,
         }
@@ -599,7 +599,7 @@ pub fn is_xid_continue(self) -> bool {
     #[inline]
     pub fn is_lowercase(self) -> bool {
         match self {
-            'a'...'z' => true,
+            'a'..='z' => true,
             c if c > '\x7f' => derived_property::Lowercase(c),
             _ => false,
         }
@@ -627,7 +627,7 @@ pub fn is_lowercase(self) -> bool {
     #[inline]
     pub fn is_uppercase(self) -> bool {
         match self {
-            'A'...'Z' => true,
+            'A'..='Z' => true,
             c if c > '\x7f' => derived_property::Uppercase(c),
             _ => false,
         }
@@ -654,7 +654,7 @@ pub fn is_uppercase(self) -> bool {
     #[inline]
     pub fn is_whitespace(self) -> bool {
         match self {
-            ' ' | '\x09'...'\x0d' => true,
+            ' ' | '\x09'..='\x0d' => true,
             c if c > '\x7f' => property::White_Space(c),
             _ => false,
         }
@@ -737,7 +737,7 @@ pub(crate) fn is_grapheme_extended(self) -> bool {
     #[inline]
     pub fn is_numeric(self) -> bool {
         match self {
-            '0'...'9' => true,
+            '0'..='9' => true,
             c if c > '\x7f' => general_category::N(c),
             _ => false,
         }
index 4451ab445cc5c9e5315598a76032d7aa50d0f13c..51391fa50d56f915dfd51cb32c778a311a969d08 100644 (file)
@@ -121,19 +121,19 @@ impl GenericRadix for $T {
             fn digit(x: u8) -> u8 {
                 match x {
                     $($x => $conv,)+
-                    x => panic!("number not in the range 0..{}: {}", Self::BASE - 1, x),
+                    x => panic!("number not in the range 0..={}: {}", Self::BASE - 1, x),
                 }
             }
         }
     }
 }
 
-radix! { Binary,    2, "0b", x @  0 ...  1 => b'0' + x }
-radix! { Octal,     8, "0o", x @  0 ...  7 => b'0' + x }
-radix! { LowerHex, 16, "0x", x @  0 ...  9 => b'0' + x,
-                             x @ 10 ... 15 => b'a' + (x - 10) }
-radix! { UpperHex, 16, "0x", x @  0 ...  9 => b'0' + x,
-                             x @ 10 ... 15 => b'A' + (x - 10) }
+radix! { Binary,    2, "0b", x @  0 ..=  1 => b'0' + x }
+radix! { Octal,     8, "0o", x @  0 ..=  7 => b'0' + x }
+radix! { LowerHex, 16, "0x", x @  0 ..=  9 => b'0' + x,
+                             x @ 10 ..= 15 => b'a' + (x - 10) }
+radix! { UpperHex, 16, "0x", x @  0 ..=  9 => b'0' + x,
+                             x @ 10 ..= 15 => b'A' + (x - 10) }
 
 macro_rules! int_base {
     ($Trait:ident for $T:ident as $U:ident -> $Radix:ident) => {
index 31635ffa53c83b20ab7172bd2ea5480760bcbbf6..08bd9289ab48758559b14030151c36e343fbb078 100644 (file)
@@ -1119,6 +1119,12 @@ impl<'a, T: ?Sized + Unpin> PinMut<'a, T> {
     pub fn new(reference: &'a mut T) -> PinMut<'a, T> {
         PinMut { inner: reference }
     }
+
+    /// Get a mutable reference to the data inside of this `PinMut`.
+    #[unstable(feature = "pin", issue = "49150")]
+    pub fn get_mut(this: PinMut<'a, T>) -> &'a mut T {
+        this.inner
+    }
 }
 
 
@@ -1150,21 +1156,21 @@ pub fn reborrow<'b>(&'b mut self) -> PinMut<'b, T> {
     /// the data out of the mutable reference you receive when you call this
     /// function.
     #[unstable(feature = "pin", issue = "49150")]
-    pub unsafe fn get_mut(this: PinMut<'a, T>) -> &'a mut T {
+    pub unsafe fn get_mut_unchecked(this: PinMut<'a, T>) -> &'a mut T {
         this.inner
     }
 
     /// Construct a new pin by mapping the interior value.
     ///
-    /// For example, if you  wanted to get a `PinMut` of a field of something, you
-    /// could use this to get access to that field in one line of code.
+    /// For example, if you  wanted to get a `PinMut` of a field of something,
+    /// you could use this to get access to that field in one line of code.
     ///
     /// This function is unsafe. You must guarantee that the data you return
     /// will not move so long as the argument value does not move (for example,
     /// because it is one of the fields of that value), and also that you do
     /// not move out of the argument you receive to the interior function.
     #[unstable(feature = "pin", issue = "49150")]
-    pub unsafe fn map<U, F>(this: PinMut<'a, T>, f: F) -> PinMut<'a, U> where
+    pub unsafe fn map_unchecked<U, F>(this: PinMut<'a, T>, f: F) -> PinMut<'a, U> where
         F: FnOnce(&mut T) -> &mut U
     {
         PinMut { inner: f(this.inner) }
index 1168126c47c93a538c4a35a304533a0e3c20302b..7e2dd304d7f5a23b2fa2644d949eaf2711c9c1d5 100644 (file)
@@ -1996,12 +1996,10 @@ pub fn is_negative(self) -> bool { self < 0 }
         /// # Examples
         ///
         /// ```
-        /// #![feature(int_to_from_bytes)]
-        ///
         /// let bytes = i32::min_value().to_be().to_bytes();
         /// assert_eq!(bytes, [0x80, 0, 0, 0]);
         /// ```
-        #[unstable(feature = "int_to_from_bytes", issue = "49792")]
+        #[stable(feature = "int_to_from_bytes", since = "1.29.0")]
         #[inline]
         pub fn to_bytes(self) -> [u8; mem::size_of::<Self>()] {
             unsafe { mem::transmute(self) }
@@ -2018,12 +2016,10 @@ pub fn is_negative(self) -> bool { self < 0 }
         /// # Examples
         ///
         /// ```
-        /// #![feature(int_to_from_bytes)]
-        ///
         /// let int = i32::from_be(i32::from_bytes([0x80, 0, 0, 0]));
         /// assert_eq!(int, i32::min_value());
         /// ```
-        #[unstable(feature = "int_to_from_bytes", issue = "49792")]
+        #[stable(feature = "int_to_from_bytes", since = "1.29.0")]
         #[inline]
         pub fn from_bytes(bytes: [u8; mem::size_of::<Self>()]) -> Self {
             unsafe { mem::transmute(bytes) }
@@ -3702,12 +3698,10 @@ pub fn wrapping_next_power_of_two(self) -> Self {
         /// # Examples
         ///
         /// ```
-        /// #![feature(int_to_from_bytes)]
-        ///
         /// let bytes = 0x1234_5678_u32.to_be().to_bytes();
         /// assert_eq!(bytes, [0x12, 0x34, 0x56, 0x78]);
         /// ```
-        #[unstable(feature = "int_to_from_bytes", issue = "49792")]
+        #[stable(feature = "int_to_from_bytes", since = "1.29.0")]
         #[inline]
         pub fn to_bytes(self) -> [u8; mem::size_of::<Self>()] {
             unsafe { mem::transmute(self) }
@@ -3724,12 +3718,10 @@ pub fn wrapping_next_power_of_two(self) -> Self {
         /// # Examples
         ///
         /// ```
-        /// #![feature(int_to_from_bytes)]
-        ///
         /// let int = u32::from_be(u32::from_bytes([0x12, 0x34, 0x56, 0x78]));
         /// assert_eq!(int, 0x1234_5678_u32);
         /// ```
-        #[unstable(feature = "int_to_from_bytes", issue = "49792")]
+        #[stable(feature = "int_to_from_bytes", since = "1.29.0")]
         #[inline]
         pub fn from_bytes(bytes: [u8; mem::size_of::<Self>()]) -> Self {
             unsafe { mem::transmute(bytes) }
index e633d80a63cd19efabe39a438dfc639431fa320e..20bc173f7e1548043c5c28bebfb57649e5518472 100644 (file)
@@ -275,7 +275,7 @@ pub fn as_mut(&mut self) -> Option<&mut T> {
     #[unstable(feature = "pin", issue = "49150")]
     pub fn as_pin_mut<'a>(self: PinMut<'a, Self>) -> Option<PinMut<'a, T>> {
         unsafe {
-            PinMut::get_mut(self).as_mut().map(|x| PinMut::new_unchecked(x))
+            PinMut::get_mut_unchecked(self).as_mut().map(|x| PinMut::new_unchecked(x))
         }
     }
 
index 6f4c130d8f318b1eb1114ad6b7b7591e8f98c2aa..e74e527927d7bc47cff1d9ea70820a31d651ac8c 100644 (file)
@@ -1230,7 +1230,7 @@ pub fn ends_with(&self, needle: &[T]) -> bool
     /// assert_eq!(s.binary_search(&4),   Err(7));
     /// assert_eq!(s.binary_search(&100), Err(13));
     /// let r = s.binary_search(&1);
-    /// assert!(match r { Ok(1...4) => true, _ => false, });
+    /// assert!(match r { Ok(1..=4) => true, _ => false, });
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn binary_search(&self, x: &T) -> Result<usize, usize>
@@ -1268,7 +1268,7 @@ pub fn binary_search(&self, x: &T) -> Result<usize, usize>
     /// assert_eq!(s.binary_search_by(|probe| probe.cmp(&seek)), Err(13));
     /// let seek = 1;
     /// let r = s.binary_search_by(|probe| probe.cmp(&seek));
-    /// assert!(match r { Ok(1...4) => true, _ => false, });
+    /// assert!(match r { Ok(1..=4) => true, _ => false, });
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
@@ -1325,7 +1325,7 @@ pub fn binary_search_by<'a, F>(&'a self, mut f: F) -> Result<usize, usize>
     /// assert_eq!(s.binary_search_by_key(&4, |&(a,b)| b),   Err(7));
     /// assert_eq!(s.binary_search_by_key(&100, |&(a,b)| b), Err(13));
     /// let r = s.binary_search_by_key(&1, |&(a,b)| b);
-    /// assert!(match r { Ok(1...4) => true, _ => false, });
+    /// assert!(match r { Ok(1..=4) => true, _ => false, });
     /// ```
     #[stable(feature = "slice_binary_search_by_key", since = "1.10.0")]
     #[inline]
index 30b7267da7c5e09a6bded4d315589f5730e88114..5cfb36d3b195bbcc2673673b2c2155cd74f8975f 100644 (file)
@@ -101,10 +101,10 @@ macro_rules! error { () => ({
                     }
                     3 => {
                         match (byte, safe_get(self.source, i)) {
-                            (0xE0, 0xA0 ... 0xBF) => (),
-                            (0xE1 ... 0xEC, 0x80 ... 0xBF) => (),
-                            (0xED, 0x80 ... 0x9F) => (),
-                            (0xEE ... 0xEF, 0x80 ... 0xBF) => (),
+                            (0xE0, 0xA0 ..= 0xBF) => (),
+                            (0xE1 ..= 0xEC, 0x80 ..= 0xBF) => (),
+                            (0xED, 0x80 ..= 0x9F) => (),
+                            (0xEE ..= 0xEF, 0x80 ..= 0xBF) => (),
                             _ => {
                                 error!();
                             }
@@ -117,9 +117,9 @@ macro_rules! error { () => ({
                     }
                     4 => {
                         match (byte, safe_get(self.source, i)) {
-                            (0xF0, 0x90 ... 0xBF) => (),
-                            (0xF1 ... 0xF3, 0x80 ... 0xBF) => (),
-                            (0xF4, 0x80 ... 0x8F) => (),
+                            (0xF0, 0x90 ..= 0xBF) => (),
+                            (0xF1 ..= 0xF3, 0x80 ..= 0xBF) => (),
+                            (0xF4, 0x80 ..= 0x8F) => (),
                             _ => {
                                 error!();
                             }
index 5e1a9c25a2190729b0696c65d43e50d2caba4fed..5ae2f6349e5b7e335846eeafb779c40e7ca106eb 100644 (file)
@@ -21,7 +21,7 @@
 use fmt;
 use iter::{Map, Cloned, FusedIterator, TrustedLen, Filter};
 use iter_private::TrustedRandomAccess;
-use slice::{self, SliceIndex};
+use slice::{self, SliceIndex, Split as SliceSplit};
 use mem;
 
 pub mod pattern;
@@ -1484,10 +1484,10 @@ macro_rules! next { () => {{
                 },
                 3 => {
                     match (first, next!()) {
-                        (0xE0         , 0xA0 ... 0xBF) |
-                        (0xE1 ... 0xEC, 0x80 ... 0xBF) |
-                        (0xED         , 0x80 ... 0x9F) |
-                        (0xEE ... 0xEF, 0x80 ... 0xBF) => {}
+                        (0xE0         , 0xA0 ..= 0xBF) |
+                        (0xE1 ..= 0xEC, 0x80 ..= 0xBF) |
+                        (0xED         , 0x80 ..= 0x9F) |
+                        (0xEE ..= 0xEF, 0x80 ..= 0xBF) => {}
                         _ => err!(Some(1))
                     }
                     if next!() & !CONT_MASK != TAG_CONT_U8 {
@@ -1496,9 +1496,9 @@ macro_rules! next { () => {{
                 }
                 4 => {
                     match (first, next!()) {
-                        (0xF0         , 0x90 ... 0xBF) |
-                        (0xF1 ... 0xF3, 0x80 ... 0xBF) |
-                        (0xF4         , 0x80 ... 0x8F) => {}
+                        (0xF0         , 0x90 ..= 0xBF) |
+                        (0xF1 ..= 0xF3, 0x80 ..= 0xBF) |
+                        (0xF4         , 0x80 ..= 0x8F) => {}
                         _ => err!(Some(1))
                     }
                     if next!() & !CONT_MASK != TAG_CONT_U8 {
@@ -2722,7 +2722,10 @@ pub fn bytes(&self) -> Bytes {
     /// the original string slice, separated by any amount of whitespace.
     ///
     /// 'Whitespace' is defined according to the terms of the Unicode Derived
-    /// Core Property `White_Space`.
+    /// Core Property `White_Space`. If you only want to split on ASCII whitespace
+    /// instead, use [`split_ascii_whitespace`].
+    ///
+    /// [`split_ascii_whitespace`]: #method.split_ascii_whitespace
     ///
     /// # Examples
     ///
@@ -2756,6 +2759,53 @@ pub fn split_whitespace(&self) -> SplitWhitespace {
         SplitWhitespace { inner: self.split(IsWhitespace).filter(IsNotEmpty) }
     }
 
+    /// Split a string slice by ASCII whitespace.
+    ///
+    /// The iterator returned will return string slices that are sub-slices of
+    /// the original string slice, separated by any amount of ASCII whitespace.
+    ///
+    /// To split by Unicode `Whitespace` instead, use [`split_whitespace`].
+    ///
+    /// [`split_whitespace`]: #method.split_whitespace
+    ///
+    /// # Examples
+    ///
+    /// Basic usage:
+    ///
+    /// ```
+    /// #![feature(split_ascii_whitespace)]
+    /// let mut iter = "A few words".split_ascii_whitespace();
+    ///
+    /// assert_eq!(Some("A"), iter.next());
+    /// assert_eq!(Some("few"), iter.next());
+    /// assert_eq!(Some("words"), iter.next());
+    ///
+    /// assert_eq!(None, iter.next());
+    /// ```
+    ///
+    /// All kinds of ASCII whitespace are considered:
+    ///
+    /// ```
+    /// let mut iter = " Mary   had\ta little  \n\t lamb".split_whitespace();
+    /// assert_eq!(Some("Mary"), iter.next());
+    /// assert_eq!(Some("had"), iter.next());
+    /// assert_eq!(Some("a"), iter.next());
+    /// assert_eq!(Some("little"), iter.next());
+    /// assert_eq!(Some("lamb"), iter.next());
+    ///
+    /// assert_eq!(None, iter.next());
+    /// ```
+    #[unstable(feature = "split_ascii_whitespace", issue = "48656")]
+    #[inline]
+    pub fn split_ascii_whitespace(&self) -> SplitAsciiWhitespace {
+        let inner = self
+            .as_bytes()
+            .split(IsAsciiWhitespace)
+            .filter(IsNotEmpty)
+            .map(UnsafeBytesToStr);
+        SplitAsciiWhitespace { inner }
+    }
+
     /// An iterator over the lines of a string, as string slices.
     ///
     /// Lines are ended with either a newline (`\n`) or a carriage return with
@@ -3895,6 +3945,20 @@ pub struct SplitWhitespace<'a> {
     inner: Filter<Split<'a, IsWhitespace>, IsNotEmpty>,
 }
 
+/// An iterator over the non-ASCII-whitespace substrings of a string,
+/// separated by any amount of ASCII whitespace.
+///
+/// This struct is created by the [`split_ascii_whitespace`] method on [`str`].
+/// See its documentation for more.
+///
+/// [`split_ascii_whitespace`]: ../../std/primitive.str.html#method.split_ascii_whitespace
+/// [`str`]: ../../std/primitive.str.html
+#[unstable(feature = "split_ascii_whitespace", issue = "48656")]
+#[derive(Clone, Debug)]
+pub struct SplitAsciiWhitespace<'a> {
+    inner: Map<Filter<SliceSplit<'a, u8, IsAsciiWhitespace>, IsNotEmpty>, UnsafeBytesToStr>,
+}
+
 #[derive(Clone)]
 struct IsWhitespace;
 
@@ -3914,6 +3978,25 @@ extern "rust-call" fn call_mut(&mut self, arg: (char, )) -> bool {
     }
 }
 
+#[derive(Clone)]
+struct IsAsciiWhitespace;
+
+impl<'a> FnOnce<(&'a u8, )> for IsAsciiWhitespace {
+    type Output = bool;
+
+    #[inline]
+    extern "rust-call" fn call_once(mut self, arg: (&u8, )) -> bool {
+        self.call_mut(arg)
+    }
+}
+
+impl<'a> FnMut<(&'a u8, )> for IsAsciiWhitespace {
+    #[inline]
+    extern "rust-call" fn call_mut(&mut self, arg: (&u8, )) -> bool {
+        arg.0.is_ascii_whitespace()
+    }
+}
+
 #[derive(Clone)]
 struct IsNotEmpty;
 
@@ -3921,30 +4004,72 @@ impl<'a, 'b> FnOnce<(&'a &'b str, )> for IsNotEmpty {
     type Output = bool;
 
     #[inline]
-    extern "rust-call" fn call_once(mut self, arg: (&&str, )) -> bool {
+    extern "rust-call" fn call_once(mut self, arg: (&'a &'b str, )) -> bool {
         self.call_mut(arg)
     }
 }
 
 impl<'a, 'b> FnMut<(&'a &'b str, )> for IsNotEmpty {
     #[inline]
-    extern "rust-call" fn call_mut(&mut self, arg: (&&str, )) -> bool {
+    extern "rust-call" fn call_mut(&mut self, arg: (&'a &'b str, )) -> bool {
+        !arg.0.is_empty()
+    }
+}
+
+impl<'a, 'b> FnOnce<(&'a &'b [u8], )> for IsNotEmpty {
+    type Output = bool;
+
+    #[inline]
+    extern "rust-call" fn call_once(mut self, arg: (&'a &'b [u8], )) -> bool {
+        self.call_mut(arg)
+    }
+}
+
+impl<'a, 'b> FnMut<(&'a &'b [u8], )> for IsNotEmpty {
+    #[inline]
+    extern "rust-call" fn call_mut(&mut self, arg: (&'a &'b [u8], )) -> bool {
         !arg.0.is_empty()
     }
 }
 
+#[derive(Clone)]
+struct UnsafeBytesToStr;
+
+impl<'a> FnOnce<(&'a [u8], )> for UnsafeBytesToStr {
+    type Output = &'a str;
+
+    #[inline]
+    extern "rust-call" fn call_once(mut self, arg: (&'a [u8], )) -> &'a str {
+        self.call_mut(arg)
+    }
+}
+
+impl<'a> FnMut<(&'a [u8], )> for UnsafeBytesToStr {
+    #[inline]
+    extern "rust-call" fn call_mut(&mut self, arg: (&'a [u8], )) -> &'a str {
+        unsafe { from_utf8_unchecked(arg.0) }
+    }
+}
+
 
 #[stable(feature = "split_whitespace", since = "1.1.0")]
 impl<'a> Iterator for SplitWhitespace<'a> {
     type Item = &'a str;
 
+    #[inline]
     fn next(&mut self) -> Option<&'a str> {
         self.inner.next()
     }
+
+    #[inline]
+    fn size_hint(&self) -> (usize, Option<usize>) {
+        self.inner.size_hint()
+    }
 }
 
 #[stable(feature = "split_whitespace", since = "1.1.0")]
 impl<'a> DoubleEndedIterator for SplitWhitespace<'a> {
+    #[inline]
     fn next_back(&mut self) -> Option<&'a str> {
         self.inner.next_back()
     }
@@ -3953,6 +4078,32 @@ fn next_back(&mut self) -> Option<&'a str> {
 #[stable(feature = "fused", since = "1.26.0")]
 impl<'a> FusedIterator for SplitWhitespace<'a> {}
 
+#[unstable(feature = "split_ascii_whitespace", issue = "48656")]
+impl<'a> Iterator for SplitAsciiWhitespace<'a> {
+    type Item = &'a str;
+
+    #[inline]
+    fn next(&mut self) -> Option<&'a str> {
+        self.inner.next()
+    }
+
+    #[inline]
+    fn size_hint(&self) -> (usize, Option<usize>) {
+        self.inner.size_hint()
+    }
+}
+
+#[unstable(feature = "split_ascii_whitespace", issue = "48656")]
+impl<'a> DoubleEndedIterator for SplitAsciiWhitespace<'a> {
+    #[inline]
+    fn next_back(&mut self) -> Option<&'a str> {
+        self.inner.next_back()
+    }
+}
+
+#[unstable(feature = "split_ascii_whitespace", issue = "48656")]
+impl<'a> FusedIterator for SplitAsciiWhitespace<'a> {}
+
 /// An iterator of [`u16`] over the string encoded as UTF-16.
 ///
 /// [`u16`]: ../../std/primitive.u16.html
diff --git a/src/libcore/task.rs b/src/libcore/task.rs
deleted file mode 100644 (file)
index 1a6018f..0000000
+++ /dev/null
@@ -1,569 +0,0 @@
-// Copyright 2018 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.
-
-#![unstable(feature = "futures_api",
-            reason = "futures in libcore are unstable",
-            issue = "50547")]
-
-//! Types and Traits for working with asynchronous tasks.
-
-use fmt;
-use ptr::NonNull;
-use future::Future;
-use mem::PinMut;
-
-/// Indicates whether a value is available or if the current task has been
-/// scheduled to receive a wakeup instead.
-#[derive(Copy, Clone, Debug, Eq, PartialEq, Ord, PartialOrd, Hash)]
-pub enum Poll<T> {
-    /// Represents that a value is immediately ready.
-    Ready(T),
-
-    /// Represents that a value is not ready yet.
-    ///
-    /// When a function returns `Pending`, the function *must* also
-    /// ensure that the current task is scheduled to be awoken when
-    /// progress can be made.
-    Pending,
-}
-
-impl<T> Poll<T> {
-    /// Change the ready value of this `Poll` with the closure provided
-    pub fn map<U, F>(self, f: F) -> Poll<U>
-        where F: FnOnce(T) -> U
-    {
-        match self {
-            Poll::Ready(t) => Poll::Ready(f(t)),
-            Poll::Pending => Poll::Pending,
-        }
-    }
-
-    /// Returns whether this is `Poll::Ready`
-    pub fn is_ready(&self) -> bool {
-        match *self {
-            Poll::Ready(_) => true,
-            Poll::Pending => false,
-        }
-    }
-
-    /// Returns whether this is `Poll::Pending`
-    pub fn is_pending(&self) -> bool {
-        !self.is_ready()
-    }
-}
-
-impl<T, E> Poll<Result<T, E>> {
-    /// Change the success value of this `Poll` with the closure provided
-    pub fn map_ok<U, F>(self, f: F) -> Poll<Result<U, E>>
-        where F: FnOnce(T) -> U
-    {
-        match self {
-            Poll::Ready(Ok(t)) => Poll::Ready(Ok(f(t))),
-            Poll::Ready(Err(e)) => Poll::Ready(Err(e)),
-            Poll::Pending => Poll::Pending,
-        }
-    }
-
-    /// Change the error value of this `Poll` with the closure provided
-    pub fn map_err<U, F>(self, f: F) -> Poll<Result<T, U>>
-        where F: FnOnce(E) -> U
-    {
-        match self {
-            Poll::Ready(Ok(t)) => Poll::Ready(Ok(t)),
-            Poll::Ready(Err(e)) => Poll::Ready(Err(f(e))),
-            Poll::Pending => Poll::Pending,
-        }
-    }
-}
-
-impl<T> From<T> for Poll<T> {
-    fn from(t: T) -> Poll<T> {
-        Poll::Ready(t)
-    }
-}
-
-/// A `Waker` is a handle for waking up a task by notifying its executor that it
-/// is ready to be run.
-///
-/// This handle contains a trait object pointing to an instance of the `UnsafeWake`
-/// trait, allowing notifications to get routed through it.
-#[repr(transparent)]
-pub struct Waker {
-    inner: NonNull<UnsafeWake>,
-}
-
-unsafe impl Send for Waker {}
-unsafe impl Sync for Waker {}
-
-impl Waker {
-    /// Constructs a new `Waker` directly.
-    ///
-    /// Note that most code will not need to call this. Implementers of the
-    /// `UnsafeWake` trait will typically provide a wrapper that calls this
-    /// but you otherwise shouldn't call it directly.
-    ///
-    /// If you're working with the standard library then it's recommended to
-    /// use the `Waker::from` function instead which works with the safe
-    /// `Arc` type and the safe `Wake` trait.
-    #[inline]
-    pub unsafe fn new(inner: NonNull<UnsafeWake>) -> Self {
-        Waker { inner: inner }
-    }
-
-    /// Wake up the task associated with this `Waker`.
-    #[inline]
-    pub fn wake(&self) {
-        unsafe { self.inner.as_ref().wake() }
-    }
-
-    /// Returns whether or not this `Waker` and `other` awaken the same task.
-    ///
-    /// This function works on a best-effort basis, and may return false even
-    /// when the `Waker`s would awaken the same task. However, if this function
-    /// returns true, it is guaranteed that the `Waker`s will awaken the same
-    /// task.
-    ///
-    /// This function is primarily used for optimization purposes.
-    #[inline]
-    pub fn will_wake(&self, other: &Waker) -> bool {
-        self.inner == other.inner
-    }
-}
-
-impl Clone for Waker {
-    #[inline]
-    fn clone(&self) -> Self {
-        unsafe {
-            self.inner.as_ref().clone_raw()
-        }
-    }
-}
-
-impl fmt::Debug for Waker {
-    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        f.debug_struct("Waker")
-            .finish()
-    }
-}
-
-impl Drop for Waker {
-    #[inline]
-    fn drop(&mut self) {
-        unsafe {
-            self.inner.as_ref().drop_raw()
-        }
-    }
-}
-
-/// A `LocalWaker` is a handle for waking up a task by notifying its executor that it
-/// is ready to be run.
-///
-/// This is similar to the `Waker` type, but cannot be sent across threads.
-/// Task executors can use this type to implement more optimized singlethreaded wakeup
-/// behavior.
-#[repr(transparent)]
-pub struct LocalWaker {
-    inner: NonNull<UnsafeWake>,
-}
-
-impl !Send for LocalWaker {}
-impl !Sync for LocalWaker {}
-
-impl LocalWaker {
-    /// Constructs a new `LocalWaker` directly.
-    ///
-    /// Note that most code will not need to call this. Implementers of the
-    /// `UnsafeWake` trait will typically provide a wrapper that calls this
-    /// but you otherwise shouldn't call it directly.
-    ///
-    /// If you're working with the standard library then it's recommended to
-    /// use the `LocalWaker::from` function instead which works with the safe
-    /// `Rc` type and the safe `LocalWake` trait.
-    ///
-    /// For this function to be used safely, it must be sound to call `inner.wake_local()`
-    /// on the current thread.
-    #[inline]
-    pub unsafe fn new(inner: NonNull<UnsafeWake>) -> Self {
-        LocalWaker { inner: inner }
-    }
-
-    /// Wake up the task associated with this `LocalWaker`.
-    #[inline]
-    pub fn wake(&self) {
-        unsafe { self.inner.as_ref().wake_local() }
-    }
-
-    /// Returns whether or not this `LocalWaker` and `other` `LocalWaker` awaken the same task.
-    ///
-    /// This function works on a best-effort basis, and may return false even
-    /// when the `LocalWaker`s would awaken the same task. However, if this function
-    /// returns true, it is guaranteed that the `LocalWaker`s will awaken the same
-    /// task.
-    ///
-    /// This function is primarily used for optimization purposes.
-    #[inline]
-    pub fn will_wake(&self, other: &LocalWaker) -> bool {
-        self.inner == other.inner
-    }
-
-    /// Returns whether or not this `LocalWaker` and `other` `Waker` awaken the same task.
-    ///
-    /// This function works on a best-effort basis, and may return false even
-    /// when the `Waker`s would awaken the same task. However, if this function
-    /// returns true, it is guaranteed that the `LocalWaker`s will awaken the same
-    /// task.
-    ///
-    /// This function is primarily used for optimization purposes.
-    #[inline]
-    pub fn will_wake_nonlocal(&self, other: &Waker) -> bool {
-        self.inner == other.inner
-    }
-}
-
-impl From<LocalWaker> for Waker {
-    #[inline]
-    fn from(local_waker: LocalWaker) -> Self {
-        Waker { inner: local_waker.inner }
-    }
-}
-
-impl Clone for LocalWaker {
-    #[inline]
-    fn clone(&self) -> Self {
-        unsafe {
-            LocalWaker { inner: self.inner.as_ref().clone_raw().inner }
-        }
-    }
-}
-
-impl fmt::Debug for LocalWaker {
-    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        f.debug_struct("Waker")
-            .finish()
-    }
-}
-
-impl Drop for LocalWaker {
-    #[inline]
-    fn drop(&mut self) {
-        unsafe {
-            self.inner.as_ref().drop_raw()
-        }
-    }
-}
-
-/// An unsafe trait for implementing custom memory management for a `Waker` or `LocalWaker`.
-///
-/// A `Waker` conceptually is a cloneable trait object for `Wake`, and is
-/// most often essentially just `Arc<dyn Wake>`. However, in some contexts
-/// (particularly `no_std`), it's desirable to avoid `Arc` in favor of some
-/// custom memory management strategy. This trait is designed to allow for such
-/// customization.
-///
-/// When using `std`, a default implementation of the `UnsafeWake` trait is provided for
-/// `Arc<T>` where `T: Wake` and `Rc<T>` where `T: LocalWake`.
-///
-/// Although the methods on `UnsafeWake` take pointers rather than references,
-pub unsafe trait UnsafeWake: Send + Sync {
-    /// Creates a clone of this `UnsafeWake` and stores it behind a `Waker`.
-    ///
-    /// This function will create a new uniquely owned handle that under the
-    /// hood references the same notification instance. In other words calls
-    /// to `wake` on the returned handle should be equivalent to calls to
-    /// `wake` on this handle.
-    ///
-    /// # Unsafety
-    ///
-    /// This function is unsafe to call because it's asserting the `UnsafeWake`
-    /// value is in a consistent state, i.e. hasn't been dropped.
-    unsafe fn clone_raw(&self) -> Waker;
-
-    /// Drops this instance of `UnsafeWake`, deallocating resources
-    /// associated with it.
-    ///
-    /// FIXME(cramertj)
-    /// This method is intended to have a signature such as:
-    ///
-    /// ```ignore (not-a-doctest)
-    /// fn drop_raw(self: *mut Self);
-    /// ```
-    ///
-    /// Unfortunately in Rust today that signature is not object safe.
-    /// Nevertheless it's recommended to implement this function *as if* that
-    /// were its signature. As such it is not safe to call on an invalid
-    /// pointer, nor is the validity of the pointer guaranteed after this
-    /// function returns.
-    ///
-    /// # Unsafety
-    ///
-    /// This function is unsafe to call because it's asserting the `UnsafeWake`
-    /// value is in a consistent state, i.e. hasn't been dropped.
-    unsafe fn drop_raw(&self);
-
-    /// Indicates that the associated task is ready to make progress and should
-    /// be `poll`ed.
-    ///
-    /// Executors generally maintain a queue of "ready" tasks; `wake` should place
-    /// the associated task onto this queue.
-    ///
-    /// # Panics
-    ///
-    /// Implementations should avoid panicking, but clients should also be prepared
-    /// for panics.
-    ///
-    /// # Unsafety
-    ///
-    /// This function is unsafe to call because it's asserting the `UnsafeWake`
-    /// value is in a consistent state, i.e. hasn't been dropped.
-    unsafe fn wake(&self);
-
-    /// Indicates that the associated task is ready to make progress and should
-    /// be `poll`ed. This function is the same as `wake`, but can only be called
-    /// from the thread that this `UnsafeWake` is "local" to. This allows for
-    /// implementors to provide specialized wakeup behavior specific to the current
-    /// thread. This function is called by `LocalWaker::wake`.
-    ///
-    /// Executors generally maintain a queue of "ready" tasks; `wake_local` should place
-    /// the associated task onto this queue.
-    ///
-    /// # Panics
-    ///
-    /// Implementations should avoid panicking, but clients should also be prepared
-    /// for panics.
-    ///
-    /// # Unsafety
-    ///
-    /// This function is unsafe to call because it's asserting the `UnsafeWake`
-    /// value is in a consistent state, i.e. hasn't been dropped, and that the
-    /// `UnsafeWake` hasn't moved from the thread on which it was created.
-    unsafe fn wake_local(&self) {
-        self.wake()
-    }
-}
-
-/// Information about the currently-running task.
-///
-/// Contexts are always tied to the stack, since they are set up specifically
-/// when performing a single `poll` step on a task.
-pub struct Context<'a> {
-    local_waker: &'a LocalWaker,
-    executor: &'a mut Executor,
-}
-
-impl<'a> fmt::Debug for Context<'a> {
-    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        f.debug_struct("Context")
-            .finish()
-    }
-}
-
-impl<'a> Context<'a> {
-    /// Create a new task `Context` with the provided `local_waker`, `waker`, and `executor`.
-    #[inline]
-    pub fn new(local_waker: &'a LocalWaker, executor: &'a mut Executor) -> Context<'a> {
-        Context {
-            local_waker,
-            executor,
-        }
-    }
-
-    /// Get the `LocalWaker` associated with the current task.
-    #[inline]
-    pub fn local_waker(&self) -> &'a LocalWaker {
-        self.local_waker
-    }
-
-    /// Get the `Waker` associated with the current task.
-    #[inline]
-    pub fn waker(&self) -> &'a Waker {
-        unsafe { &*(self.local_waker as *const LocalWaker as *const Waker) }
-    }
-
-    /// Get the default executor associated with this task.
-    ///
-    /// This method is useful primarily if you want to explicitly handle
-    /// spawn failures.
-    #[inline]
-    pub fn executor(&mut self) -> &mut Executor {
-        self.executor
-    }
-
-    /// Produce a context like the current one, but using the given waker instead.
-    ///
-    /// This advanced method is primarily used when building "internal
-    /// schedulers" within a task, where you want to provide some customized
-    /// wakeup logic.
-    #[inline]
-    pub fn with_waker<'b>(&'b mut self, local_waker: &'b LocalWaker) -> Context<'b> {
-        Context {
-            local_waker,
-            executor: self.executor,
-        }
-    }
-
-    /// Produce a context like the current one, but using the given executor
-    /// instead.
-    ///
-    /// This advanced method is primarily used when building "internal
-    /// schedulers" within a task.
-    #[inline]
-    pub fn with_executor<'b, E>(&'b mut self, executor: &'b mut E) -> Context<'b>
-        where E: Executor
-    {
-        Context {
-            local_waker: self.local_waker,
-            executor: executor,
-        }
-    }
-}
-
-/// A task executor.
-///
-/// A *task* is a `()`-producing async value that runs at the top level, and will
-/// be `poll`ed until completion. It's also the unit at which wake-up
-/// notifications occur. Executors, such as thread pools, allow tasks to be
-/// spawned and are responsible for putting tasks onto ready queues when
-/// they are woken up, and polling them when they are ready.
-pub trait Executor {
-    /// Spawn the given task, polling it until completion.
-    ///
-    /// # Errors
-    ///
-    /// The executor may be unable to spawn tasks, either because it has
-    /// been shut down or is resource-constrained.
-    fn spawn_obj(&mut self, task: TaskObj) -> Result<(), SpawnObjError>;
-
-    /// Determine whether the executor is able to spawn new tasks.
-    ///
-    /// # Returns
-    ///
-    /// An `Ok` return means the executor is *likely* (but not guaranteed)
-    /// to accept a subsequent spawn attempt. Likewise, an `Err` return
-    /// means that `spawn` is likely, but not guaranteed, to yield an error.
-    #[inline]
-    fn status(&self) -> Result<(), SpawnErrorKind> {
-        Ok(())
-    }
-}
-
-/// A custom trait object for polling tasks, roughly akin to
-/// `Box<Future<Output = ()> + Send>`.
-pub struct TaskObj {
-    ptr: *mut (),
-    poll_fn: unsafe fn(*mut (), &mut Context) -> Poll<()>,
-    drop_fn: unsafe fn(*mut ()),
-}
-
-impl fmt::Debug for TaskObj {
-    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        f.debug_struct("TaskObj")
-            .finish()
-    }
-}
-
-unsafe impl Send for TaskObj {}
-
-/// A custom implementation of a task trait object for `TaskObj`, providing
-/// a hand-rolled vtable.
-///
-/// This custom representation is typically used only in `no_std` contexts,
-/// where the default `Box`-based implementation is not available.
-///
-/// The implementor must guarantee that it is safe to call `poll` repeatedly (in
-/// a non-concurrent fashion) with the result of `into_raw` until `drop` is
-/// called.
-pub unsafe trait UnsafeTask: Send + 'static {
-    /// Convert a owned instance into a (conceptually owned) void pointer.
-    fn into_raw(self) -> *mut ();
-
-    /// Poll the task represented by the given void pointer.
-    ///
-    /// # Safety
-    ///
-    /// The trait implementor must guarantee that it is safe to repeatedly call
-    /// `poll` with the result of `into_raw` until `drop` is called; such calls
-    /// are not, however, allowed to race with each other or with calls to `drop`.
-    unsafe fn poll(task: *mut (), cx: &mut Context) -> Poll<()>;
-
-    /// Drops the task represented by the given void pointer.
-    ///
-    /// # Safety
-    ///
-    /// The trait implementor must guarantee that it is safe to call this
-    /// function once per `into_raw` invocation; that call cannot race with
-    /// other calls to `drop` or `poll`.
-    unsafe fn drop(task: *mut ());
-}
-
-impl TaskObj {
-    /// Create a `TaskObj` from a custom trait object representation.
-    #[inline]
-    pub fn new<T: UnsafeTask>(t: T) -> TaskObj {
-        TaskObj {
-            ptr: t.into_raw(),
-            poll_fn: T::poll,
-            drop_fn: T::drop,
-        }
-    }
-}
-
-impl Future for TaskObj {
-    type Output = ();
-
-    #[inline]
-    fn poll(self: PinMut<Self>, cx: &mut Context) -> Poll<()> {
-        unsafe {
-            (self.poll_fn)(self.ptr, cx)
-        }
-    }
-}
-
-impl Drop for TaskObj {
-    fn drop(&mut self) {
-        unsafe {
-            (self.drop_fn)(self.ptr)
-        }
-    }
-}
-
-/// Provides the reason that an executor was unable to spawn.
-pub struct SpawnErrorKind {
-    _hidden: (),
-}
-
-impl fmt::Debug for SpawnErrorKind {
-    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        f.debug_tuple("SpawnErrorKind")
-            .field(&"shutdown")
-            .finish()
-    }
-}
-
-impl SpawnErrorKind {
-    /// Spawning is failing because the executor has been shut down.
-    pub fn shutdown() -> SpawnErrorKind {
-        SpawnErrorKind { _hidden: () }
-    }
-
-    /// Check whether this error is the `shutdown` error.
-    pub fn is_shutdown(&self) -> bool {
-        true
-    }
-}
-
-/// The result of a failed spawn
-#[derive(Debug)]
-pub struct SpawnObjError {
-    /// The kind of error
-    pub kind: SpawnErrorKind,
-
-    /// The task for which spawning was attempted
-    pub task: TaskObj,
-}
diff --git a/src/libcore/task/context.rs b/src/libcore/task/context.rs
new file mode 100644 (file)
index 0000000..c69d452
--- /dev/null
@@ -0,0 +1,92 @@
+// Copyright 2018 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.
+
+#![unstable(feature = "futures_api",
+            reason = "futures in libcore are unstable",
+            issue = "50547")]
+
+use fmt;
+use super::{Executor, Waker, LocalWaker};
+
+/// Information about the currently-running task.
+///
+/// Contexts are always tied to the stack, since they are set up specifically
+/// when performing a single `poll` step on a task.
+pub struct Context<'a> {
+    local_waker: &'a LocalWaker,
+    executor: &'a mut Executor,
+}
+
+impl<'a> fmt::Debug for Context<'a> {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        f.debug_struct("Context")
+            .finish()
+    }
+}
+
+impl<'a> Context<'a> {
+    /// Create a new task `Context` with the provided `local_waker`, `waker`, and `executor`.
+    #[inline]
+    pub fn new(local_waker: &'a LocalWaker, executor: &'a mut Executor) -> Context<'a> {
+        Context {
+            local_waker,
+            executor,
+        }
+    }
+
+    /// Get the `LocalWaker` associated with the current task.
+    #[inline]
+    pub fn local_waker(&self) -> &'a LocalWaker {
+        self.local_waker
+    }
+
+    /// Get the `Waker` associated with the current task.
+    #[inline]
+    pub fn waker(&self) -> &'a Waker {
+        unsafe { &*(self.local_waker as *const LocalWaker as *const Waker) }
+    }
+
+    /// Get the default executor associated with this task.
+    ///
+    /// This method is useful primarily if you want to explicitly handle
+    /// spawn failures.
+    #[inline]
+    pub fn executor(&mut self) -> &mut Executor {
+        self.executor
+    }
+
+    /// Produce a context like the current one, but using the given waker instead.
+    ///
+    /// This advanced method is primarily used when building "internal
+    /// schedulers" within a task, where you want to provide some customized
+    /// wakeup logic.
+    #[inline]
+    pub fn with_waker<'b>(&'b mut self, local_waker: &'b LocalWaker) -> Context<'b> {
+        Context {
+            local_waker,
+            executor: self.executor,
+        }
+    }
+
+    /// Produce a context like the current one, but using the given executor
+    /// instead.
+    ///
+    /// This advanced method is primarily used when building "internal
+    /// schedulers" within a task.
+    #[inline]
+    pub fn with_executor<'b, E>(&'b mut self, executor: &'b mut E) -> Context<'b>
+        where E: Executor
+    {
+        Context {
+            local_waker: self.local_waker,
+            executor: executor,
+        }
+    }
+}
diff --git a/src/libcore/task/executor.rs b/src/libcore/task/executor.rs
new file mode 100644 (file)
index 0000000..73bf80d
--- /dev/null
@@ -0,0 +1,90 @@
+// Copyright 2018 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.
+
+#![unstable(feature = "futures_api",
+            reason = "futures in libcore are unstable",
+            issue = "50547")]
+
+use fmt;
+use super::{TaskObj, LocalTaskObj};
+
+/// A task executor.
+///
+/// A *task* is a `()`-producing async value that runs at the top level, and will
+/// be `poll`ed until completion. It's also the unit at which wake-up
+/// notifications occur. Executors, such as thread pools, allow tasks to be
+/// spawned and are responsible for putting tasks onto ready queues when
+/// they are woken up, and polling them when they are ready.
+pub trait Executor {
+    /// Spawn the given task, polling it until completion.
+    ///
+    /// # Errors
+    ///
+    /// The executor may be unable to spawn tasks, either because it has
+    /// been shut down or is resource-constrained.
+    fn spawn_obj(&mut self, task: TaskObj) -> Result<(), SpawnObjError>;
+
+    /// Determine whether the executor is able to spawn new tasks.
+    ///
+    /// # Returns
+    ///
+    /// An `Ok` return means the executor is *likely* (but not guaranteed)
+    /// to accept a subsequent spawn attempt. Likewise, an `Err` return
+    /// means that `spawn` is likely, but not guaranteed, to yield an error.
+    #[inline]
+    fn status(&self) -> Result<(), SpawnErrorKind> {
+        Ok(())
+    }
+}
+
+/// Provides the reason that an executor was unable to spawn.
+pub struct SpawnErrorKind {
+    _hidden: (),
+}
+
+impl fmt::Debug for SpawnErrorKind {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        f.debug_tuple("SpawnErrorKind")
+            .field(&"shutdown")
+            .finish()
+    }
+}
+
+impl SpawnErrorKind {
+    /// Spawning is failing because the executor has been shut down.
+    pub fn shutdown() -> SpawnErrorKind {
+        SpawnErrorKind { _hidden: () }
+    }
+
+    /// Check whether this error is the `shutdown` error.
+    pub fn is_shutdown(&self) -> bool {
+        true
+    }
+}
+
+/// The result of a failed spawn
+#[derive(Debug)]
+pub struct SpawnObjError {
+    /// The kind of error
+    pub kind: SpawnErrorKind,
+
+    /// The task for which spawning was attempted
+    pub task: TaskObj,
+}
+
+/// The result of a failed spawn
+#[derive(Debug)]
+pub struct SpawnLocalObjError {
+    /// The kind of error
+    pub kind: SpawnErrorKind,
+
+    /// The task for which spawning was attempted
+    pub task: LocalTaskObj,
+}
diff --git a/src/libcore/task/mod.rs b/src/libcore/task/mod.rs
new file mode 100644 (file)
index 0000000..d167a37
--- /dev/null
@@ -0,0 +1,32 @@
+// Copyright 2018 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.
+
+#![unstable(feature = "futures_api",
+            reason = "futures in libcore are unstable",
+            issue = "50547")]
+
+//! Types and Traits for working with asynchronous tasks.
+
+mod context;
+pub use self::context::Context;
+
+mod executor;
+pub use self::executor::{
+  Executor, SpawnErrorKind, SpawnObjError, SpawnLocalObjError
+};
+
+mod poll;
+pub use self::poll::Poll;
+
+mod task;
+pub use self::task::{TaskObj, LocalTaskObj, UnsafeTask};
+
+mod wake;
+pub use self::wake::{Waker, LocalWaker, UnsafeWake};
diff --git a/src/libcore/task/poll.rs b/src/libcore/task/poll.rs
new file mode 100644 (file)
index 0000000..10c954f
--- /dev/null
@@ -0,0 +1,83 @@
+// Copyright 2018 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.
+
+#![unstable(feature = "futures_api",
+            reason = "futures in libcore are unstable",
+            issue = "50547")]
+
+/// Indicates whether a value is available or if the current task has been
+/// scheduled to receive a wakeup instead.
+#[derive(Copy, Clone, Debug, Eq, PartialEq, Ord, PartialOrd, Hash)]
+pub enum Poll<T> {
+    /// Represents that a value is immediately ready.
+    Ready(T),
+
+    /// Represents that a value is not ready yet.
+    ///
+    /// When a function returns `Pending`, the function *must* also
+    /// ensure that the current task is scheduled to be awoken when
+    /// progress can be made.
+    Pending,
+}
+
+impl<T> Poll<T> {
+    /// Change the ready value of this `Poll` with the closure provided
+    pub fn map<U, F>(self, f: F) -> Poll<U>
+        where F: FnOnce(T) -> U
+    {
+        match self {
+            Poll::Ready(t) => Poll::Ready(f(t)),
+            Poll::Pending => Poll::Pending,
+        }
+    }
+
+    /// Returns whether this is `Poll::Ready`
+    pub fn is_ready(&self) -> bool {
+        match *self {
+            Poll::Ready(_) => true,
+            Poll::Pending => false,
+        }
+    }
+
+    /// Returns whether this is `Poll::Pending`
+    pub fn is_pending(&self) -> bool {
+        !self.is_ready()
+    }
+}
+
+impl<T, E> Poll<Result<T, E>> {
+    /// Change the success value of this `Poll` with the closure provided
+    pub fn map_ok<U, F>(self, f: F) -> Poll<Result<U, E>>
+        where F: FnOnce(T) -> U
+    {
+        match self {
+            Poll::Ready(Ok(t)) => Poll::Ready(Ok(f(t))),
+            Poll::Ready(Err(e)) => Poll::Ready(Err(e)),
+            Poll::Pending => Poll::Pending,
+        }
+    }
+
+    /// Change the error value of this `Poll` with the closure provided
+    pub fn map_err<U, F>(self, f: F) -> Poll<Result<T, U>>
+        where F: FnOnce(E) -> U
+    {
+        match self {
+            Poll::Ready(Ok(t)) => Poll::Ready(Ok(t)),
+            Poll::Ready(Err(e)) => Poll::Ready(Err(f(e))),
+            Poll::Pending => Poll::Pending,
+        }
+    }
+}
+
+impl<T> From<T> for Poll<T> {
+    fn from(t: T) -> Poll<T> {
+        Poll::Ready(t)
+    }
+}
diff --git a/src/libcore/task/task.rs b/src/libcore/task/task.rs
new file mode 100644 (file)
index 0000000..c5a4187
--- /dev/null
@@ -0,0 +1,142 @@
+// Copyright 2018 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.
+
+#![unstable(feature = "futures_api",
+            reason = "futures in libcore are unstable",
+            issue = "50547")]
+
+use fmt;
+use future::Future;
+use mem::PinMut;
+use super::{Context, Poll};
+
+/// A custom trait object for polling tasks, roughly akin to
+/// `Box<Future<Output = ()>>`.
+/// Contrary to `TaskObj`, `LocalTaskObj` does not have a `Send` bound.
+pub struct LocalTaskObj {
+    ptr: *mut (),
+    poll_fn: unsafe fn(*mut (), &mut Context) -> Poll<()>,
+    drop_fn: unsafe fn(*mut ()),
+}
+
+impl LocalTaskObj {
+    /// Create a `LocalTaskObj` from a custom trait object representation.
+    #[inline]
+    pub fn new<T: UnsafeTask>(t: T) -> LocalTaskObj {
+        LocalTaskObj {
+            ptr: t.into_raw(),
+            poll_fn: T::poll,
+            drop_fn: T::drop,
+        }
+    }
+
+    /// Converts the `LocalTaskObj` into a `TaskObj`
+    /// To make this operation safe one has to ensure that the `UnsafeTask`
+    /// instance from which this `LocalTaskObj` was created actually implements
+    /// `Send`.
+    pub unsafe fn as_task_obj(self) -> TaskObj {
+        TaskObj(self)
+    }
+}
+
+impl fmt::Debug for LocalTaskObj {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        f.debug_struct("LocalTaskObj")
+            .finish()
+    }
+}
+
+impl From<TaskObj> for LocalTaskObj {
+    fn from(task: TaskObj) -> LocalTaskObj {
+        task.0
+    }
+}
+
+impl Future for LocalTaskObj {
+    type Output = ();
+
+    #[inline]
+    fn poll(self: PinMut<Self>, cx: &mut Context) -> Poll<()> {
+        unsafe {
+            (self.poll_fn)(self.ptr, cx)
+        }
+    }
+}
+
+impl Drop for LocalTaskObj {
+    fn drop(&mut self) {
+        unsafe {
+            (self.drop_fn)(self.ptr)
+        }
+    }
+}
+
+/// A custom trait object for polling tasks, roughly akin to
+/// `Box<Future<Output = ()> + Send>`.
+pub struct TaskObj(LocalTaskObj);
+
+unsafe impl Send for TaskObj {}
+
+impl TaskObj {
+    /// Create a `TaskObj` from a custom trait object representation.
+    #[inline]
+    pub fn new<T: UnsafeTask + Send>(t: T) -> TaskObj {
+        TaskObj(LocalTaskObj::new(t))
+    }
+}
+
+impl fmt::Debug for TaskObj {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        f.debug_struct("TaskObj")
+            .finish()
+    }
+}
+
+impl Future for TaskObj {
+    type Output = ();
+
+    #[inline]
+    fn poll(self: PinMut<Self>, cx: &mut Context) -> Poll<()> {
+        let pinned_field = unsafe { PinMut::map_unchecked(self, |x| &mut x.0) };
+        pinned_field.poll(cx)
+    }
+}
+
+/// A custom implementation of a task trait object for `TaskObj`, providing
+/// a hand-rolled vtable.
+///
+/// This custom representation is typically used only in `no_std` contexts,
+/// where the default `Box`-based implementation is not available.
+///
+/// The implementor must guarantee that it is safe to call `poll` repeatedly (in
+/// a non-concurrent fashion) with the result of `into_raw` until `drop` is
+/// called.
+pub unsafe trait UnsafeTask: 'static {
+    /// Convert a owned instance into a (conceptually owned) void pointer.
+    fn into_raw(self) -> *mut ();
+
+    /// Poll the task represented by the given void pointer.
+    ///
+    /// # Safety
+    ///
+    /// The trait implementor must guarantee that it is safe to repeatedly call
+    /// `poll` with the result of `into_raw` until `drop` is called; such calls
+    /// are not, however, allowed to race with each other or with calls to `drop`.
+    unsafe fn poll(task: *mut (), cx: &mut Context) -> Poll<()>;
+
+    /// Drops the task represented by the given void pointer.
+    ///
+    /// # Safety
+    ///
+    /// The trait implementor must guarantee that it is safe to call this
+    /// function once per `into_raw` invocation; that call cannot race with
+    /// other calls to `drop` or `poll`.
+    unsafe fn drop(task: *mut ());
+}
diff --git a/src/libcore/task/wake.rs b/src/libcore/task/wake.rs
new file mode 100644 (file)
index 0000000..4fd45be
--- /dev/null
@@ -0,0 +1,275 @@
+// Copyright 2018 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.
+
+#![unstable(feature = "futures_api",
+            reason = "futures in libcore are unstable",
+            issue = "50547")]
+
+use fmt;
+use ptr::NonNull;
+
+/// A `Waker` is a handle for waking up a task by notifying its executor that it
+/// is ready to be run.
+///
+/// This handle contains a trait object pointing to an instance of the `UnsafeWake`
+/// trait, allowing notifications to get routed through it.
+#[repr(transparent)]
+pub struct Waker {
+    inner: NonNull<UnsafeWake>,
+}
+
+unsafe impl Send for Waker {}
+unsafe impl Sync for Waker {}
+
+impl Waker {
+    /// Constructs a new `Waker` directly.
+    ///
+    /// Note that most code will not need to call this. Implementers of the
+    /// `UnsafeWake` trait will typically provide a wrapper that calls this
+    /// but you otherwise shouldn't call it directly.
+    ///
+    /// If you're working with the standard library then it's recommended to
+    /// use the `Waker::from` function instead which works with the safe
+    /// `Arc` type and the safe `Wake` trait.
+    #[inline]
+    pub unsafe fn new(inner: NonNull<UnsafeWake>) -> Self {
+        Waker { inner: inner }
+    }
+
+    /// Wake up the task associated with this `Waker`.
+    #[inline]
+    pub fn wake(&self) {
+        unsafe { self.inner.as_ref().wake() }
+    }
+
+    /// Returns whether or not this `Waker` and `other` awaken the same task.
+    ///
+    /// This function works on a best-effort basis, and may return false even
+    /// when the `Waker`s would awaken the same task. However, if this function
+    /// returns true, it is guaranteed that the `Waker`s will awaken the same
+    /// task.
+    ///
+    /// This function is primarily used for optimization purposes.
+    #[inline]
+    pub fn will_wake(&self, other: &Waker) -> bool {
+        self.inner == other.inner
+    }
+}
+
+impl Clone for Waker {
+    #[inline]
+    fn clone(&self) -> Self {
+        unsafe {
+            self.inner.as_ref().clone_raw()
+        }
+    }
+}
+
+impl fmt::Debug for Waker {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        f.debug_struct("Waker")
+            .finish()
+    }
+}
+
+impl Drop for Waker {
+    #[inline]
+    fn drop(&mut self) {
+        unsafe {
+            self.inner.as_ref().drop_raw()
+        }
+    }
+}
+
+/// A `LocalWaker` is a handle for waking up a task by notifying its executor that it
+/// is ready to be run.
+///
+/// This is similar to the `Waker` type, but cannot be sent across threads.
+/// Task executors can use this type to implement more optimized singlethreaded wakeup
+/// behavior.
+#[repr(transparent)]
+pub struct LocalWaker {
+    inner: NonNull<UnsafeWake>,
+}
+
+impl !Send for LocalWaker {}
+impl !Sync for LocalWaker {}
+
+impl LocalWaker {
+    /// Constructs a new `LocalWaker` directly.
+    ///
+    /// Note that most code will not need to call this. Implementers of the
+    /// `UnsafeWake` trait will typically provide a wrapper that calls this
+    /// but you otherwise shouldn't call it directly.
+    ///
+    /// If you're working with the standard library then it's recommended to
+    /// use the `LocalWaker::from` function instead which works with the safe
+    /// `Rc` type and the safe `LocalWake` trait.
+    ///
+    /// For this function to be used safely, it must be sound to call `inner.wake_local()`
+    /// on the current thread.
+    #[inline]
+    pub unsafe fn new(inner: NonNull<UnsafeWake>) -> Self {
+        LocalWaker { inner: inner }
+    }
+
+    /// Wake up the task associated with this `LocalWaker`.
+    #[inline]
+    pub fn wake(&self) {
+        unsafe { self.inner.as_ref().wake_local() }
+    }
+
+    /// Returns whether or not this `LocalWaker` and `other` `LocalWaker` awaken the same task.
+    ///
+    /// This function works on a best-effort basis, and may return false even
+    /// when the `LocalWaker`s would awaken the same task. However, if this function
+    /// returns true, it is guaranteed that the `LocalWaker`s will awaken the same
+    /// task.
+    ///
+    /// This function is primarily used for optimization purposes.
+    #[inline]
+    pub fn will_wake(&self, other: &LocalWaker) -> bool {
+        self.inner == other.inner
+    }
+
+    /// Returns whether or not this `LocalWaker` and `other` `Waker` awaken the same task.
+    ///
+    /// This function works on a best-effort basis, and may return false even
+    /// when the `Waker`s would awaken the same task. However, if this function
+    /// returns true, it is guaranteed that the `LocalWaker`s will awaken the same
+    /// task.
+    ///
+    /// This function is primarily used for optimization purposes.
+    #[inline]
+    pub fn will_wake_nonlocal(&self, other: &Waker) -> bool {
+        self.inner == other.inner
+    }
+}
+
+impl From<LocalWaker> for Waker {
+    #[inline]
+    fn from(local_waker: LocalWaker) -> Self {
+        Waker { inner: local_waker.inner }
+    }
+}
+
+impl Clone for LocalWaker {
+    #[inline]
+    fn clone(&self) -> Self {
+        unsafe {
+            LocalWaker { inner: self.inner.as_ref().clone_raw().inner }
+        }
+    }
+}
+
+impl fmt::Debug for LocalWaker {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        f.debug_struct("Waker")
+            .finish()
+    }
+}
+
+impl Drop for LocalWaker {
+    #[inline]
+    fn drop(&mut self) {
+        unsafe {
+            self.inner.as_ref().drop_raw()
+        }
+    }
+}
+
+/// An unsafe trait for implementing custom memory management for a `Waker` or `LocalWaker`.
+///
+/// A `Waker` conceptually is a cloneable trait object for `Wake`, and is
+/// most often essentially just `Arc<dyn Wake>`. However, in some contexts
+/// (particularly `no_std`), it's desirable to avoid `Arc` in favor of some
+/// custom memory management strategy. This trait is designed to allow for such
+/// customization.
+///
+/// When using `std`, a default implementation of the `UnsafeWake` trait is provided for
+/// `Arc<T>` where `T: Wake` and `Rc<T>` where `T: LocalWake`.
+///
+/// Although the methods on `UnsafeWake` take pointers rather than references,
+pub unsafe trait UnsafeWake: Send + Sync {
+    /// Creates a clone of this `UnsafeWake` and stores it behind a `Waker`.
+    ///
+    /// This function will create a new uniquely owned handle that under the
+    /// hood references the same notification instance. In other words calls
+    /// to `wake` on the returned handle should be equivalent to calls to
+    /// `wake` on this handle.
+    ///
+    /// # Unsafety
+    ///
+    /// This function is unsafe to call because it's asserting the `UnsafeWake`
+    /// value is in a consistent state, i.e. hasn't been dropped.
+    unsafe fn clone_raw(&self) -> Waker;
+
+    /// Drops this instance of `UnsafeWake`, deallocating resources
+    /// associated with it.
+    ///
+    /// FIXME(cramertj)
+    /// This method is intended to have a signature such as:
+    ///
+    /// ```ignore (not-a-doctest)
+    /// fn drop_raw(self: *mut Self);
+    /// ```
+    ///
+    /// Unfortunately in Rust today that signature is not object safe.
+    /// Nevertheless it's recommended to implement this function *as if* that
+    /// were its signature. As such it is not safe to call on an invalid
+    /// pointer, nor is the validity of the pointer guaranteed after this
+    /// function returns.
+    ///
+    /// # Unsafety
+    ///
+    /// This function is unsafe to call because it's asserting the `UnsafeWake`
+    /// value is in a consistent state, i.e. hasn't been dropped.
+    unsafe fn drop_raw(&self);
+
+    /// Indicates that the associated task is ready to make progress and should
+    /// be `poll`ed.
+    ///
+    /// Executors generally maintain a queue of "ready" tasks; `wake` should place
+    /// the associated task onto this queue.
+    ///
+    /// # Panics
+    ///
+    /// Implementations should avoid panicking, but clients should also be prepared
+    /// for panics.
+    ///
+    /// # Unsafety
+    ///
+    /// This function is unsafe to call because it's asserting the `UnsafeWake`
+    /// value is in a consistent state, i.e. hasn't been dropped.
+    unsafe fn wake(&self);
+
+    /// Indicates that the associated task is ready to make progress and should
+    /// be `poll`ed. This function is the same as `wake`, but can only be called
+    /// from the thread that this `UnsafeWake` is "local" to. This allows for
+    /// implementors to provide specialized wakeup behavior specific to the current
+    /// thread. This function is called by `LocalWaker::wake`.
+    ///
+    /// Executors generally maintain a queue of "ready" tasks; `wake_local` should place
+    /// the associated task onto this queue.
+    ///
+    /// # Panics
+    ///
+    /// Implementations should avoid panicking, but clients should also be prepared
+    /// for panics.
+    ///
+    /// # Unsafety
+    ///
+    /// This function is unsafe to call because it's asserting the `UnsafeWake`
+    /// value is in a consistent state, i.e. hasn't been dropped, and that the
+    /// `UnsafeWake` hasn't moved from the thread on which it was created.
+    unsafe fn wake_local(&self) {
+        self.wake()
+    }
+}
index fcd79222e1699882aee57f3f54528967dbbb646e..7981567067dad3c1f241d175c39474e29b819cfc 100644 (file)
@@ -60,8 +60,8 @@ fn test_binary_search() {
     assert_eq!(b.binary_search(&0), Err(0));
     assert_eq!(b.binary_search(&1), Ok(0));
     assert_eq!(b.binary_search(&2), Err(1));
-    assert!(match b.binary_search(&3) { Ok(1...3) => true, _ => false });
-    assert!(match b.binary_search(&3) { Ok(1...3) => true, _ => false });
+    assert!(match b.binary_search(&3) { Ok(1..=3) => true, _ => false });
+    assert!(match b.binary_search(&3) { Ok(1..=3) => true, _ => false });
     assert_eq!(b.binary_search(&4), Err(4));
     assert_eq!(b.binary_search(&5), Err(4));
     assert_eq!(b.binary_search(&6), Err(4));
index df139965753a6fe6bdb6b665208d445f49b085bf..466f28f0ef0aab4182b4b433cb03315724094266 100644 (file)
@@ -161,6 +161,20 @@ fn checked_div() {
     assert_eq!(Duration::new(2, 0).checked_div(0), None);
 }
 
+#[test]
+fn correct_sum() {
+    let durations = [
+        Duration::new(1, 999_999_999),
+        Duration::new(2, 999_999_999),
+        Duration::new(0, 999_999_999),
+        Duration::new(0, 999_999_999),
+        Duration::new(0, 999_999_999),
+        Duration::new(5, 0),
+    ];
+    let sum = durations.iter().sum::<Duration>();
+    assert_eq!(sum, Duration::new(1+2+5+4, 1_000_000_000 - 5));
+}
+
 #[test]
 fn debug_formatting_extreme_values() {
     assert_eq!(
index 563eea0066d59abdb10f5fdcd1bbe72c31a62c24..25721b7fcecbb8f93a317df1f99ddf4dcb4548ba 100644 (file)
@@ -524,17 +524,47 @@ fn div_assign(&mut self, rhs: u32) {
     }
 }
 
+macro_rules! sum_durations {
+    ($iter:expr) => {{
+        let mut total_secs: u64 = 0;
+        let mut total_nanos: u64 = 0;
+
+        for entry in $iter {
+            total_secs = total_secs
+                .checked_add(entry.secs)
+                .expect("overflow in iter::sum over durations");
+            total_nanos = match total_nanos.checked_add(entry.nanos as u64) {
+                Some(n) => n,
+                None => {
+                    total_secs = total_secs
+                        .checked_add(total_nanos / NANOS_PER_SEC as u64)
+                        .expect("overflow in iter::sum over durations");
+                    (total_nanos % NANOS_PER_SEC as u64) + entry.nanos as u64
+                }
+            };
+        }
+        total_secs = total_secs
+            .checked_add(total_nanos / NANOS_PER_SEC as u64)
+            .expect("overflow in iter::sum over durations");
+        total_nanos = total_nanos % NANOS_PER_SEC as u64;
+        Duration {
+            secs: total_secs,
+            nanos: total_nanos as u32,
+        }
+    }};
+}
+
 #[stable(feature = "duration_sum", since = "1.16.0")]
 impl Sum for Duration {
     fn sum<I: Iterator<Item=Duration>>(iter: I) -> Duration {
-        iter.fold(Duration::new(0, 0), |a, b| a + b)
+        sum_durations!(iter)
     }
 }
 
 #[stable(feature = "duration_sum", since = "1.16.0")]
 impl<'a> Sum<&'a Duration> for Duration {
     fn sum<I: Iterator<Item=&'a Duration>>(iter: I) -> Duration {
-        iter.fold(Duration::new(0, 0), |a, b| a + *b)
+        sum_durations!(iter)
     }
 }
 
index 02046edd218ef73fd83232737ad70259ac7647f1..e14a86eb954f0824ec8c14cddfdb3be96b996088 100644 (file)
@@ -616,6 +616,7 @@ fn allow_internal_unstable(&self, reason: CompilerDesugaringKind, span: Span) ->
             format: codemap::CompilerDesugaring(reason),
             allow_internal_unstable: true,
             allow_internal_unsafe: false,
+            local_inner_macros: false,
             edition: codemap::hygiene::default_edition(),
         });
         span.with_ctxt(SyntaxContext::empty().apply_mark(mark))
@@ -1074,11 +1075,15 @@ fn lower_generic_arg(&mut self,
                         -> hir::GenericArg {
         match arg {
             ast::GenericArg::Lifetime(lt) => GenericArg::Lifetime(self.lower_lifetime(&lt)),
-            ast::GenericArg::Type(ty) => GenericArg::Type(self.lower_ty(&ty, itctx)),
+            ast::GenericArg::Type(ty) => GenericArg::Type(self.lower_ty_direct(&ty, itctx)),
         }
     }
 
     fn lower_ty(&mut self, t: &Ty, itctx: ImplTraitContext) -> P<hir::Ty> {
+        P(self.lower_ty_direct(t, itctx))
+    }
+
+    fn lower_ty_direct(&mut self, t: &Ty, itctx: ImplTraitContext) -> hir::Ty {
         let kind = match t.node {
             TyKind::Infer => hir::TyInfer,
             TyKind::Err => hir::TyErr,
@@ -1115,10 +1120,10 @@ fn lower_ty(&mut self, t: &Ty, itctx: ImplTraitContext) -> P<hir::Ty> {
             ),
             TyKind::Never => hir::TyNever,
             TyKind::Tup(ref tys) => {
-                hir::TyTup(tys.iter().map(|ty| self.lower_ty(ty, itctx)).collect())
+                hir::TyTup(tys.iter().map(|ty| self.lower_ty_direct(ty, itctx)).collect())
             }
             TyKind::Paren(ref ty) => {
-                return self.lower_ty(ty, itctx);
+                return self.lower_ty_direct(ty, itctx);
             }
             TyKind::Path(ref qself, ref path) => {
                 let id = self.lower_node_id(t.id);
@@ -1228,12 +1233,12 @@ fn lower_ty(&mut self, t: &Ty, itctx: ImplTraitContext) -> P<hir::Ty> {
         };
 
         let LoweredNodeId { node_id, hir_id } = self.lower_node_id(t.id);
-        P(hir::Ty {
+        hir::Ty {
             id: node_id,
             node: kind,
             span: t.span,
             hir_id,
-        })
+        }
     }
 
     fn lower_existential_impl_trait(
@@ -1636,7 +1641,7 @@ fn lower_qpath(
             // e.g. `Vec` in `Vec::new` or `<I as Iterator>::Item` in
             // `<I as Iterator>::Item::default`.
             let new_id = self.next_id();
-            self.ty_path(new_id, p.span, hir::QPath::Resolved(qself, path))
+            P(self.ty_path(new_id, p.span, hir::QPath::Resolved(qself, path)))
         };
 
         // Anything after the base path are associated "extensions",
@@ -1667,7 +1672,7 @@ fn lower_qpath(
 
             // Wrap the associated extension in another type node.
             let new_id = self.next_id();
-            ty = self.ty_path(new_id, p.span, qpath);
+            ty = P(self.ty_path(new_id, p.span, qpath));
         }
 
         // Should've returned in the for loop above.
@@ -1802,10 +1807,10 @@ fn lower_parenthesized_parameter_data(
             |this| {
                 const DISALLOWED: ImplTraitContext = ImplTraitContext::Disallowed;
                 let &ParenthesisedArgs { ref inputs, ref output, span } = data;
-                let inputs = inputs.iter().map(|ty| this.lower_ty(ty, DISALLOWED)).collect();
+                let inputs = inputs.iter().map(|ty| this.lower_ty_direct(ty, DISALLOWED)).collect();
                 let mk_tup = |this: &mut Self, tys, span| {
                     let LoweredNodeId { node_id, hir_id } = this.next_id();
-                    P(hir::Ty { node: hir::TyTup(tys), id: node_id, hir_id, span })
+                    hir::Ty { node: hir::TyTup(tys), id: node_id, hir_id, span }
                 };
 
                 (
@@ -1818,7 +1823,7 @@ fn lower_parenthesized_parameter_data(
                                 ty: output
                                     .as_ref()
                                     .map(|ty| this.lower_ty(&ty, DISALLOWED))
-                                    .unwrap_or_else(|| mk_tup(this, hir::HirVec::new(), span)),
+                                    .unwrap_or_else(|| P(mk_tup(this, hir::HirVec::new(), span))),
                                 span: output.as_ref().map_or(span, |ty| ty.span),
                             }
                         ],
@@ -1894,9 +1899,9 @@ fn lower_fn_decl(
             .iter()
             .map(|arg| {
                 if let Some(def_id) = fn_def_id {
-                    self.lower_ty(&arg.ty, ImplTraitContext::Universal(def_id))
+                    self.lower_ty_direct(&arg.ty, ImplTraitContext::Universal(def_id))
                 } else {
-                    self.lower_ty(&arg.ty, ImplTraitContext::Disallowed)
+                    self.lower_ty_direct(&arg.ty, ImplTraitContext::Disallowed)
                 }
             })
             .collect::<HirVec<_>>();
@@ -1936,7 +1941,7 @@ fn lower_fn_decl(
     // fn_def_id: DefId of the parent function. Used to create child impl trait definition.
     fn lower_async_fn_ret_ty(
         &mut self,
-        inputs: &[P<hir::Ty>],
+        inputs: &[hir::Ty],
         output: &FunctionRetTy,
         fn_def_id: DefId,
     ) -> hir::FunctionRetTy {
@@ -3356,7 +3361,7 @@ fn lower_pat(&mut self, p: &Pat) -> P<hir::Pat> {
             PatKind::Ref(ref inner, mutbl) => {
                 hir::PatKind::Ref(self.lower_pat(inner), self.lower_mutability(mutbl))
             }
-            PatKind::Range(ref e1, ref e2, ref end) => hir::PatKind::Range(
+            PatKind::Range(ref e1, ref e2, Spanned { node: ref end, .. }) => hir::PatKind::Range(
                 P(self.lower_expr(e1)),
                 P(self.lower_expr(e2)),
                 self.lower_range_end(end),
@@ -3536,12 +3541,22 @@ fn lower_expr(&mut self, e: &Expr) -> hir::Expr {
                         this.expr_block(block, ThinVec::new())
                     })
                 })
-            },
+            }
             ExprKind::Closure(
-                capture_clause, asyncness, movability, ref decl, ref body, fn_decl_span) =>
-            {
-                self.with_new_scopes(|this| {
-                    if let IsAsync::Async(async_closure_node_id) = asyncness {
+                capture_clause, asyncness, movability, ref decl, ref body, fn_decl_span
+            ) => {
+                if let IsAsync::Async(async_closure_node_id) = asyncness {
+                    let outer_decl = FnDecl {
+                        inputs: decl.inputs.clone(),
+                        output: FunctionRetTy::Default(fn_decl_span),
+                        variadic: false,
+                    };
+                    // We need to lower the declaration outside the new scope, because we
+                    // have to conserve the state of being inside a loop condition for the
+                    // closure argument types.
+                    let fn_decl = self.lower_fn_decl(&outer_decl, None, false, false);
+
+                    self.with_new_scopes(|this| {
                         // FIXME(cramertj) allow `async` non-`move` closures with
                         if capture_clause == CaptureBy::Ref &&
                             !decl.inputs.is_empty()
@@ -3561,11 +3576,6 @@ fn lower_expr(&mut self, e: &Expr) -> hir::Expr {
 
                         // Transform `async |x: u8| -> X { ... }` into
                         // `|x: u8| future_from_generator(|| -> X { ... })`
-                        let outer_decl = FnDecl {
-                            inputs: decl.inputs.clone(),
-                            output: FunctionRetTy::Default(fn_decl_span),
-                            variadic: false,
-                        };
                         let body_id = this.lower_body(Some(&outer_decl), |this| {
                             let async_ret_ty = if let FunctionRetTy::Ty(ty) = &decl.output {
                                 Some(&**ty)
@@ -3579,12 +3589,17 @@ fn lower_expr(&mut self, e: &Expr) -> hir::Expr {
                         });
                         hir::ExprClosure(
                             this.lower_capture_clause(capture_clause),
-                            this.lower_fn_decl(&outer_decl, None, false, false),
+                            fn_decl,
                             body_id,
                             fn_decl_span,
                             None,
                         )
-                    } else {
+                    })
+                } else {
+                    // Lower outside new scope to preserve `is_in_loop_condition`.
+                    let fn_decl = self.lower_fn_decl(decl, None, false, false);
+
+                    self.with_new_scopes(|this| {
                         let mut is_generator = false;
                         let body_id = this.lower_body(Some(decl), |this| {
                             let e = this.lower_expr(body);
@@ -3618,13 +3633,13 @@ fn lower_expr(&mut self, e: &Expr) -> hir::Expr {
                         };
                         hir::ExprClosure(
                             this.lower_capture_clause(capture_clause),
-                            this.lower_fn_decl(decl, None, false, false),
+                            fn_decl,
                             body_id,
                             fn_decl_span,
                             generator_option,
                         )
-                    }
-                })
+                    })
+                }
             }
             ExprKind::Block(ref blk, opt_label) => {
                 hir::ExprBlock(self.lower_block(blk,
@@ -3651,7 +3666,7 @@ fn lower_expr(&mut self, e: &Expr) -> hir::Expr {
                 let e1 = self.lower_expr(e1);
                 let e2 = self.lower_expr(e2);
                 let ty_path = P(self.std_path(span, &["ops", "RangeInclusive"], None, false));
-                let ty = self.ty_path(id, span, hir::QPath::Resolved(None, ty_path));
+                let ty = P(self.ty_path(id, span, hir::QPath::Resolved(None, ty_path)));
                 let new_seg = P(hir::PathSegment::from_name(Symbol::intern("new")));
                 let new_path = hir::QPath::TypeRelative(ty, new_seg);
                 let new = P(self.expr(span, hir::ExprPath(new_path), ThinVec::new()));
@@ -4539,7 +4554,7 @@ fn std_path(
             .resolve_str_path(span, self.crate_root, components, params, is_value)
     }
 
-    fn ty_path(&mut self, id: LoweredNodeId, span: Span, qpath: hir::QPath) -> P<hir::Ty> {
+    fn ty_path(&mut self, id: LoweredNodeId, span: Span, qpath: hir::QPath) -> hir::Ty {
         let mut id = id;
         let node = match qpath {
             hir::QPath::Resolved(None, path) => {
@@ -4564,12 +4579,12 @@ fn ty_path(&mut self, id: LoweredNodeId, span: Span, qpath: hir::QPath) -> P<hir
             }
             _ => hir::TyPath(qpath),
         };
-        P(hir::Ty {
+        hir::Ty {
             id: id.node_id,
             hir_id: id.hir_id,
             node,
             span,
-        })
+        }
     }
 
     /// Invoked to create the lifetime argument for a type `&T`
index 5f6921c7a87cc860d430b12f20f6fb10fae0474b..68ff74a0e51129860bc09c7d06e044602a9b1f9c 100644 (file)
@@ -383,7 +383,7 @@ pub fn with_generic_args<F, R>(&self, f: F) -> R
 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
 pub enum GenericArg {
     Lifetime(Lifetime),
-    Type(P<Ty>),
+    Type(Ty),
 }
 
 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
@@ -412,7 +412,7 @@ pub fn is_empty(&self) -> bool {
         self.args.is_empty() && self.bindings.is_empty() && !self.parenthesized
     }
 
-    pub fn inputs(&self) -> &[P<Ty>] {
+    pub fn inputs(&self) -> &[Ty] {
         if self.parenthesized {
             for arg in &self.args {
                 match arg {
@@ -1658,7 +1658,7 @@ pub enum Ty_ {
     /// The never type (`!`)
     TyNever,
     /// A tuple (`(A, B, C, D,...)`)
-    TyTup(HirVec<P<Ty>>),
+    TyTup(HirVec<Ty>),
     /// A path to a type definition (`module::module::...::Type`), or an
     /// associated type, e.g. `<Vec<T> as Trait>::Type` or `<T>::Target`.
     ///
@@ -1719,7 +1719,7 @@ pub struct Arg {
 /// Represents the header (not the body) of a function declaration
 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
 pub struct FnDecl {
-    pub inputs: HirVec<P<Ty>>,
+    pub inputs: HirVec<Ty>,
     pub output: FunctionRetTy,
     pub variadic: bool,
     /// True if this function has an `self`, `&self` or `&mut self` receiver
index f56f4e12e7a02b9b16ffa34c2f9119ad0c492235..2a3b1ce6a36a5075fcf33ff85b6224cfe705baf0 100644 (file)
@@ -52,7 +52,8 @@ pub fn to_hex(&self) -> String {
     pub fn encode_opaque(&self, encoder: &mut Encoder) -> EncodeResult {
         let bytes: [u8; 16] = unsafe { mem::transmute([self.0.to_le(), self.1.to_le()]) };
 
-        encoder.emit_raw_bytes(&bytes)
+        encoder.emit_raw_bytes(&bytes);
+        Ok(())
     }
 
     pub fn decode_opaque<'a>(decoder: &mut Decoder<'a>) -> Result<Fingerprint, String> {
@@ -92,7 +93,7 @@ impl serialize::UseSpecializedEncodable for Fingerprint { }
 
 impl serialize::UseSpecializedDecodable for Fingerprint { }
 
-impl<'a> serialize::SpecializedEncoder<Fingerprint> for serialize::opaque::Encoder<'a> {
+impl serialize::SpecializedEncoder<Fingerprint> for serialize::opaque::Encoder {
     fn specialized_encode(&mut self, f: &Fingerprint) -> Result<(), Self::Error> {
         f.encode_opaque(self)
     }
index 935bc4c8c6d8c532e017942150cc4ad53fe38d56..790ef7029638060037b9bb6d88d77a0e184ef80d 100644 (file)
@@ -395,6 +395,7 @@ fn hash_token<'a, 'gcx, W: StableHasherResult>(
     format,
     allow_internal_unstable,
     allow_internal_unsafe,
+    local_inner_macros,
     edition
 });
 
index 1164c332330bc30d6bd0ad71532099517c1da44d..ef11cc0f4932e6094a238799cddd30d317ceca6a 100644 (file)
@@ -29,7 +29,7 @@
 //! For a more detailed look at what is happening here, check
 //! out the [chapter in the rustc guide][c].
 //!
-//! [c]: https://rust-lang-nursery.github.io/rustc-guide/traits-canonicalization.html
+//! [c]: https://rust-lang-nursery.github.io/rustc-guide/traits/canonicalization.html
 
 use infer::{InferCtxt, InferOk, InferResult, RegionVariableOrigin, TypeVariableOrigin};
 use rustc_data_structures::indexed_vec::Idx;
@@ -274,7 +274,7 @@ pub fn fresh_inference_var_for_canonical_var(
     /// To get a good understanding of what is happening here, check
     /// out the [chapter in the rustc guide][c].
     ///
-    /// [c]: https://rust-lang-nursery.github.io/rustc-guide/traits-canonicalization.html#processing-the-canonicalized-query-result
+    /// [c]: https://rust-lang-nursery.github.io/rustc-guide/traits/canonicalization.html#processing-the-canonicalized-query-result
     pub fn instantiate_query_result<R>(
         &self,
         cause: &ObligationCause<'tcx>,
@@ -458,7 +458,7 @@ fn unify_canonical_vars(
     /// To get a good understanding of what is happening here, check
     /// out the [chapter in the rustc guide][c].
     ///
-    /// [c]: https://rust-lang-nursery.github.io/rustc-guide/traits-canonicalization.html#canonicalizing-the-query
+    /// [c]: https://rust-lang-nursery.github.io/rustc-guide/traits/canonicalization.html#canonicalizing-the-query
     pub fn canonicalize_query<V>(&self, value: &V) -> (V::Canonicalized, CanonicalVarValues<'tcx>)
     where
         V: Canonicalize<'gcx, 'tcx>,
@@ -497,7 +497,7 @@ pub fn canonicalize_query<V>(&self, value: &V) -> (V::Canonicalized, CanonicalVa
     /// To get a good understanding of what is happening here, check
     /// out the [chapter in the rustc guide][c].
     ///
-    /// [c]: https://rust-lang-nursery.github.io/rustc-guide/traits-canonicalization.html#canonicalizing-the-query-result
+    /// [c]: https://rust-lang-nursery.github.io/rustc-guide/traits/canonicalization.html#canonicalizing-the-query-result
     pub fn canonicalize_response<V>(
         &self,
         value: &V,
index 680d445a1bcfcc6b169d405998178bc598df5250..43ed80b474ad5ebe4e2002f8d443012d5d57601e 100644 (file)
@@ -583,7 +583,7 @@ fn region_vars_confined_to_snapshot(&self,
     /// For more information about how skolemization for HRTBs works, see
     /// the [rustc guide].
     ///
-    /// [rustc guide]: https://rust-lang-nursery.github.io/rustc-guide/trait-hrtb.html
+    /// [rustc guide]: https://rust-lang-nursery.github.io/rustc-guide/traits/hrtb.html
     pub fn skolemize_late_bound_regions<T>(&self,
                                            binder: &ty::Binder<T>)
                                            -> (T, SkolemizationMap<'tcx>)
index 0086aed3e7c975b94b41d8b2646139b55be56dca..6e1c4191173bc8e44fae22c6b17f37b5d69cc46e 100644 (file)
@@ -3,7 +3,7 @@
 > WARNING: This README is obsolete and will be removed soon! For
 > more info on how the current borrowck works, see the [rustc guide].
 
-[rustc guide]: https://rust-lang-nursery.github.io/rustc-guide/mir-borrowck.html
+[rustc guide]: https://rust-lang-nursery.github.io/rustc-guide/mir/borrowck.html
 
 ## Terminology
 
index 07b87e2012dde775df98f09d6c502d3ec8a8aed0..61603e6dee6866e7081232760b29c16fbfd73ee4 100644 (file)
@@ -3,7 +3,7 @@
 > WARNING: This README is obsolete and will be removed soon! For
 > more info on how the current borrowck works, see the [rustc guide].
 
-[rustc guide]: https://rust-lang-nursery.github.io/rustc-guide/mir-borrowck.html
+[rustc guide]: https://rust-lang-nursery.github.io/rustc-guide/mir/borrowck.html
 
 ## Terminology
 
index 1f8c7f0064ed9570381249c26b95f9ec2d3194bb..a6bbd93750575cb3093e3f34ff7236f0a9ffc994 100644 (file)
     "detects name collision with an existing but unstable method"
 }
 
+declare_lint! {
+    pub IRREFUTABLE_LET_PATTERNS,
+    Deny,
+    "detects irrefutable patterns in if-let and while-let statements"
+}
+
 declare_lint! {
     pub UNUSED_LABELS,
     Allow,
@@ -361,6 +367,7 @@ fn get_lints(&self) -> LintArray {
             BARE_TRAIT_OBJECTS,
             ABSOLUTE_PATHS_NOT_STARTING_WITH_CRATE,
             UNSTABLE_NAME_COLLISIONS,
+            IRREFUTABLE_LET_PATTERNS,
             DUPLICATE_ASSOCIATED_TYPE_BINDINGS,
             DUPLICATE_MACRO_EXPORTS,
             INTRA_DOC_LINK_RESOLUTION_FAILURE,
index 824930a7eb00007766e052d0992bbaf0ff494032..c9874f510f7314653e795c09d2e8e88ec88fa912 100644 (file)
@@ -178,10 +178,10 @@ fn push_pass<P: LintPass + ?Sized + 'static>(&mut self,
                                         sess: Option<&Session>,
                                         from_plugin: bool,
                                         pass: &Box<P>) {
-        for &lint in pass.get_lints() {
-            self.lints.push((*lint, from_plugin));
+        for lint in pass.get_lints() {
+            self.lints.push((lint, from_plugin));
 
-            let id = LintId::of(*lint);
+            let id = LintId::of(lint);
             if self.by_name.insert(lint.name_lower(), Id(id)).is_some() {
                 let msg = format!("duplicate specification of lint {}", lint.name_lower());
                 match (sess, from_plugin) {
index 9338e235c534df2f9fd7afd9a9a5d72e47023606..bff596e21e53abd5cba6fcc8082241d97654f2a4 100644 (file)
@@ -35,7 +35,7 @@
 
 use errors::{DiagnosticBuilder, DiagnosticId};
 use hir::def_id::{CrateNum, LOCAL_CRATE};
-use hir::intravisit::{self, FnKind};
+use hir::intravisit;
 use hir;
 use lint::builtin::BuiltinLintDiagnostics;
 use session::{Session, DiagnosticMessageId};
@@ -123,12 +123,11 @@ macro_rules! declare_lint {
 #[macro_export]
 macro_rules! lint_array {
     ($( $lint:expr ),* $(,)?) => {{
-         static ARRAY: LintArray = &[ $( &$lint ),* ];
-         ARRAY
+        vec![$($lint),*]
     }}
 }
 
-pub type LintArray = &'static [&'static &'static Lint];
+pub type LintArray = Vec<&'static Lint>;
 
 pub trait LintPass {
     /// Get descriptions of the lints this `LintPass` object can emit.
@@ -140,6 +139,80 @@ pub trait LintPass {
     fn get_lints(&self) -> LintArray;
 }
 
+#[macro_export]
+macro_rules! late_lint_methods {
+    ($macro:path, $args:tt, [$hir:tt]) => (
+        $macro!($args, [$hir], [
+            fn check_body(a: &$hir hir::Body);
+            fn check_body_post(a: &$hir hir::Body);
+            fn check_name(a: Span, b: ast::Name);
+            fn check_crate(a: &$hir hir::Crate);
+            fn check_crate_post(a: &$hir hir::Crate);
+            fn check_mod(a: &$hir hir::Mod, b: Span, c: ast::NodeId);
+            fn check_mod_post(a: &$hir hir::Mod, b: Span, c: ast::NodeId);
+            fn check_foreign_item(a: &$hir hir::ForeignItem);
+            fn check_foreign_item_post(a: &$hir hir::ForeignItem);
+            fn check_item(a: &$hir hir::Item);
+            fn check_item_post(a: &$hir hir::Item);
+            fn check_local(a: &$hir hir::Local);
+            fn check_block(a: &$hir hir::Block);
+            fn check_block_post(a: &$hir hir::Block);
+            fn check_stmt(a: &$hir hir::Stmt);
+            fn check_arm(a: &$hir hir::Arm);
+            fn check_pat(a: &$hir hir::Pat);
+            fn check_decl(a: &$hir hir::Decl);
+            fn check_expr(a: &$hir hir::Expr);
+            fn check_expr_post(a: &$hir hir::Expr);
+            fn check_ty(a: &$hir hir::Ty);
+            fn check_generic_param(a: &$hir hir::GenericParam);
+            fn check_generics(a: &$hir hir::Generics);
+            fn check_where_predicate(a: &$hir hir::WherePredicate);
+            fn check_poly_trait_ref(a: &$hir hir::PolyTraitRef, b: hir::TraitBoundModifier);
+            fn check_fn(
+                a: hir::intravisit::FnKind<$hir>,
+                b: &$hir hir::FnDecl,
+                c: &$hir hir::Body,
+                d: Span,
+                e: ast::NodeId);
+            fn check_fn_post(
+                a: hir::intravisit::FnKind<$hir>,
+                b: &$hir hir::FnDecl,
+                c: &$hir hir::Body,
+                d: Span,
+                e: ast::NodeId
+            );
+            fn check_trait_item(a: &$hir hir::TraitItem);
+            fn check_trait_item_post(a: &$hir hir::TraitItem);
+            fn check_impl_item(a: &$hir hir::ImplItem);
+            fn check_impl_item_post(a: &$hir hir::ImplItem);
+            fn check_struct_def(
+                a: &$hir hir::VariantData,
+                b: ast::Name,
+                c: &$hir hir::Generics,
+                d: ast::NodeId
+            );
+            fn check_struct_def_post(
+                a: &$hir hir::VariantData,
+                b: ast::Name,
+                c: &$hir hir::Generics,
+                d: ast::NodeId
+            );
+            fn check_struct_field(a: &$hir hir::StructField);
+            fn check_variant(a: &$hir hir::Variant, b: &$hir hir::Generics);
+            fn check_variant_post(a: &$hir hir::Variant, b: &$hir hir::Generics);
+            fn check_lifetime(a: &$hir hir::Lifetime);
+            fn check_path(a: &$hir hir::Path, b: ast::NodeId);
+            fn check_attribute(a: &$hir ast::Attribute);
+
+            /// Called when entering a syntax node that can have lint attributes such
+            /// as `#[allow(...)]`. Called with *all* the attributes of that node.
+            fn enter_lint_attrs(a: &$hir [ast::Attribute]);
+
+            /// Counterpart to `enter_lint_attrs`.
+            fn exit_lint_attrs(a: &$hir [ast::Attribute]);
+        ]);
+    )
+}
 
 /// Trait for types providing lint checks.
 ///
@@ -149,90 +222,67 @@ pub trait LintPass {
 //
 // FIXME: eliminate the duplication with `Visitor`. But this also
 // contains a few lint-specific methods with no equivalent in `Visitor`.
-pub trait LateLintPass<'a, 'tcx>: LintPass {
-    fn check_body(&mut self, _: &LateContext, _: &'tcx hir::Body) { }
-    fn check_body_post(&mut self, _: &LateContext, _: &'tcx hir::Body) { }
-    fn check_name(&mut self, _: &LateContext, _: Span, _: ast::Name) { }
-    fn check_crate(&mut self, _: &LateContext<'a, 'tcx>, _: &'tcx hir::Crate) { }
-    fn check_crate_post(&mut self, _: &LateContext<'a, 'tcx>, _: &'tcx hir::Crate) { }
-    fn check_mod(&mut self,
-                 _: &LateContext<'a, 'tcx>,
-                 _: &'tcx hir::Mod,
-                 _: Span,
-                 _: ast::NodeId) { }
-    fn check_mod_post(&mut self,
-                      _: &LateContext<'a, 'tcx>,
-                      _: &'tcx hir::Mod,
-                      _: Span,
-                      _: ast::NodeId) { }
-    fn check_foreign_item(&mut self, _: &LateContext<'a, 'tcx>, _: &'tcx hir::ForeignItem) { }
-    fn check_foreign_item_post(&mut self, _: &LateContext<'a, 'tcx>, _: &'tcx hir::ForeignItem) { }
-    fn check_item(&mut self, _: &LateContext<'a, 'tcx>, _: &'tcx hir::Item) { }
-    fn check_item_post(&mut self, _: &LateContext<'a, 'tcx>, _: &'tcx hir::Item) { }
-    fn check_local(&mut self, _: &LateContext<'a, 'tcx>, _: &'tcx hir::Local) { }
-    fn check_block(&mut self, _: &LateContext<'a, 'tcx>, _: &'tcx hir::Block) { }
-    fn check_block_post(&mut self, _: &LateContext<'a, 'tcx>, _: &'tcx hir::Block) { }
-    fn check_stmt(&mut self, _: &LateContext<'a, 'tcx>, _: &'tcx hir::Stmt) { }
-    fn check_arm(&mut self, _: &LateContext<'a, 'tcx>, _: &'tcx hir::Arm) { }
-    fn check_pat(&mut self, _: &LateContext<'a, 'tcx>, _: &'tcx hir::Pat) { }
-    fn check_decl(&mut self, _: &LateContext<'a, 'tcx>, _: &'tcx hir::Decl) { }
-    fn check_expr(&mut self, _: &LateContext<'a, 'tcx>, _: &'tcx hir::Expr) { }
-    fn check_expr_post(&mut self, _: &LateContext<'a, 'tcx>, _: &'tcx hir::Expr) { }
-    fn check_ty(&mut self, _: &LateContext<'a, 'tcx>, _: &'tcx hir::Ty) { }
-    fn check_generic_param(&mut self, _: &LateContext<'a, 'tcx>, _: &'tcx hir::GenericParam) { }
-    fn check_generics(&mut self, _: &LateContext<'a, 'tcx>, _: &'tcx hir::Generics) { }
-    fn check_where_predicate(&mut self, _: &LateContext<'a, 'tcx>, _: &'tcx hir::WherePredicate) { }
-    fn check_poly_trait_ref(&mut self, _: &LateContext<'a, 'tcx>, _: &'tcx hir::PolyTraitRef,
-                            _: hir::TraitBoundModifier) { }
-    fn check_fn(&mut self,
-                _: &LateContext<'a, 'tcx>,
-                _: FnKind<'tcx>,
-                _: &'tcx hir::FnDecl,
-                _: &'tcx hir::Body,
-                _: Span,
-                _: ast::NodeId) { }
-    fn check_fn_post(&mut self,
-                     _: &LateContext<'a, 'tcx>,
-                     _: FnKind<'tcx>,
-                     _: &'tcx hir::FnDecl,
-                     _: &'tcx hir::Body,
-                     _: Span,
-                     _: ast::NodeId) { }
-    fn check_trait_item(&mut self, _: &LateContext<'a, 'tcx>, _: &'tcx hir::TraitItem) { }
-    fn check_trait_item_post(&mut self, _: &LateContext<'a, 'tcx>, _: &'tcx hir::TraitItem) { }
-    fn check_impl_item(&mut self, _: &LateContext<'a, 'tcx>, _: &'tcx hir::ImplItem) { }
-    fn check_impl_item_post(&mut self, _: &LateContext<'a, 'tcx>, _: &'tcx hir::ImplItem) { }
-    fn check_struct_def(&mut self,
-                        _: &LateContext<'a, 'tcx>,
-                        _: &'tcx hir::VariantData,
-                        _: ast::Name,
-                        _: &'tcx hir::Generics,
-                        _: ast::NodeId) { }
-    fn check_struct_def_post(&mut self,
-                             _: &LateContext<'a, 'tcx>,
-                             _: &'tcx hir::VariantData,
-                             _: ast::Name,
-                             _: &'tcx hir::Generics,
-                             _: ast::NodeId) { }
-    fn check_struct_field(&mut self, _: &LateContext<'a, 'tcx>, _: &'tcx hir::StructField) { }
-    fn check_variant(&mut self,
-                     _: &LateContext<'a, 'tcx>,
-                     _: &'tcx hir::Variant,
-                     _: &'tcx hir::Generics) { }
-    fn check_variant_post(&mut self,
-                          _: &LateContext<'a, 'tcx>,
-                          _: &'tcx hir::Variant,
-                          _: &'tcx hir::Generics) { }
-    fn check_lifetime(&mut self, _: &LateContext<'a, 'tcx>, _: &'tcx hir::Lifetime) { }
-    fn check_path(&mut self, _: &LateContext<'a, 'tcx>, _: &'tcx hir::Path, _: ast::NodeId) { }
-    fn check_attribute(&mut self, _: &LateContext<'a, 'tcx>, _: &'tcx ast::Attribute) { }
 
-    /// Called when entering a syntax node that can have lint attributes such
-    /// as `#[allow(...)]`. Called with *all* the attributes of that node.
-    fn enter_lint_attrs(&mut self, _: &LateContext<'a, 'tcx>, _: &'tcx [ast::Attribute]) { }
+macro_rules! expand_lint_pass_methods {
+    ($context:ty, [$($(#[$attr:meta])* fn $name:ident($($param:ident: $arg:ty),*);)*]) => (
+        $(#[inline(always)] fn $name(&mut self, $context, $(_: $arg),*) {})*
+    )
+}
 
-    /// Counterpart to `enter_lint_attrs`.
-    fn exit_lint_attrs(&mut self, _: &LateContext<'a, 'tcx>, _: &'tcx [ast::Attribute]) { }
+macro_rules! declare_late_lint_pass {
+    ([], [$hir:tt], [$($methods:tt)*]) => (
+        pub trait LateLintPass<'a, $hir>: LintPass {
+            expand_lint_pass_methods!(&LateContext<'a, $hir>, [$($methods)*]);
+        }
+    )
+}
+
+late_lint_methods!(declare_late_lint_pass, [], ['tcx]);
+
+#[macro_export]
+macro_rules! expand_combined_late_lint_pass_method {
+    ([$($passes:ident),*], $self: ident, $name: ident, $params:tt) => ({
+        $($self.$passes.$name $params;)*
+    })
+}
+
+#[macro_export]
+macro_rules! expand_combined_late_lint_pass_methods {
+    ($passes:tt, [$($(#[$attr:meta])* fn $name:ident($($param:ident: $arg:ty),*);)*]) => (
+        $(fn $name(&mut self, context: &LateContext<'a, 'tcx>, $($param: $arg),*) {
+            expand_combined_late_lint_pass_method!($passes, self, $name, (context, $($param),*));
+        })*
+    )
+}
+
+#[macro_export]
+macro_rules! declare_combined_late_lint_pass {
+    ([$name:ident, [$($passes:ident: $constructor:expr,)*]], [$hir:tt], $methods:tt) => (
+        #[allow(non_snake_case)]
+        struct $name {
+            $($passes: $passes,)*
+        }
+
+        impl $name {
+            fn new() -> Self {
+                Self {
+                    $($passes: $constructor,)*
+                }
+            }
+        }
+
+        impl<'a, 'tcx> LateLintPass<'a, 'tcx> for $name {
+            expand_combined_late_lint_pass_methods!([$($passes),*], $methods);
+        }
+
+        impl LintPass for $name {
+            fn get_lints(&self) -> LintArray {
+                let mut lints = Vec::new();
+                $(lints.extend_from_slice(&self.$passes.get_lints());)*
+                lints
+            }
+        }
+    )
 }
 
 pub trait EarlyLintPass: LintPass {
index e478f493647728e9cb50886c7bbba443d54fcc6f..c7249c0aa20c881ce5fb87cc113bc17d8720b928 100644 (file)
@@ -14,7 +14,7 @@
 //! For more information about how MIR-based region-checking works,
 //! see the [rustc guide].
 //!
-//! [rustc guide]: https://rust-lang-nursery.github.io/rustc-guide/mir-borrowck.html
+//! [rustc guide]: https://rust-lang-nursery.github.io/rustc-guide/mir/borrowck.html
 
 use ich::{StableHashingContext, NodeIdHashingMode};
 use util::nodemap::{FxHashMap, FxHashSet};
index efb3eecd691f2dc47d3930af098c0b49166ff05b..076c3c5f17df892f207cd3a7f704a6675fafa972 100644 (file)
@@ -1792,7 +1792,7 @@ fn visit_segment_args(
 
     fn visit_fn_like_elision(
         &mut self,
-        inputs: &'tcx [P<hir::Ty>],
+        inputs: &'tcx [hir::Ty],
         output: Option<&'tcx P<hir::Ty>>,
     ) {
         debug!("visit_fn_like_elision: enter");
index 87fb0a6b70ace31e42352020b9097e26520dc754..ee6cb398acdceecef12b853bc67886eeeb0a61ee 100644 (file)
@@ -10,7 +10,7 @@
 
 //! MIR datatypes and passes. See the [rustc guide] for more info.
 //!
-//! [rustc guide]: https://rust-lang-nursery.github.io/rustc-guide/mir.html
+//! [rustc guide]: https://rust-lang-nursery.github.io/rustc-guide/mir/index.html
 
 use graphviz::IntoCow;
 use hir::def::CtorKind;
index 5a626e7b82cc47c17f5b297dc63a9dc6ec1ad0a3..6a6bebdbd8652ca4fdc420419ffd6880af6d3215 100644 (file)
@@ -11,8 +11,8 @@
 //! See rustc guide chapters on [trait-resolution] and [trait-specialization] for more info on how
 //! this works.
 //!
-//! [trait-resolution]: https://rust-lang-nursery.github.io/rustc-guide/trait-resolution.html
-//! [trait-specialization]: https://rust-lang-nursery.github.io/rustc-guide/trait-specialization.html
+//! [trait-resolution]: https://rust-lang-nursery.github.io/rustc-guide/traits/resolution.html
+//! [trait-specialization]: https://rust-lang-nursery.github.io/rustc-guide/traits/specialization.html
 
 use hir::def_id::{DefId, LOCAL_CRATE};
 use syntax_pos::DUMMY_SP;
index 0d7d39ccf40dfcff2e069e7537c8d5472f5becba..e5559b7012dc978145a233602ed09f59f6dbd79b 100644 (file)
@@ -963,7 +963,7 @@ pub fn get_fn_like_arguments(&self, node: hir::map::Node) -> (Span, Vec<ArgKind>
                 ..
             }) => {
                 (self.tcx.sess.codemap().def_span(span), decl.inputs.iter()
-                        .map(|arg| match arg.clone().into_inner().node {
+                        .map(|arg| match arg.clone().node {
                     hir::TyTup(ref tys) => ArgKind::Tuple(
                         Some(arg.span),
                         tys.iter()
index 354debf87dc0783bc85aae9830f93c7ec7c580af..15f0b8eebc1db92b0d9a6a8271369f4cf20f0cd6 100644 (file)
@@ -10,7 +10,7 @@
 
 //! Trait Resolution. See [rustc guide] for more info on how this works.
 //!
-//! [rustc guide]: https://rust-lang-nursery.github.io/rustc-guide/trait-resolution.html
+//! [rustc guide]: https://rust-lang-nursery.github.io/rustc-guide/traits/resolution.html
 
 pub use self::SelectionError::*;
 pub use self::FulfillmentErrorCode::*;
index 08af80543dff2c51a936c2584fc023708f5f6be5..fe30b6a2f88b7be9e4ccc8bb73a2b819bd1c00a8 100644 (file)
@@ -10,7 +10,7 @@
 
 //! See [rustc guide] for more info on how this works.
 //!
-//! [rustc guide]: https://rust-lang-nursery.github.io/rustc-guide/trait-resolution.html#selection
+//! [rustc guide]: https://rust-lang-nursery.github.io/rustc-guide/traits/resolution.html#selection
 
 use self::SelectionCandidate::*;
 use self::EvaluationResult::*;
@@ -1047,7 +1047,7 @@ fn insert_evaluation_cache(&mut self,
     // candidates. See [rustc guide] for more details.
     //
     // [rustc guide]:
-    // https://rust-lang-nursery.github.io/rustc-guide/trait-resolution.html#candidate-assembly
+    // https://rust-lang-nursery.github.io/rustc-guide/traits/resolution.html#candidate-assembly
 
     fn candidate_from_obligation<'o>(&mut self,
                                      stack: &TraitObligationStack<'o, 'tcx>)
@@ -2415,7 +2415,7 @@ fn collect_predicates_for_types(&mut self,
     // type error.  See [rustc guide] for more details.
     //
     // [rustc guide]:
-    // https://rust-lang-nursery.github.io/rustc-guide/trait-resolution.html#confirmation
+    // https://rust-lang-nursery.github.io/rustc-guide/traits/resolution.html#confirmation
 
     fn confirm_candidate(&mut self,
                          obligation: &TraitObligation<'tcx>,
index d33806285142e4ba90de19eeac6cf240684892f0..f6ae5113cb2a5505e3ed72b0e659f9bacfd02605 100644 (file)
@@ -17,7 +17,7 @@
 //! See the [rustc guide] for a bit more detail on how specialization
 //! fits together with the rest of the trait machinery.
 //!
-//! [rustc guide]: https://rust-lang-nursery.github.io/rustc-guide/trait-specialization.html
+//! [rustc guide]: https://rust-lang-nursery.github.io/rustc-guide/traits/specialization.html
 
 use super::{SelectionContext, FulfillmentContext};
 use super::util::impl_trait_ref_and_oblig;
index d911f32ed3f1f7bc227d5f08ab4854de38011233..967a3324cfb2a92113d202133085d0b80df2d9bb 100644 (file)
@@ -54,7 +54,7 @@ pub trait TyEncoder: Encoder {
     fn position(&self) -> usize;
 }
 
-impl<'buf> TyEncoder for opaque::Encoder<'buf> {
+impl TyEncoder for opaque::Encoder {
     #[inline]
     fn position(&self) -> usize {
         self.position()
index 3285380c823922b2cf74ccc8b602c0f7be21644c..c42323e3d4a23de4695d376b57569ce7d287f53f 100644 (file)
@@ -979,7 +979,7 @@ fn specialized_encode(&mut self, node_id: &NodeId) -> Result<(), Self::Error> {
 }
 
 impl<'enc, 'a, 'tcx> SpecializedEncoder<Fingerprint>
-for CacheEncoder<'enc, 'a, 'tcx, opaque::Encoder<'enc>>
+for CacheEncoder<'enc, 'a, 'tcx, opaque::Encoder>
 {
     fn specialized_encode(&mut self, f: &Fingerprint) -> Result<(), Self::Error> {
         f.encode_opaque(&mut self.encoder)
@@ -1057,7 +1057,7 @@ impl IntEncodedWithFixedSize {
 impl UseSpecializedEncodable for IntEncodedWithFixedSize {}
 impl UseSpecializedDecodable for IntEncodedWithFixedSize {}
 
-impl<'enc> SpecializedEncoder<IntEncodedWithFixedSize> for opaque::Encoder<'enc> {
+impl SpecializedEncoder<IntEncodedWithFixedSize> for opaque::Encoder {
     fn specialized_encode(&mut self, x: &IntEncodedWithFixedSize) -> Result<(), Self::Error> {
         let start_pos = self.position();
         for i in 0 .. IntEncodedWithFixedSize::ENCODED_SIZE {
index 4a69fbdacc476a006051365189d339bcedc0b329..d8ca817ff2bd0314021f627f4f6869d4862f8d39 100644 (file)
@@ -1087,7 +1087,7 @@ pub fn is_self(&self) -> bool {
 ///
 /// [1]: http://smallcultfollowing.com/babysteps/blog/2013/10/29/intermingled-parameter-lists/
 /// [2]: http://smallcultfollowing.com/babysteps/blog/2013/11/04/intermingled-parameter-lists/
-/// [rustc guide]: https://rust-lang-nursery.github.io/rustc-guide/trait-hrtb.html
+/// [rustc guide]: https://rust-lang-nursery.github.io/rustc-guide/traits/hrtb.html
 #[derive(Clone, PartialEq, Eq, Hash, Copy, RustcEncodable, RustcDecodable, PartialOrd, Ord)]
 pub enum RegionKind {
     // Region bound in a type or fn declaration which will be
index 3252a2cd6ab0f6bcbfe35c54ae3ba41cd6cb36e2..4fe9c34c140cbdf8136258728b33931570fdffa0 100644 (file)
@@ -1062,10 +1062,14 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
                 TyParam(ref param_ty) => write!(f, "{}", param_ty),
                 TyAdt(def, substs) => cx.parameterized(f, substs, def.did, &[]),
                 TyDynamic(data, r) => {
-                    data.print(f, cx)?;
                     let r = r.print_to_string(cx);
                     if !r.is_empty() {
-                        write!(f, " + {}", r)
+                        write!(f, "(")?;
+                    }
+                    write!(f, "dyn ")?;
+                    data.print(f, cx)?;
+                    if !r.is_empty() {
+                        write!(f, " + {})", r)
                     } else {
                         Ok(())
                     }
index 60d28d8098b4ca656b7b86cbb6617c63adf3dba7..373ab04de4b825bbd1ea31ee512cea24a6b9feba 100644 (file)
@@ -103,6 +103,7 @@ fn fold_item(&mut self, item: P<Item>) -> SmallVector<P<Item>> {
             format: MacroAttribute(Symbol::intern(name)),
             allow_internal_unstable: true,
             allow_internal_unsafe: false,
+            local_inner_macros: false,
             edition: hygiene::default_edition(),
         });
 
index 7abd02b6656f3aa15f8192930d827fd302e9ff16..b21448df582a9786748e2a7f08ff642ebb220515 100644 (file)
@@ -1753,9 +1753,9 @@ fn from_hexadecimal_string(s: &str, round: Round) -> Result<StatusAnd<Self>, Par
                     } else {
                         loss = Some(match hex_value {
                             0 => Loss::ExactlyZero,
-                            1...7 => Loss::LessThanHalf,
+                            1..=7 => Loss::LessThanHalf,
                             8 => Loss::ExactlyHalf,
-                            9...15 => Loss::MoreThanHalf,
+                            9..=15 => Loss::MoreThanHalf,
                             _ => unreachable!(),
                         });
                     }
index 6fc0ed47b807b9de89d03f3197ab6bafc39074f2..8bc0b4969b8f985f439e855f79b6919e8648657a 100644 (file)
@@ -3,7 +3,7 @@
 > WARNING: This README is more or less obsolete, and will be removed
 > soon! The new system is described in the [rustc guide].
 
-[rustc guide]: https://rust-lang-nursery.github.io/rustc-guide/mir-borrowck.html
+[rustc guide]: https://rust-lang-nursery.github.io/rustc-guide/mir/borrowck.html
 
 This pass has the job of enforcing memory safety. This is a subtle
 topic. This docs aim to explain both the practice and the theory
index d6d386c9fbe77d74cd3468c1aed99fdf985c1704..c553eca08e6b4979a929d9dafbf49c3c40e6727d 100644 (file)
@@ -230,8 +230,7 @@ fn new() -> WasmEncoder {
     }
 
     fn u32(&mut self, val: u32) {
-        let at = self.data.len();
-        leb128::write_u32_leb128(&mut self.data, at, val);
+        leb128::write_u32_leb128(&mut self.data, val);
     }
 
     fn byte(&mut self, val: u8) {
index 57cc33d09bbea94e1f36f7fa1c82fe58ae831ce5..94776f17c7989074aea7cf6b89a75776788d76dd 100644 (file)
@@ -48,8 +48,3 @@ fn main() {
 "##,
 
 }
-
-
-register_diagnostics! {
-    E0558
-}
index dcb82e5c424e5305770d3faee1eaebe7916e5a8a..ac71ecff96457b59e579ab0e7606360dd2b222bf 100644 (file)
@@ -424,7 +424,7 @@ pub fn sanitize(result: &mut String, s: &str) -> bool {
             '-' | ':' => result.push('.'),
 
             // These are legal symbols
-            'a'...'z' | 'A'...'Z' | '0'...'9' | '_' | '.' | '$' => result.push(c),
+            'a'..='z' | 'A'..='Z' | '0'..='9' | '_' | '.' | '$' => result.push(c),
 
             _ => {
                 result.push('$');
index d45994adeb67bcf2da10fcbfed2c587ff9632c90..98f7873fda0e41da5c569fcb237117881aaed3f0 100644 (file)
@@ -25,6 +25,7 @@
 use std::env;
 
 use rustc::session::config::nightly_options;
+use rustc_serialize::opaque::Encoder;
 
 /// The first few bytes of files generated by incremental compilation
 const FILE_MAGIC: &'static [u8] = b"RSIC";
 /// the git commit hash.
 const RUSTC_VERSION: Option<&'static str> = option_env!("CFG_VERSION");
 
-pub fn write_file_header<W: io::Write>(stream: &mut W) -> io::Result<()> {
-    stream.write_all(FILE_MAGIC)?;
-    stream.write_all(&[(HEADER_FORMAT_VERSION >> 0) as u8,
-                       (HEADER_FORMAT_VERSION >> 8) as u8])?;
+pub fn write_file_header(stream: &mut Encoder) {
+    stream.emit_raw_bytes(FILE_MAGIC);
+    stream.emit_raw_bytes(&[(HEADER_FORMAT_VERSION >> 0) as u8,
+                       (HEADER_FORMAT_VERSION >> 8) as u8]);
 
     let rustc_version = rustc_version();
     assert_eq!(rustc_version.len(), (rustc_version.len() as u8) as usize);
-    stream.write_all(&[rustc_version.len() as u8])?;
-    stream.write_all(rustc_version.as_bytes())?;
-
-    Ok(())
+    stream.emit_raw_bytes(&[rustc_version.len() as u8]);
+    stream.emit_raw_bytes(rustc_version.as_bytes());
 }
 
 /// Reads the contents of a file with a file header as defined in this module.
index dcef0c662c3a1164ca53bbf87b24fa9f07d68400..06b0ea946d778fc99847092fbb00a60a054923dd 100644 (file)
@@ -16,7 +16,6 @@
 use rustc_data_structures::sync::join;
 use rustc_serialize::Encodable as RustcEncodable;
 use rustc_serialize::opaque::Encoder;
-use std::io::{self, Cursor};
 use std::fs;
 use std::path::PathBuf;
 
@@ -98,7 +97,7 @@ pub fn save_work_product_index(sess: &Session,
 }
 
 fn save_in<F>(sess: &Session, path_buf: PathBuf, encode: F)
-    where F: FnOnce(&mut Encoder) -> io::Result<()>
+    where F: FnOnce(&mut Encoder)
 {
     debug!("save: storing data in {}", path_buf.display());
 
@@ -121,20 +120,12 @@ fn save_in<F>(sess: &Session, path_buf: PathBuf, encode: F)
     }
 
     // generate the data in a memory buffer
-    let mut wr = Cursor::new(Vec::new());
-    file_format::write_file_header(&mut wr).unwrap();
-    match encode(&mut Encoder::new(&mut wr)) {
-        Ok(()) => {}
-        Err(err) => {
-            sess.err(&format!("could not encode dep-graph to `{}`: {}",
-                              path_buf.display(),
-                              err));
-            return;
-        }
-    }
+    let mut encoder = Encoder::new(Vec::new());
+    file_format::write_file_header(&mut encoder);
+    encode(&mut encoder);
 
     // write the data out
-    let data = wr.into_inner();
+    let data = encoder.into_inner();
     match fs::write(&path_buf, data) {
         Ok(_) => {
             debug!("save: data written to disk successfully");
@@ -149,10 +140,9 @@ fn save_in<F>(sess: &Session, path_buf: PathBuf, encode: F)
 }
 
 fn encode_dep_graph(tcx: TyCtxt,
-                    encoder: &mut Encoder)
-                    -> io::Result<()> {
+                    encoder: &mut Encoder) {
     // First encode the commandline arguments hash
-    tcx.sess.opts.dep_tracking_hash().encode(encoder)?;
+    tcx.sess.opts.dep_tracking_hash().encode(encoder).unwrap();
 
     // Encode the graph data.
     let serialized_graph = time(tcx.sess, "getting serialized graph", || {
@@ -234,14 +224,12 @@ struct Stat {
     }
 
     time(tcx.sess, "encoding serialized graph", || {
-        serialized_graph.encode(encoder)
-    })?;
-
-    Ok(())
+        serialized_graph.encode(encoder).unwrap();
+    });
 }
 
 fn encode_work_product_index(work_products: &FxHashMap<WorkProductId, WorkProduct>,
-                             encoder: &mut Encoder) -> io::Result<()> {
+                             encoder: &mut Encoder) {
     let serialized_products: Vec<_> = work_products
         .iter()
         .map(|(id, work_product)| {
@@ -252,13 +240,12 @@ fn encode_work_product_index(work_products: &FxHashMap<WorkProductId, WorkProduc
         })
         .collect();
 
-    serialized_products.encode(encoder)
+    serialized_products.encode(encoder).unwrap();
 }
 
 fn encode_query_cache(tcx: TyCtxt,
-                      encoder: &mut Encoder)
-                      -> io::Result<()> {
+                      encoder: &mut Encoder) {
     time(tcx.sess, "serialize query result cache", || {
-        tcx.serialize_query_result_cache(encoder)
+        tcx.serialize_query_result_cache(encoder).unwrap();
     })
 }
index d6120ab207924b2206a05eab6d4f45e29c716bd9..dfbfcfccf7c896f9bb6bc97598c4dcad75c644e5 100644 (file)
@@ -43,6 +43,7 @@
 
 use syntax::ast;
 use syntax::attr;
+use syntax::codemap::Spanned;
 use syntax::edition::Edition;
 use syntax::feature_gate::{AttributeGate, AttributeType, Stability, deprecated_attributes};
 use syntax_pos::{BytePos, Span, SyntaxContext};
@@ -1669,6 +1670,7 @@ fn check_item(
     }
 }
 
+
 /// Does nothing as a lint pass, but registers some `Lint`s
 /// which are used by other parts of the compiler.
 #[derive(Copy, Clone)]
@@ -1701,3 +1703,39 @@ fn get_lints(&self) -> LintArray {
         )
     }
 }
+
+
+declare_lint! {
+    pub ELLIPSIS_INCLUSIVE_RANGE_PATTERNS,
+    Allow,
+    "`...` range patterns are deprecated"
+}
+
+
+pub struct EllipsisInclusiveRangePatterns;
+
+impl LintPass for EllipsisInclusiveRangePatterns {
+    fn get_lints(&self) -> LintArray {
+        lint_array!(ELLIPSIS_INCLUSIVE_RANGE_PATTERNS)
+    }
+}
+
+impl EarlyLintPass for EllipsisInclusiveRangePatterns {
+    fn check_pat(&mut self, cx: &EarlyContext, pat: &ast::Pat) {
+        use self::ast::{PatKind, RangeEnd, RangeSyntax};
+
+        if let PatKind::Range(
+            _, _, Spanned { span, node: RangeEnd::Included(RangeSyntax::DotDotDot) }
+        ) = pat.node {
+            let msg = "`...` range patterns are deprecated";
+            let mut err = cx.struct_span_lint(ELLIPSIS_INCLUSIVE_RANGE_PATTERNS, span, msg);
+            err.span_suggestion_short_with_applicability(
+                span, "use `..=` for an inclusive range", "..=".to_owned(),
+                // FIXME: outstanding problem with precedence in ref patterns:
+                // https://github.com/rust-lang/rust/issues/51043#issuecomment-392252285
+                Applicability::MaybeIncorrect
+            );
+            err.emit()
+        }
+    }
+}
index 1d443258dc6423dd93c715aaff3f0e1149e8a761..13e97a9d3e5914b3d36fce41ccbdb01da6bdc8f0 100644 (file)
 extern crate syntax_pos;
 
 use rustc::lint;
+use rustc::lint::{LateContext, LateLintPass, LintPass, LintArray};
 use rustc::lint::builtin::{BARE_TRAIT_OBJECTS, ABSOLUTE_PATHS_NOT_STARTING_WITH_CRATE};
 use rustc::session;
 use rustc::util;
+use rustc::hir;
+
+use syntax::ast;
+use syntax_pos::Span;
 
 use session::Session;
 use syntax::edition::Edition;
 /// defined in this crate and the ones defined in
 /// `rustc::lint::builtin`).
 pub fn register_builtins(store: &mut lint::LintStore, sess: Option<&Session>) {
-    macro_rules! add_builtin {
-        ($sess:ident, $($name:ident),*,) => (
-            {$(
-                store.register_late_pass($sess, false, box $name);
-                )*}
-            )
-    }
-
     macro_rules! add_early_builtin {
         ($sess:ident, $($name:ident),*,) => (
             {$(
@@ -83,14 +80,6 @@ macro_rules! add_early_builtin {
             )
     }
 
-    macro_rules! add_builtin_with_new {
-        ($sess:ident, $($name:ident),*,) => (
-            {$(
-                store.register_late_pass($sess, false, box $name::new());
-                )*}
-            )
-    }
-
     macro_rules! add_early_builtin_with_new {
         ($sess:ident, $($name:ident),*,) => (
             {$(
@@ -111,45 +100,45 @@ macro_rules! add_lint_group {
                        AnonymousParameters,
                        UnusedDocComment,
                        BadRepr,
+                       EllipsisInclusiveRangePatterns,
                        );
 
     add_early_builtin_with_new!(sess,
                                 DeprecatedAttr,
                                 );
 
-    add_builtin!(sess,
-                 HardwiredLints,
-                 WhileTrue,
-                 ImproperCTypes,
-                 VariantSizeDifferences,
-                 BoxPointers,
-                 UnusedAttributes,
-                 PathStatements,
-                 UnusedResults,
-                 NonCamelCaseTypes,
-                 NonSnakeCase,
-                 NonUpperCaseGlobals,
-                 NonShorthandFieldPatterns,
-                 UnsafeCode,
-                 UnusedAllocation,
-                 MissingCopyImplementations,
-                 UnstableFeatures,
-                 UnconditionalRecursion,
-                 InvalidNoMangleItems,
-                 PluginAsLibrary,
-                 MutableTransmutes,
-                 UnionsWithDropFields,
-                 UnreachablePub,
-                 TypeAliasBounds,
-                 UnusedBrokenConst,
-                 TrivialConstraints,
-                 );
+    late_lint_methods!(declare_combined_late_lint_pass, [BuiltinCombinedLateLintPass, [
+        HardwiredLints: HardwiredLints,
+        WhileTrue: WhileTrue,
+        ImproperCTypes: ImproperCTypes,
+        VariantSizeDifferences: VariantSizeDifferences,
+        BoxPointers: BoxPointers,
+        UnusedAttributes: UnusedAttributes,
+        PathStatements: PathStatements,
+        UnusedResults: UnusedResults,
+        NonCamelCaseTypes: NonCamelCaseTypes,
+        NonSnakeCase: NonSnakeCase,
+        NonUpperCaseGlobals: NonUpperCaseGlobals,
+        NonShorthandFieldPatterns: NonShorthandFieldPatterns,
+        UnsafeCode: UnsafeCode,
+        UnusedAllocation: UnusedAllocation,
+        MissingCopyImplementations: MissingCopyImplementations,
+        UnstableFeatures: UnstableFeatures,
+        UnconditionalRecursion: UnconditionalRecursion,
+        InvalidNoMangleItems: InvalidNoMangleItems,
+        PluginAsLibrary: PluginAsLibrary,
+        MutableTransmutes: MutableTransmutes,
+        UnionsWithDropFields: UnionsWithDropFields,
+        UnreachablePub: UnreachablePub,
+        TypeAliasBounds: TypeAliasBounds,
+        UnusedBrokenConst: UnusedBrokenConst,
+        TrivialConstraints: TrivialConstraints,
+        TypeLimits: TypeLimits::new(),
+        MissingDoc: MissingDoc::new(),
+        MissingDebugImplementations: MissingDebugImplementations::new(),
+    ]], ['tcx]);
 
-    add_builtin_with_new!(sess,
-                          TypeLimits,
-                          MissingDoc,
-                          MissingDebugImplementations,
-                          );
+    store.register_late_pass(sess, false, box BuiltinCombinedLateLintPass::new());
 
     add_lint_group!(sess,
                     "bad_style",
@@ -188,7 +177,8 @@ macro_rules! add_lint_group {
                     "rust_2018_idioms",
                     BARE_TRAIT_OBJECTS,
                     UNREACHABLE_PUB,
-                    UNUSED_EXTERN_CRATES);
+                    UNUSED_EXTERN_CRATES,
+                    ELLIPSIS_INCLUSIVE_RANGE_PATTERNS);
 
     // Guidelines for creating a future incompatibility lint:
     //
index ce270006a9d0ad187d1a1e213363238804dbc545..46c4a3a1abe80aff682ce27a2ffc5d17f1118c73 100644 (file)
@@ -35,8 +35,6 @@
 use rustc_serialize::{Encodable, Encoder, SpecializedEncoder, opaque};
 
 use std::hash::Hash;
-use std::io::prelude::*;
-use std::io::Cursor;
 use std::path::Path;
 use rustc_data_structures::sync::Lrc;
 use std::u32;
@@ -52,7 +50,7 @@
 use rustc::hir::intravisit;
 
 pub struct EncodeContext<'a, 'tcx: 'a> {
-    opaque: opaque::Encoder<'a>,
+    opaque: opaque::Encoder,
     pub tcx: TyCtxt<'a, 'tcx, 'tcx>,
     link_meta: &'a LinkMeta,
 
@@ -76,7 +74,7 @@ macro_rules! encoder_methods {
 }
 
 impl<'a, 'tcx> Encoder for EncodeContext<'a, 'tcx> {
-    type Error = <opaque::Encoder<'a> as Encoder>::Error;
+    type Error = <opaque::Encoder as Encoder>::Error;
 
     fn emit_nil(&mut self) -> Result<(), Self::Error> {
         Ok(())
@@ -480,7 +478,7 @@ fn encode_crate_root(&mut self) -> Lazy<CrateRoot> {
 
         // Index the items
         i = self.position();
-        let index = items.write_index(&mut self.opaque.cursor);
+        let index = items.write_index(&mut self.opaque);
         let index_bytes = self.position() - i;
 
         let attrs = tcx.hir.krate_attrs();
@@ -537,7 +535,7 @@ fn encode_crate_root(&mut self) -> Lazy<CrateRoot> {
 
         if self.tcx.sess.meta_stats() {
             let mut zero_bytes = 0;
-            for e in self.opaque.cursor.get_ref() {
+            for e in self.opaque.data.iter() {
                 if *e == 0 {
                     zero_bytes += 1;
                 }
@@ -1797,15 +1795,15 @@ pub fn encode_metadata<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                                  link_meta: &LinkMeta)
                                  -> EncodedMetadata
 {
-    let mut cursor = Cursor::new(vec![]);
-    cursor.write_all(METADATA_HEADER).unwrap();
+    let mut encoder = opaque::Encoder::new(vec![]);
+    encoder.emit_raw_bytes(METADATA_HEADER);
 
     // Will be filled with the root position after encoding everything.
-    cursor.write_all(&[0, 0, 0, 0]).unwrap();
+    encoder.emit_raw_bytes(&[0, 0, 0, 0]);
 
-    let root = {
+    let (root, mut result) = {
         let mut ecx = EncodeContext {
-            opaque: opaque::Encoder::new(&mut cursor),
+            opaque: encoder,
             tcx,
             link_meta,
             lazy_state: LazyState::NoNode,
@@ -1821,9 +1819,9 @@ pub fn encode_metadata<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
 
         // Encode all the entries and extra information in the crate,
         // culminating in the `CrateRoot` which points to all of it.
-        ecx.encode_crate_root()
+        let root = ecx.encode_crate_root();
+        (root, ecx.opaque.into_inner())
     };
-    let mut result = cursor.into_inner();
 
     // Encode the root position.
     let header = METADATA_HEADER.len();
index 157b8385a6922e9d3e77e44b4bf0ab238ea89f24..0b4f7e579acb91fb133ee069fd7ab637458fae7c 100644 (file)
@@ -11,7 +11,7 @@
 use schema::*;
 
 use rustc::hir::def_id::{DefId, DefIndex, DefIndexAddressSpace};
-use std::io::{Cursor, Write};
+use rustc_serialize::opaque::Encoder;
 use std::slice;
 use std::u32;
 
@@ -54,15 +54,15 @@ pub fn record_index(&mut self, item: DefIndex, entry: Lazy<Entry>) {
         self.positions[space_index][array_index] = position.to_le();
     }
 
-    pub fn write_index(&self, buf: &mut Cursor<Vec<u8>>) -> LazySeq<Index> {
+    pub fn write_index(&self, buf: &mut Encoder) -> LazySeq<Index> {
         let pos = buf.position();
 
         // First we write the length of the lower range ...
-        buf.write_all(words_to_bytes(&[(self.positions[0].len() as u32).to_le()])).unwrap();
+        buf.emit_raw_bytes(words_to_bytes(&[(self.positions[0].len() as u32).to_le()]));
         // ... then the values in the lower range ...
-        buf.write_all(words_to_bytes(&self.positions[0][..])).unwrap();
+        buf.emit_raw_bytes(words_to_bytes(&self.positions[0][..]));
         // ... then the values in the higher range.
-        buf.write_all(words_to_bytes(&self.positions[1][..])).unwrap();
+        buf.emit_raw_bytes(words_to_bytes(&self.positions[1][..]));
         LazySeq::with_position_and_length(pos as usize,
             self.positions[0].len() + self.positions[1].len() + 1)
     }
index ee0a087a1dd0ae9860199e80afa58d8fc4cac970..b9d6486d9174a9117ca38c11d7aed88c4567fb17 100644 (file)
@@ -540,12 +540,12 @@ pub fn new_source_scope(&mut self,
     // ==============
     /// Finds the breakable scope for a given label. This is used for
     /// resolving `break` and `continue`.
-    pub fn find_breakable_scope(&mut self,
+    pub fn find_breakable_scope(&self,
                            span: Span,
                            label: region::Scope)
-                           -> &mut BreakableScope<'tcx> {
+                           -> &BreakableScope<'tcx> {
         // find the loop-scope with the correct id
-        self.breakable_scopes.iter_mut()
+        self.breakable_scopes.iter()
             .rev()
             .filter(|breakable_scope| breakable_scope.region_scope == label)
             .next()
index f195775bf86e97419942fe974b7c5865dcc96342..c2da1bee3954ab3fa2ecb0f551b2e52b4475b2c8 100644 (file)
@@ -306,9 +306,9 @@ struct X { x: (), }
 ```compile_fail
 match 5u32 {
     // This range is ok, albeit pointless.
-    1 ... 1 => {}
+    1 ..= 1 => {}
     // This range is empty, and the compiler can tell.
-    1000 ... 5 => {}
+    1000 ..= 5 => {}
 }
 ```
 "##,
index b96cc352bdb60374499a42ef41efe306d7607c6a..24301e970f506dee709e332988ee24bd85796450 100644 (file)
@@ -371,43 +371,56 @@ fn check_arms<'a, 'tcx>(cx: &mut MatchCheckCtxt<'a, 'tcx>,
                 NotUseful => {
                     match source {
                         hir::MatchSource::IfLetDesugar { .. } => {
-                            if printed_if_let_err {
-                                // we already printed an irrefutable if-let pattern error.
-                                // We don't want two, that's just confusing.
+                            if cx.tcx.features().irrefutable_let_patterns {
+                                cx.tcx.lint_node(
+                                    lint::builtin::IRREFUTABLE_LET_PATTERNS,
+                                    hir_pat.id, pat.span,
+                                    "irrefutable if-let pattern");
                             } else {
-                                // find the first arm pattern so we can use its span
-                                let &(ref first_arm_pats, _) = &arms[0];
-                                let first_pat = &first_arm_pats[0];
-                                let span = first_pat.0.span;
-                                struct_span_err!(cx.tcx.sess, span, E0162,
-                                                "irrefutable if-let pattern")
-                                    .span_label(span, "irrefutable pattern")
-                                    .emit();
-                                printed_if_let_err = true;
+                                if printed_if_let_err {
+                                    // we already printed an irrefutable if-let pattern error.
+                                    // We don't want two, that's just confusing.
+                                } else {
+                                    // find the first arm pattern so we can use its span
+                                    let &(ref first_arm_pats, _) = &arms[0];
+                                    let first_pat = &first_arm_pats[0];
+                                    let span = first_pat.0.span;
+                                    struct_span_err!(cx.tcx.sess, span, E0162,
+                                                    "irrefutable if-let pattern")
+                                        .span_label(span, "irrefutable pattern")
+                                        .emit();
+                                    printed_if_let_err = true;
+                                }
                             }
                         },
 
                         hir::MatchSource::WhileLetDesugar => {
-                            // find the first arm pattern so we can use its span
-                            let &(ref first_arm_pats, _) = &arms[0];
-                            let first_pat = &first_arm_pats[0];
-                            let span = first_pat.0.span;
-
                             // check which arm we're on.
                             match arm_index {
                                 // The arm with the user-specified pattern.
                                 0 => {
                                     cx.tcx.lint_node(
-                                            lint::builtin::UNREACHABLE_PATTERNS,
+                                        lint::builtin::UNREACHABLE_PATTERNS,
                                         hir_pat.id, pat.span,
                                         "unreachable pattern");
                                 },
                                 // The arm with the wildcard pattern.
                                 1 => {
-                                    struct_span_err!(cx.tcx.sess, span, E0165,
-                                                     "irrefutable while-let pattern")
-                                        .span_label(span, "irrefutable pattern")
-                                        .emit();
+                                    if cx.tcx.features().irrefutable_let_patterns {
+                                        cx.tcx.lint_node(
+                                            lint::builtin::IRREFUTABLE_LET_PATTERNS,
+                                            hir_pat.id, pat.span,
+                                            "irrefutable while-let pattern");
+                                    } else {
+                                        // find the first arm pattern so we can use its span
+                                        let &(ref first_arm_pats, _) = &arms[0];
+                                        let first_pat = &first_arm_pats[0];
+                                        let span = first_pat.0.span;
+                                        struct_span_err!(cx.tcx.sess, span, E0165,
+                                                         "irrefutable while-let pattern")
+                                            .span_label(span, "irrefutable pattern")
+                                            .emit();
+                                    }
                                 },
                                 _ => bug!(),
                             }
@@ -468,7 +481,7 @@ fn check_exhaustive<'a, 'tcx>(cx: &mut MatchCheckCtxt<'a, 'tcx>,
             let joined_patterns = match witnesses.len() {
                 0 => bug!(),
                 1 => format!("`{}`", witnesses[0]),
-                2...LIMIT => {
+                2..=LIMIT => {
                     let (tail, head) = witnesses.split_last().unwrap();
                     let head: Vec<_> = head.iter().map(|w| w.to_string()).collect();
                     format!("`{}` and `{}`", head.join("`, `"), tail)
index 2b1422773c117a2d8f67a724d35ae19d16257ed6..9b92a8b5e7861edff98293cf2e23de07beee3eb3 100644 (file)
@@ -416,7 +416,6 @@ fn lower_pattern_unadjusted(&mut self, pat: &'tcx hir::Pat) -> Pattern<'tcx> {
             }
 
             PatKind::Slice(ref prefix, ref slice, ref suffix) => {
-                let ty = self.tables.node_id_to_type(pat.hir_id);
                 match ty.sty {
                     ty::TyRef(_, ty, _) =>
                         PatternKind::Deref {
@@ -427,11 +426,12 @@ fn lower_pattern_unadjusted(&mut self, pat: &'tcx hir::Pat) -> Pattern<'tcx> {
                                     pat.span, ty, prefix, slice, suffix))
                             },
                         },
-
                     ty::TySlice(..) |
                     ty::TyArray(..) =>
                         self.slice_or_array_pattern(pat.span, ty, prefix, slice, suffix),
-
+                    ty::TyError => { // Avoid ICE
+                        return Pattern { span: pat.span, ty, kind: Box::new(PatternKind::Wild) };
+                    }
                     ref sty =>
                         span_bug!(
                             pat.span,
@@ -441,7 +441,6 @@ fn lower_pattern_unadjusted(&mut self, pat: &'tcx hir::Pat) -> Pattern<'tcx> {
             }
 
             PatKind::Tuple(ref subpatterns, ddpos) => {
-                let ty = self.tables.node_id_to_type(pat.hir_id);
                 match ty.sty {
                     ty::TyTuple(ref tys) => {
                         let subpatterns =
@@ -455,7 +454,9 @@ fn lower_pattern_unadjusted(&mut self, pat: &'tcx hir::Pat) -> Pattern<'tcx> {
 
                         PatternKind::Leaf { subpatterns: subpatterns }
                     }
-
+                    ty::TyError => { // Avoid ICE (#50577)
+                        return Pattern { span: pat.span, ty, kind: Box::new(PatternKind::Wild) };
+                    }
                     ref sty => span_bug!(pat.span, "unexpected type for tuple pattern: {:?}", sty),
                 }
             }
@@ -464,6 +465,9 @@ fn lower_pattern_unadjusted(&mut self, pat: &'tcx hir::Pat) -> Pattern<'tcx> {
                 let var_ty = self.tables.node_id_to_type(pat.hir_id);
                 let region = match var_ty.sty {
                     ty::TyRef(r, _, _) => Some(r),
+                    ty::TyError => { // Avoid ICE
+                        return Pattern { span: pat.span, ty, kind: Box::new(PatternKind::Wild) };
+                    }
                     _ => None,
                 };
                 let bm = *self.tables.pat_binding_modes().get(pat.hir_id)
@@ -505,12 +509,8 @@ fn lower_pattern_unadjusted(&mut self, pat: &'tcx hir::Pat) -> Pattern<'tcx> {
                 let def = self.tables.qpath_def(qpath, pat.hir_id);
                 let adt_def = match ty.sty {
                     ty::TyAdt(adt_def, _) => adt_def,
-                    ty::TyError => {  // Avoid ICE (#50585)
-                        return Pattern {
-                            span: pat.span,
-                            ty,
-                            kind: Box::new(PatternKind::Wild),
-                        };
+                    ty::TyError => { // Avoid ICE (#50585)
+                        return Pattern { span: pat.span, ty, kind: Box::new(PatternKind::Wild) };
                     }
                     _ => span_bug!(pat.span,
                                    "tuple struct pattern not applied to an ADT {:?}",
index 3fcf1b5c8ed599e84d4b442cbf67ed7e63536f06..592c9dbe6ffe4bd93eac6cbdf9ce83f154594b0f 100644 (file)
@@ -76,7 +76,7 @@ pub fn value_to_const_value<'tcx>(
     val: Value,
     ty: Ty<'tcx>,
 ) -> &'tcx ty::Const<'tcx> {
-    let layout = ecx.tcx.layout_of(ty::ParamEnv::reveal_all().and(ty)).unwrap();
+    let layout = ecx.layout_of(ty).unwrap();
     match (val, &layout.abi) {
         (Value::Scalar(Scalar::Bits { defined: 0, ..}), _) if layout.is_zst() => {},
         (Value::ByRef(..), _) |
index ea15f4c75b96c73bb0bd7336242812ac7be2f398..b1ab86674cf90fa74388effcfa7b49e6c403f3a3 100644 (file)
@@ -108,6 +108,7 @@ pub fn register_syntax_extension(&mut self, name: ast::Name, extension: SyntaxEx
                 def_info: _,
                 allow_internal_unstable,
                 allow_internal_unsafe,
+                local_inner_macros,
                 unstable_feature,
                 edition,
             } => {
@@ -117,6 +118,7 @@ pub fn register_syntax_extension(&mut self, name: ast::Name, extension: SyntaxEx
                     def_info: Some((nid, self.krate_span)),
                     allow_internal_unstable,
                     allow_internal_unsafe,
+                    local_inner_macros,
                     unstable_feature,
                     edition,
                 }
@@ -152,6 +154,7 @@ pub fn register_macro(&mut self, name: &str, expander: MacroExpanderFn) {
             def_info: None,
             allow_internal_unstable: false,
             allow_internal_unsafe: false,
+            local_inner_macros: false,
             unstable_feature: None,
             edition: hygiene::default_edition(),
         });
index ebdaa456170b215a33bd16d653d040821e8fd934..c9d00f80b0ba325b31d073fc997b24d203d2baf0 100644 (file)
@@ -451,11 +451,18 @@ pub fn resolve_macro_to_def_inner(&mut self, scope: Mark, path: &ast::Path,
                                   kind: MacroKind, force: bool)
                                   -> Result<Def, Determinacy> {
         let ast::Path { ref segments, span } = *path;
-        let path: Vec<_> = segments.iter().map(|seg| seg.ident).collect();
+        let mut path: Vec<_> = segments.iter().map(|seg| seg.ident).collect();
         let invocation = self.invocations[&scope];
         let module = invocation.module.get();
         self.current_module = if module.is_trait() { module.parent.unwrap() } else { module };
 
+        // Possibly apply the macro helper hack
+        if self.use_extern_macros && kind == MacroKind::Bang && path.len() == 1 &&
+           path[0].span.ctxt().outer().expn_info().map_or(false, |info| info.local_inner_macros) {
+            let root = Ident::new(keywords::DollarCrate.name(), path[0].span);
+            path.insert(0, root);
+        }
+
         if path.len() > 1 {
             if !self.use_extern_macros && self.gated_errors.insert(span) {
                 let msg = "non-ident macro paths are experimental";
index fcae9ea22bba1cde930429a3eeb15b8df4fd25b2..3195823eb09820758b69bd39031994f1de4ad0e2 100644 (file)
@@ -139,11 +139,11 @@ pub fn align<C: HasDataLayout>(&self, cx: C) -> Align {
             RegKind::Integer => {
                 match self.size.bits() {
                     1 => dl.i1_align,
-                    2...8 => dl.i8_align,
-                    9...16 => dl.i16_align,
-                    17...32 => dl.i32_align,
-                    33...64 => dl.i64_align,
-                    65...128 => dl.i128_align,
+                    2..=8 => dl.i8_align,
+                    9..=16 => dl.i16_align,
+                    17..=32 => dl.i32_align,
+                    33..=64 => dl.i64_align,
+                    65..=128 => dl.i128_align,
                     _ => panic!("unsupported integer: {:?}", self)
                 }
             }
index 7ff04df6233995322e64931624333243d9c7c7dd..9003e30357cbd8b24a22ceed894398a829866a26 100644 (file)
@@ -441,10 +441,10 @@ pub fn align<C: HasDataLayout>(&self, cx: C) -> Align {
     /// Find the smallest Integer type which can represent the signed value.
     pub fn fit_signed(x: i128) -> Integer {
         match x {
-            -0x0000_0000_0000_0080...0x0000_0000_0000_007f => I8,
-            -0x0000_0000_0000_8000...0x0000_0000_0000_7fff => I16,
-            -0x0000_0000_8000_0000...0x0000_0000_7fff_ffff => I32,
-            -0x8000_0000_0000_0000...0x7fff_ffff_ffff_ffff => I64,
+            -0x0000_0000_0000_0080..=0x0000_0000_0000_007f => I8,
+            -0x0000_0000_0000_8000..=0x0000_0000_0000_7fff => I16,
+            -0x0000_0000_8000_0000..=0x0000_0000_7fff_ffff => I32,
+            -0x8000_0000_0000_0000..=0x7fff_ffff_ffff_ffff => I64,
             _ => I128
         }
     }
@@ -452,10 +452,10 @@ pub fn fit_signed(x: i128) -> Integer {
     /// Find the smallest Integer type which can represent the unsigned value.
     pub fn fit_unsigned(x: u128) -> Integer {
         match x {
-            0...0x0000_0000_0000_00ff => I8,
-            0...0x0000_0000_0000_ffff => I16,
-            0...0x0000_0000_ffff_ffff => I32,
-            0...0xffff_ffff_ffff_ffff => I64,
+            0..=0x0000_0000_0000_00ff => I8,
+            0..=0x0000_0000_0000_ffff => I16,
+            0..=0x0000_0000_ffff_ffff => I32,
+            0..=0xffff_ffff_ffff_ffff => I64,
             _ => I128,
         }
     }
index e84586520b1e4421286ac96df63d7aa1c1c56591..889073f6b4ca96a0ba5a9bfa67522c2176c73ce0 100644 (file)
@@ -3846,7 +3846,14 @@ fn check_expr_kind(&self,
                 }
 
             }
-            hir::ExprContinue(_) => { tcx.types.never }
+            hir::ExprContinue(destination) => {
+                if let Ok(_) = destination.target_id {
+                    tcx.types.never
+                } else {
+                    // There was an error, make typecheck fail
+                    tcx.types.err
+                }
+            }
             hir::ExprRet(ref expr_opt) => {
                 if self.ret_coercion.is_none() {
                     struct_span_err!(self.tcx.sess, expr.span, E0572,
index 824346dab94fc326e49763054fe50bd764abbe7a..a537b7d41c44b631777de4a141ff039759e47e1e 100644 (file)
@@ -419,7 +419,7 @@ fn convert_item<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, item_id: ast::NodeId) {
                 convert_variant_ctor(tcx, struct_def.id());
             }
         },
-        hir::ItemExistential(..) |
+        hir::ItemExistential(..) => {}
         hir::ItemTy(..) | hir::ItemStatic(..) | hir::ItemConst(..) | hir::ItemFn(..) => {
             tcx.generics_of(def_id);
             tcx.type_of(def_id);
@@ -1066,24 +1066,7 @@ fn type_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                 ItemExistential(hir::ExistTy { impl_trait_fn: None, .. }) => unimplemented!(),
                 // existential types desugared from impl Trait
                 ItemExistential(hir::ExistTy { impl_trait_fn: Some(owner), .. }) => {
-                    tcx.typeck_tables_of(owner).concrete_existential_types
-                        .get(&def_id)
-                        .cloned()
-                        .unwrap_or_else(|| {
-                            // This can occur if some error in the
-                            // owner fn prevented us from populating
-                            // the `concrete_existential_types` table.
-                            tcx.sess.delay_span_bug(
-                                DUMMY_SP,
-                                &format!(
-                                    "owner {:?} has no existential type for {:?} in its tables",
-                                    owner,
-                                    def_id,
-                                ),
-                            );
-
-                            tcx.types.err
-                        })
+                    tcx.typeck_tables_of(owner).concrete_existential_types[&def_id]
                 },
                 ItemTrait(..) | ItemTraitAlias(..) |
                 ItemMod(..) |
@@ -1898,11 +1881,18 @@ fn codegen_fn_attrs<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, id: DefId) -> Codegen
                 }
             });
         } else if attr.check_name("export_name") {
-            if let s @ Some(_) = attr.value_str() {
-                codegen_fn_attrs.export_name = s;
+            if let Some(s) = attr.value_str() {
+                if s.as_str().contains("\0") {
+                    // `#[export_name = ...]` will be converted to a null-terminated string,
+                    // so it may not contain any null characters.
+                    struct_span_err!(tcx.sess, attr.span, E0648,
+                                     "`export_name` may not contain null characters")
+                        .emit();
+                }
+                codegen_fn_attrs.export_name = Some(s);
             } else {
                 struct_span_err!(tcx.sess, attr.span, E0558,
-                                    "export_name attribute has invalid format")
+                                 "`export_name` attribute has invalid format")
                     .span_label(attr.span, "did you mean #[export_name=\"*\"]?")
                     .emit();
             }
index 3f7e3529e9648f713430dd29216aec29ab623802..dd09bf96da594e3dedd478073b545b808fc0cc66 100644 (file)
@@ -207,7 +207,7 @@ struct Dog {
 // The ordering relation for strings can't be evaluated at compile time,
 // so this doesn't work:
 match string {
-    "hello" ... "world" => {}
+    "hello" ..= "world" => {}
     _ => {}
 }
 
@@ -2146,7 +2146,7 @@ fn main() -> i32 { 0 }
 
 let x = 1u8;
 match x {
-    0u8...3i8 => (),
+    0u8..=3i8 => (),
     // error: mismatched types in range: expected u8, found i8
     _ => ()
 }
@@ -2189,7 +2189,7 @@ fn x(self: Rc<Foo>) {}
 let x = 1u8;
 
 match x {
-    0u8...3u8 => (), // ok!
+    0u8..=3u8 => (), // ok!
     _ => ()
 }
 ```
@@ -3709,7 +3709,7 @@ fn main() {}
 Erroneous code example:
 
 ```ignore (error-emitted-at-codegen-which-cannot-be-handled-by-compile_fail)
-#[export_name] // error: export_name attribute has invalid format
+#[export_name] // error: `export_name` attribute has invalid format
 pub fn something() {}
 
 fn main() {}
@@ -4545,6 +4545,15 @@ fn start(_: isize, _: *const *const u8) -> isize where (): Copy {
 ```
 "##,
 
+E0648: r##"
+`export_name` attributes may not contain null characters (`\0`).
+
+```compile_fail,E0648
+#[export_name="\0foo"] // error: `export_name` may not contain null characters
+pub fn bar() {}
+```
+"##,
+
 E0689: r##"
 This error indicates that the numeric value for the method being passed exists
 but the type of the numeric value or binding could not be identified.
index 126fa7fb320348b78a3958d9a31867b86bc0729e..f0c40d1d491e21835828b5ecf4a671d91c729de1 100644 (file)
@@ -9,5 +9,5 @@ path = "lib.rs"
 
 [dependencies]
 pulldown-cmark = { version = "0.1.2", default-features = false }
-minifier = "0.0.11"
+minifier = "0.0.14"
 tempfile = "3"
index 5c09da90491d064f6001723f0080d4e1171640e4..272819ba2dd96940796d1978b14b8b8a055043b1 100644 (file)
@@ -263,7 +263,7 @@ fn generics_to_path_params(&self, generics: ty::Generics) -> hir::GenericArgs {
                     }));
                 }
                 ty::GenericParamDefKind::Type {..} => {
-                    args.push(hir::GenericArg::Type(P(self.ty_param_to_ty(param.clone()))));
+                    args.push(hir::GenericArg::Type(self.ty_param_to_ty(param.clone())));
                 }
             }
         }
index 057e7f3ab843354d88dc3d4f15fe261cee302087..3cc0745b195e696782c040f4c2c478ff14b4ae9c 100644 (file)
@@ -2150,7 +2150,7 @@ pub struct Arguments {
     pub values: Vec<Argument>,
 }
 
-impl<'a> Clean<Arguments> for (&'a [P<hir::Ty>], &'a [Spanned<ast::Name>]) {
+impl<'a> Clean<Arguments> for (&'a [hir::Ty], &'a [Spanned<ast::Name>]) {
     fn clean(&self, cx: &DocContext) -> Arguments {
         Arguments {
             values: self.0.iter().enumerate().map(|(i, ty)| {
@@ -2168,7 +2168,7 @@ fn clean(&self, cx: &DocContext) -> Arguments {
     }
 }
 
-impl<'a> Clean<Arguments> for (&'a [P<hir::Ty>], hir::BodyId) {
+impl<'a> Clean<Arguments> for (&'a [hir::Ty], hir::BodyId) {
     fn clean(&self, cx: &DocContext) -> Arguments {
         let body = cx.tcx.hir.body(self.1);
 
@@ -2184,7 +2184,7 @@ fn clean(&self, cx: &DocContext) -> Arguments {
 }
 
 impl<'a, A: Copy> Clean<FnDecl> for (&'a hir::FnDecl, A)
-    where (&'a [P<hir::Ty>], A): Clean<Arguments>
+    where (&'a [hir::Ty], A): Clean<Arguments>
 {
     fn clean(&self, cx: &DocContext) -> FnDecl {
         FnDecl {
@@ -2926,7 +2926,7 @@ fn clean(&self, cx: &DocContext) -> Type {
                                         }
                                     });
                                     if let Some(ty) = type_.cloned() {
-                                        ty_substs.insert(ty_param_def, ty.into_inner().clean(cx));
+                                        ty_substs.insert(ty_param_def, ty.clean(cx));
                                     } else if let Some(default) = default.clone() {
                                         ty_substs.insert(ty_param_def,
                                                          default.into_inner().clean(cx));
index 53ebb3a12f527e637bfe3b84938f2e6c816d9d79..ddc9bdb384c0b359812661b4ac37058adeae0578 100644 (file)
@@ -190,8 +190,8 @@ pub fn run_core(search_paths: SearchPaths,
     let intra_link_resolution_failure_name = lint::builtin::INTRA_DOC_LINK_RESOLUTION_FAILURE.name;
     let warnings_lint_name = lint::builtin::WARNINGS.name;
     let lints = lint::builtin::HardwiredLints.get_lints()
-                    .iter()
-                    .chain(rustc_lint::SoftLints.get_lints())
+                    .into_iter()
+                    .chain(rustc_lint::SoftLints.get_lints().into_iter())
                     .filter_map(|lint| {
                         if lint.name == warnings_lint_name ||
                            lint.name == intra_link_resolution_failure_name {
index f7be4f58dfb577e2bcd55f473f66695e160dd580..130451d07af8649bb188549cb6b2fd27c4d17c2c 100644 (file)
@@ -42,6 +42,7 @@
 use std::default::Default;
 use std::error;
 use std::fmt::{self, Display, Formatter, Write as FmtWrite};
+use std::ffi::OsStr;
 use std::fs::{self, File, OpenOptions};
 use std::io::prelude::*;
 use std::io::{self, BufWriter, BufReader};
@@ -756,10 +757,12 @@ fn write_shared(cx: &Context,
     // Add all the static files. These may already exist, but we just
     // overwrite them anyway to make sure that they're fresh and up-to-date.
 
-    write(cx.dst.join(&format!("rustdoc{}.css", cx.shared.resource_suffix)),
-          include_bytes!("static/rustdoc.css"))?;
-    write(cx.dst.join(&format!("settings{}.css", cx.shared.resource_suffix)),
-          include_bytes!("static/settings.css"))?;
+    write_minify(cx.dst.join(&format!("rustdoc{}.css", cx.shared.resource_suffix)),
+                 include_str!("static/rustdoc.css"),
+                 enable_minification)?;
+    write_minify(cx.dst.join(&format!("settings{}.css", cx.shared.resource_suffix)),
+                 include_str!("static/settings.css"),
+                 enable_minification)?;
 
     // To avoid "light.css" to be overwritten, we'll first run over the received themes and only
     // then we'll run over the "official" styles.
@@ -781,11 +784,13 @@ fn write_shared(cx: &Context,
           include_bytes!("static/brush.svg"))?;
     write(cx.dst.join(&format!("wheel{}.svg", cx.shared.resource_suffix)),
           include_bytes!("static/wheel.svg"))?;
-    write(cx.dst.join(&format!("light{}.css", cx.shared.resource_suffix)),
-          include_bytes!("static/themes/light.css"))?;
+    write_minify(cx.dst.join(&format!("light{}.css", cx.shared.resource_suffix)),
+                 include_str!("static/themes/light.css"),
+                 enable_minification)?;
     themes.insert("light".to_owned());
-    write(cx.dst.join(&format!("dark{}.css", cx.shared.resource_suffix)),
-          include_bytes!("static/themes/dark.css"))?;
+    write_minify(cx.dst.join(&format!("dark{}.css", cx.shared.resource_suffix)),
+                 include_str!("static/themes/dark.css"),
+                 enable_minification)?;
     themes.insert("dark".to_owned());
 
     let mut themes: Vec<&String> = themes.iter().collect();
@@ -857,10 +862,19 @@ fn write_shared(cx: &Context,
 
     if let Some(ref css) = cx.shared.css_file_extension {
         let out = cx.dst.join(&format!("theme{}.css", cx.shared.resource_suffix));
-        try_err!(fs::copy(css, out), css);
+        if !enable_minification {
+            try_err!(fs::copy(css, out), css);
+        } else {
+            let mut f = try_err!(File::open(css), css);
+            let mut buffer = String::with_capacity(1000);
+
+            try_err!(f.read_to_string(&mut buffer), css);
+            write_minify(out, &buffer, enable_minification)?;
+        }
     }
-    write(cx.dst.join(&format!("normalize{}.css", cx.shared.resource_suffix)),
-          include_bytes!("static/normalize.css"))?;
+    write_minify(cx.dst.join(&format!("normalize{}.css", cx.shared.resource_suffix)),
+                 include_str!("static/normalize.css"),
+                 enable_minification)?;
     write(cx.dst.join("FiraSans-Regular.woff"),
           include_bytes!("static/FiraSans-Regular.woff"))?;
     write(cx.dst.join("FiraSans-Medium.woff"),
@@ -1051,7 +1065,12 @@ fn write(dst: PathBuf, contents: &[u8]) -> Result<(), Error> {
 
 fn write_minify(dst: PathBuf, contents: &str, enable_minification: bool) -> Result<(), Error> {
     if enable_minification {
-        write(dst, minifier::js::minify(contents).as_bytes())
+        if dst.extension() == Some(&OsStr::new("css")) {
+            let res = try_none!(minifier::css::minify(contents).ok(), &dst);
+            write(dst, res.as_bytes())
+        } else {
+            write(dst, minifier::js::minify(contents).as_bytes())
+        }
     } else {
         write(dst, contents.as_bytes())
     }
index 566e2f1ed498c47fd8e7fbc1fc442b32b7e161b3..284406589b38c5d48e08385a347995cf4939a63c 100644 (file)
@@ -103,10 +103,14 @@ struct Output {
 }
 
 pub fn main() {
-    const STACK_SIZE: usize = 32_000_000; // 32MB
+    let thread_stack_size: usize = if cfg!(target_os = "haiku") {
+        16_000_000 // 16MB on Haiku
+    } else {
+        32_000_000 // 32MB on other platforms
+    };
     rustc_driver::set_sigpipe_handler();
     env_logger::init();
-    let res = std::thread::Builder::new().stack_size(STACK_SIZE).spawn(move || {
+    let res = std::thread::Builder::new().stack_size(thread_stack_size).spawn(move || {
         syntax::with_globals(move || {
             get_args().map(|args| main_args(&args)).unwrap_or(1)
         })
index b5b344e8d5f24a4ea39912dd12f139bb1eae797e..4c306d9b2d37505087f7c10643ffdbbe97118f57 100644 (file)
@@ -125,9 +125,9 @@ fn from_hex(&self) -> Result<Vec<u8>, FromHexError> {
             buf <<= 4;
 
             match byte {
-                b'A'...b'F' => buf |= byte - b'A' + 10,
-                b'a'...b'f' => buf |= byte - b'a' + 10,
-                b'0'...b'9' => buf |= byte - b'0',
+                b'A'..=b'F' => buf |= byte - b'A' + 10,
+                b'a'..=b'f' => buf |= byte - b'a' + 10,
+                b'0'..=b'9' => buf |= byte - b'0',
                 b' '|b'\r'|b'\n'|b'\t' => {
                     buf >>= 4;
                     continue
index efdad7d801ab5ac83d074bf569ce572642647094..9959d5ce40d2d20c0384ffe230db1c2441c6ad6c 100644 (file)
@@ -1557,14 +1557,14 @@ fn parse_u64(&mut self) -> Result<u64, ParserError> {
                 self.bump();
 
                 // A leading '0' must be the only digit before the decimal point.
-                if let '0' ... '9' = self.ch_or_null() {
+                if let '0' ..= '9' = self.ch_or_null() {
                     return self.error(InvalidNumber)
                 }
             },
-            '1' ... '9' => {
+            '1' ..= '9' => {
                 while !self.eof() {
                     match self.ch_or_null() {
-                        c @ '0' ... '9' => {
+                        c @ '0' ..= '9' => {
                             accum = accum.wrapping_mul(10);
                             accum = accum.wrapping_add((c as u64) - ('0' as u64));
 
@@ -1588,14 +1588,14 @@ fn parse_decimal(&mut self, mut res: f64) -> Result<f64, ParserError> {
 
         // Make sure a digit follows the decimal place.
         match self.ch_or_null() {
-            '0' ... '9' => (),
+            '0' ..= '9' => (),
              _ => return self.error(InvalidNumber)
         }
 
         let mut dec = 1.0;
         while !self.eof() {
             match self.ch_or_null() {
-                c @ '0' ... '9' => {
+                c @ '0' ..= '9' => {
                     dec /= 10.0;
                     res += (((c as isize) - ('0' as isize)) as f64) * dec;
                     self.bump();
@@ -1622,12 +1622,12 @@ fn parse_exponent(&mut self, mut res: f64) -> Result<f64, ParserError> {
 
         // Make sure a digit follows the exponent place.
         match self.ch_or_null() {
-            '0' ... '9' => (),
+            '0' ..= '9' => (),
             _ => return self.error(InvalidNumber)
         }
         while !self.eof() {
             match self.ch_or_null() {
-                c @ '0' ... '9' => {
+                c @ '0' ..= '9' => {
                     exp *= 10;
                     exp += (c as usize) - ('0' as usize);
 
@@ -1653,7 +1653,7 @@ fn decode_hex_escape(&mut self) -> Result<u16, ParserError> {
         while i < 4 && !self.eof() {
             self.bump();
             n = match self.ch_or_null() {
-                c @ '0' ... '9' => n * 16 + ((c as u16) - ('0' as u16)),
+                c @ '0' ..= '9' => n * 16 + ((c as u16) - ('0' as u16)),
                 'a' | 'A' => n * 16 + 10,
                 'b' | 'B' => n * 16 + 11,
                 'c' | 'C' => n * 16 + 12,
@@ -1695,13 +1695,13 @@ fn parse_str(&mut self) -> Result<string::String, ParserError> {
                     'r' => res.push('\r'),
                     't' => res.push('\t'),
                     'u' => match self.decode_hex_escape()? {
-                        0xDC00 ... 0xDFFF => {
+                        0xDC00 ..= 0xDFFF => {
                             return self.error(LoneLeadingSurrogateInHexEscape)
                         }
 
                         // Non-BMP characters are encoded as a sequence of
                         // two hex escapes, representing UTF-16 surrogates.
-                        n1 @ 0xD800 ... 0xDBFF => {
+                        n1 @ 0xD800 ..= 0xDBFF => {
                             match (self.next_char(), self.next_char()) {
                                 (Some('\\'), Some('u')) => (),
                                 _ => return self.error(UnexpectedEndOfHexEscape),
@@ -1928,7 +1928,7 @@ fn parse_value(&mut self) -> JsonEvent {
             'n' => { self.parse_ident("ull", NullValue) }
             't' => { self.parse_ident("rue", BooleanValue(true)) }
             'f' => { self.parse_ident("alse", BooleanValue(false)) }
-            '0' ... '9' | '-' => self.parse_number(),
+            '0' ..= '9' | '-' => self.parse_number(),
             '"' => match self.parse_str() {
                 Ok(s) => StringValue(s),
                 Err(e) => Error(e),
index 1786e2960825dfb7b6340c8c8a84872fc2c21a2c..ae7f25c7fedbe43ecfbe5c82de45b8ab4d8c0e85 100644 (file)
@@ -9,12 +9,8 @@
 // except according to those terms.
 
 #[inline]
-pub fn write_to_vec(vec: &mut Vec<u8>, position: usize, byte: u8) {
-    if position == vec.len() {
-        vec.push(byte);
-    } else {
-        vec[position] = byte;
-    }
+pub fn write_to_vec(vec: &mut Vec<u8>, byte: u8) {
+    vec.push(byte);
 }
 
 #[cfg(target_pointer_width = "32")]
@@ -33,8 +29,7 @@ macro_rules! leb128_size {
 macro_rules! impl_write_unsigned_leb128 {
     ($fn_name:ident, $int_ty:ident) => (
         #[inline]
-        pub fn $fn_name(out: &mut Vec<u8>, start_position: usize, mut value: $int_ty) -> usize {
-            let mut position = start_position;
+        pub fn $fn_name(out: &mut Vec<u8>, mut value: $int_ty) {
             for _ in 0 .. leb128_size!($int_ty) {
                 let mut byte = (value & 0x7F) as u8;
                 value >>= 7;
@@ -42,15 +37,12 @@ pub fn $fn_name(out: &mut Vec<u8>, start_position: usize, mut value: $int_ty) ->
                     byte |= 0x80;
                 }
 
-                write_to_vec(out, position, byte);
-                position += 1;
+                write_to_vec(out, byte);
 
                 if value == 0 {
                     break;
                 }
             }
-
-            position - start_position
         }
     )
 }
@@ -105,11 +97,9 @@ pub fn $fn_name(slice: &[u8]) -> ($int_ty, usize) {
 /// The callback `write` is called once for each position
 /// that is to be written to with the byte to be encoded
 /// at that position.
-pub fn write_signed_leb128_to<W>(mut value: i128, mut write: W) -> usize
-    where W: FnMut(usize, u8)
+pub fn write_signed_leb128_to<W>(mut value: i128, mut write: W)
+    where W: FnMut(u8)
 {
-    let mut position = 0;
-
     loop {
         let mut byte = (value as u8) & 0x7f;
         value >>= 7;
@@ -120,18 +110,16 @@ pub fn write_signed_leb128_to<W>(mut value: i128, mut write: W) -> usize
             byte |= 0x80; // Mark this byte to show that more bytes will follow.
         }
 
-        write(position, byte);
-        position += 1;
+        write(byte);
 
         if !more {
             break;
         }
     }
-    position
 }
 
-pub fn write_signed_leb128(out: &mut Vec<u8>, start_position: usize, value: i128) -> usize {
-    write_signed_leb128_to(value, |i, v| write_to_vec(out, start_position+i, v))
+pub fn write_signed_leb128(out: &mut Vec<u8>, value: i128) {
+    write_signed_leb128_to(value, |v| write_to_vec(out, v))
 }
 
 #[inline]
@@ -167,9 +155,7 @@ fn $test_name() {
             let mut stream = Vec::new();
 
             for x in 0..62 {
-                let pos = stream.len();
-                let bytes_written = $write_fn_name(&mut stream, pos, (3u64 << x) as $int_ty);
-                assert_eq!(stream.len(), pos + bytes_written);
+                $write_fn_name(&mut stream, (3u64 << x) as $int_ty);
             }
 
             let mut position = 0;
@@ -195,9 +181,7 @@ fn test_signed_leb128() {
     let values: Vec<_> = (-500..500).map(|i| i * 0x12345789ABCDEF).collect();
     let mut stream = Vec::new();
     for &x in &values {
-        let pos = stream.len();
-        let bytes_written = write_signed_leb128(&mut stream, pos, x);
-        assert_eq!(stream.len(), pos + bytes_written);
+        write_signed_leb128(&mut stream, x);
     }
     let mut pos = 0;
     for &x in &values {
index 22d27b6697a7c8973257ba0c4de88528971f82d4..a5f4b32b329e7c22a51c791035a9cb05d168076d 100644 (file)
@@ -23,6 +23,7 @@
 #![feature(box_syntax)]
 #![feature(core_intrinsics)]
 #![feature(specialization)]
+#![feature(never_type)]
 #![cfg_attr(test, feature(test))]
 
 pub use self::serialize::{Decoder, Encoder, Decodable, Encodable};
index 077efadd60af88823876634ce0524ee0311f060a..a77d1d9b88b89a0e048c6f8123de8386ef727a98 100644 (file)
 
 use leb128::{self, read_signed_leb128, write_signed_leb128};
 use std::borrow::Cow;
-use std::io::{self, Write};
 use serialize;
 
 // -----------------------------------------------------------------------------
 // Encoder
 // -----------------------------------------------------------------------------
 
-pub type EncodeResult = io::Result<()>;
+pub type EncodeResult = Result<(), !>;
 
-pub struct Encoder<'a> {
-    pub cursor: &'a mut io::Cursor<Vec<u8>>,
+pub struct Encoder {
+    pub data: Vec<u8>,
 }
 
-impl<'a> Encoder<'a> {
-    pub fn new(cursor: &'a mut io::Cursor<Vec<u8>>) -> Encoder<'a> {
-        Encoder { cursor: cursor }
+impl Encoder {
+    pub fn new(data: Vec<u8>) -> Encoder {
+        Encoder { data }
     }
 
-    pub fn emit_raw_bytes(&mut self, s: &[u8]) -> EncodeResult {
-        self.cursor.write_all(s)
+    pub fn into_inner(self) -> Vec<u8> {
+        self.data
     }
-}
 
+    pub fn emit_raw_bytes(&mut self, s: &[u8]) {
+        self.data.extend_from_slice(s);
+    }
+}
 
 macro_rules! write_uleb128 {
     ($enc:expr, $value:expr, $fun:ident) => {{
-        let pos = $enc.cursor.position() as usize;
-        let bytes_written = leb128::$fun($enc.cursor.get_mut(), pos, $value);
-        $enc.cursor.set_position((pos + bytes_written) as u64);
+        leb128::$fun(&mut $enc.data, $value);
         Ok(())
     }}
 }
 
 macro_rules! write_sleb128 {
     ($enc:expr, $value:expr) => {{
-        let pos = $enc.cursor.position() as usize;
-        let bytes_written = write_signed_leb128($enc.cursor.get_mut(), pos, $value as i128);
-        $enc.cursor.set_position((pos + bytes_written) as u64);
+        write_signed_leb128(&mut $enc.data, $value as i128);
         Ok(())
     }}
 }
 
-impl<'a> serialize::Encoder for Encoder<'a> {
-    type Error = io::Error;
+impl serialize::Encoder for Encoder {
+    type Error = !;
 
     #[inline]
     fn emit_nil(&mut self) -> EncodeResult {
@@ -87,9 +85,7 @@ fn emit_u16(&mut self, v: u16) -> EncodeResult {
 
     #[inline]
     fn emit_u8(&mut self, v: u8) -> EncodeResult {
-        let pos = self.cursor.position() as usize;
-        leb128::write_to_vec(self.cursor.get_mut(), pos, v);
-        self.cursor.set_position((pos + 1) as u64);
+        self.data.push(v);
         Ok(())
     }
 
@@ -153,15 +149,15 @@ fn emit_char(&mut self, v: char) -> EncodeResult {
     #[inline]
     fn emit_str(&mut self, v: &str) -> EncodeResult {
         self.emit_usize(v.len())?;
-        let _ = self.cursor.write_all(v.as_bytes());
+        self.emit_raw_bytes(v.as_bytes());
         Ok(())
     }
 }
 
-impl<'a> Encoder<'a> {
+impl Encoder {
     #[inline]
     pub fn position(&self) -> usize {
-        self.cursor.position() as usize
+        self.data.len()
     }
 }
 
@@ -339,7 +335,6 @@ fn error(&mut self, err: &str) -> Self::Error {
 #[cfg(test)]
 mod tests {
     use serialize::{Encodable, Decodable};
-    use std::io::Cursor;
     use std::fmt::Debug;
     use super::{Encoder, Decoder};
 
@@ -368,14 +363,13 @@ struct Struct {
 
 
     fn check_round_trip<T: Encodable + Decodable + PartialEq + Debug>(values: Vec<T>) {
-        let mut cursor = Cursor::new(Vec::new());
+        let mut encoder = Encoder::new(Vec::new());
 
         for value in &values {
-            let mut encoder = Encoder::new(&mut cursor);
             Encodable::encode(&value, &mut encoder).unwrap();
         }
 
-        let data = cursor.into_inner();
+        let data = encoder.into_inner();
         let mut decoder = Decoder::new(&data[..], 0);
 
         for value in values {
index 2da775fdc949e20f0be1cefcfddbe2333881aa26..c1cc36f3b419a2364eeef8c4df4d608e075d1a06 100644 (file)
@@ -43,7 +43,7 @@ impl<T: Generator<Yield = ()>> !Unpin for GenFuture<T> {}
 impl<T: Generator<Yield = ()>> Future for GenFuture<T> {
     type Output = T::Return;
     fn poll(self: PinMut<Self>, cx: &mut task::Context) -> Poll<Self::Output> {
-        set_task_cx(cx, || match unsafe { PinMut::get_mut(self).0.resume() } {
+        set_task_cx(cx, || match unsafe { PinMut::get_mut_unchecked(self).0.resume() } {
             GeneratorState::Yielded(()) => Poll::Pending,
             GeneratorState::Complete(x) => Poll::Ready(x),
         })
index a856e7736fbaab1e2882827dcbabb77a4b15d55b..75f038407c12714d52729f1d29e77014282e04ba 100644 (file)
 /// The multi-argument form of this macro panics with a string and has the
 /// [`format!`] syntax for building a string.
 ///
+/// See also the macro [`compile_error!`], for raising errors during compilation.
+///
 /// [runwrap]: ../std/result/enum.Result.html#method.unwrap
 /// [`Option`]: ../std/option/enum.Option.html#method.unwrap
 /// [`Result`]: ../std/result/enum.Result.html
 /// [`format!`]: ../std/macro.format.html
+/// [`compile_error!`]: ../std/macro.compile_error.html
 /// [book]: ../book/second-edition/ch09-01-unrecoverable-errors-with-panic.html
 ///
 /// # Current implementation
@@ -305,13 +308,16 @@ pub mod builtin {
     /// Unconditionally causes compilation to fail with the given error message when encountered.
     ///
     /// This macro should be used when a crate uses a conditional compilation strategy to provide
-    /// better error messages for erroneous conditions.
+    /// better error messages for erroneous conditions. It's the compiler-level form of [`panic!`],
+    /// which emits an error at *runtime*, rather than during compilation.
     ///
     /// # Examples
     ///
     /// Two such examples are macros and `#[cfg]` environments.
     ///
-    /// Emit better compiler error if a macro is passed invalid values.
+    /// Emit better compiler error if a macro is passed invalid values. Without the final branch,
+    /// the compiler would still emit an error, but the error's message would not mention the two
+    /// valid values.
     ///
     /// ```compile_fail
     /// macro_rules! give_me_foo_or_bar {
@@ -332,6 +338,8 @@ pub mod builtin {
     /// #[cfg(not(any(feature = "foo", feature = "bar")))]
     /// compile_error!("Either feature \"foo\" or \"bar\" must be enabled for this crate.")
     /// ```
+    ///
+    /// [`panic!`]: ../std/macro.panic.html
     #[stable(feature = "compile_error_macro", since = "1.20.0")]
     #[macro_export]
     macro_rules! compile_error {
index 2c11c262488b2d04f396ea37e74d9e785971b4f0..451420ae88ad8179f1ec1f37efaad1a458bf13fb 100644 (file)
@@ -327,14 +327,9 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
 impl<'a, F: Future> Future for AssertUnwindSafe<F> {
     type Output = F::Output;
 
-    fn poll(mut self: PinMut<Self>, cx: &mut task::Context) -> Poll<Self::Output> {
-        unsafe {
-            let pinned_field = PinMut::new_unchecked(
-                &mut PinMut::get_mut(self.reborrow()).0
-            );
-
-            pinned_field.poll(cx)
-        }
+    fn poll(self: PinMut<Self>, cx: &mut task::Context) -> Poll<Self::Output> {
+        let pinned_field = unsafe { PinMut::map_unchecked(self, |x| &mut x.0) };
+        pinned_field.poll(cx)
     }
 }
 
index 1231898ed7eba0051edc90b95fd0babf9ee7aece..c44db3b10722494e4e925987dff53a206bd378b8 100644 (file)
@@ -67,6 +67,7 @@
         // (missing things in `libc` which is empty) so just omit everything
         // with an empty module
         #[unstable(issue = "0", feature = "std_internals")]
+        #[allow(missing_docs)]
         pub mod unix_ext {}
     } else {
         // On other platforms like Windows document the bare bones of unix
@@ -80,11 +81,13 @@ pub mod unix_ext {}
 cfg_if! {
     if #[cfg(windows)] {
         // On windows we'll just be documenting what's already available
+        #[allow(missing_docs)]
         pub use self::ext as windows_ext;
     } else if #[cfg(any(target_os = "cloudabi", target_arch = "wasm32"))] {
         // On CloudABI and wasm right now the shim below doesn't compile, so
         // just omit it
         #[unstable(issue = "0", feature = "std_internals")]
+        #[allow(missing_docs)]
         pub mod windows_ext {}
     } else {
         // On all other platforms (aka linux/osx/etc) then pull in a "minimal"
index e186b115821649d37155da058a835f2bff6425b0..662a76d6725a68d7bb3493c7229330d446e1dd80 100644 (file)
@@ -803,7 +803,7 @@ pub fn stat(p: &Path) -> io::Result<FileAttr> {
     let p = cstr(p)?;
     let mut stat: stat64 = unsafe { mem::zeroed() };
     cvt(unsafe {
-        stat64(p.as_ptr(), &mut stat as *mut _ as *mut _)
+        stat64(p.as_ptr(), &mut stat)
     })?;
     Ok(FileAttr { stat: stat })
 }
@@ -812,7 +812,7 @@ pub fn lstat(p: &Path) -> io::Result<FileAttr> {
     let p = cstr(p)?;
     let mut stat: stat64 = unsafe { mem::zeroed() };
     cvt(unsafe {
-        lstat64(p.as_ptr(), &mut stat as *mut _ as *mut _)
+        lstat64(p.as_ptr(), &mut stat)
     })?;
     Ok(FileAttr { stat: stat })
 }
index 3f7f06714908428ee990b89fe15c483fe890d8ec..01c0ada4ffbe531f227fbaec9858831bb56b6367 100644 (file)
@@ -183,34 +183,10 @@ pub fn fill_bytes(v: &mut [u8]) {
 mod imp {
     #[link(name = "zircon")]
     extern {
-        fn zx_cprng_draw_new(buffer: *mut u8, len: usize) -> i32;
-    }
-
-    fn getrandom(buf: &mut [u8]) -> Result<usize, i32> {
-        unsafe {
-            let status = zx_cprng_draw_new(buf.as_mut_ptr(), buf.len());
-            if status == 0 {
-                Ok(buf.len())
-            } else {
-                Err(status)
-            }
-        }
+        fn zx_cprng_draw(buffer: *mut u8, len: usize);
     }
 
     pub fn fill_bytes(v: &mut [u8]) {
-        let mut buf = v;
-        while !buf.is_empty() {
-            let ret = getrandom(buf);
-            match ret {
-                Err(err) => {
-                    panic!("kernel zx_cprng_draw call failed! (returned {}, buf.len() {})",
-                        err, buf.len())
-                }
-                Ok(actual) => {
-                    let move_buf = buf;
-                    buf = &mut move_buf[(actual as usize)..];
-                }
-            }
-        }
+        unsafe { zx_cprng_draw(v.as_mut_ptr(), v.len()) }
     }
 }
index 20109d2d0d5aceb5790c6d063c7c6d9b331e72eb..61d7ed463dd3856010c89f9ab624602fb0708b26 100644 (file)
@@ -263,7 +263,7 @@ pub fn demangle(writer: &mut Write, mut s: &str, format: PrintFormat) -> io::Res
         let candidate = &s[i + llvm.len()..];
         let all_hex = candidate.chars().all(|c| {
             match c {
-                'A' ... 'F' | '0' ... '9' => true,
+                'A' ..= 'F' | '0' ..= '9' => true,
                 _ => false,
             }
         });
index 14a2555adf9baa109e7d7afe08bbea07e685826a..bbb5980bd9da6e6f112685931325191ff120a14c 100644 (file)
@@ -76,7 +76,7 @@ pub unsafe fn from_u32_unchecked(value: u32) -> CodePoint {
     #[inline]
     pub fn from_u32(value: u32) -> Option<CodePoint> {
         match value {
-            0 ... 0x10FFFF => Some(CodePoint { value: value }),
+            0 ..= 0x10FFFF => Some(CodePoint { value: value }),
             _ => None
         }
     }
@@ -101,7 +101,7 @@ pub fn to_u32(&self) -> u32 {
     #[inline]
     pub fn to_char(&self) -> Option<char> {
         match self.value {
-            0xD800 ... 0xDFFF => None,
+            0xD800 ..= 0xDFFF => None,
             _ => Some(unsafe { char::from_u32_unchecked(self.value) })
         }
     }
@@ -305,7 +305,7 @@ pub fn push_char(&mut self, c: char) {
     /// like concatenating ill-formed UTF-16 strings effectively would.
     #[inline]
     pub fn push(&mut self, code_point: CodePoint) {
-        if let trail @ 0xDC00...0xDFFF = code_point.to_u32() {
+        if let trail @ 0xDC00..=0xDFFF = code_point.to_u32() {
             if let Some(lead) = (&*self).final_lead_surrogate() {
                 let len_without_lead_surrogate = self.len() - 3;
                 self.bytes.truncate(len_without_lead_surrogate);
@@ -525,7 +525,7 @@ pub fn is_empty(&self) -> bool {
     #[inline]
     pub fn ascii_byte_at(&self, position: usize) -> u8 {
         match self.bytes[position] {
-            ascii_byte @ 0x00 ... 0x7F => ascii_byte,
+            ascii_byte @ 0x00 ..= 0x7F => ascii_byte,
             _ => 0xFF
         }
     }
@@ -630,7 +630,7 @@ fn final_lead_surrogate(&self) -> Option<u16> {
             return None
         }
         match &self.bytes[(len - 3)..] {
-            &[0xED, b2 @ 0xA0...0xAF, b3] => Some(decode_surrogate(b2, b3)),
+            &[0xED, b2 @ 0xA0..=0xAF, b3] => Some(decode_surrogate(b2, b3)),
             _ => None
         }
     }
@@ -642,7 +642,7 @@ fn initial_trail_surrogate(&self) -> Option<u16> {
             return None
         }
         match &self.bytes[..3] {
-            &[0xED, b2 @ 0xB0...0xBF, b3] => Some(decode_surrogate(b2, b3)),
+            &[0xED, b2 @ 0xB0..=0xBF, b3] => Some(decode_surrogate(b2, b3)),
             _ => None
         }
     }
index a57a9b95e5f776f3ad616aec9bc8de95cd7573a5..53465c071f33a1db651f031967010d4b513baca4 100644 (file)
@@ -617,7 +617,7 @@ pub enum PatKind {
     /// A literal
     Lit(P<Expr>),
     /// A range pattern, e.g. `1...2`, `1..=2` or `1..2`
-    Range(P<Expr>, P<Expr>, RangeEnd),
+    Range(P<Expr>, P<Expr>, Spanned<RangeEnd>),
     /// `[a, b, ..i, y, z]` is represented as:
     ///     `PatKind::Slice(box [a, b], Some(i), box [y, z])`
     Slice(Vec<P<Pat>>, Option<P<Pat>>, Vec<P<Pat>>),
@@ -843,11 +843,11 @@ pub struct Local {
 
 /// An arm of a 'match'.
 ///
-/// E.g. `0...10 => { println!("match!") }` as in
+/// E.g. `0..=10 => { println!("match!") }` as in
 ///
 /// ```
 /// match 123 {
-///     0...10 => { println!("match!") },
+///     0..=10 => { println!("match!") },
 ///     _ => { println!("no match!") },
 /// }
 /// ```
index 16d786dd6cad2f76450618c0c917a80991d12e36..9afce74f53cc4001fcccb6b1635e244061163467 100644 (file)
@@ -621,6 +621,9 @@ pub enum SyntaxExtension {
         /// Whether the contents of the macro can use `unsafe`
         /// without triggering the `unsafe_code` lint.
         allow_internal_unsafe: bool,
+        /// Enables the macro helper hack (`ident!(...)` -> `$crate::ident!(...)`)
+        /// for a given macro.
+        local_inner_macros: bool,
         /// The macro's feature name if it is unstable, and the stability feature
         unstable_feature: Option<(Symbol, u32)>,
         /// Edition of the crate in which the macro is defined
index 940fb6405f1b6065c170dfd7d7abc5ec9fdfd006..32ace937ac0067c1b424c04d548a91223f169b81 100644 (file)
@@ -64,6 +64,7 @@ pub fn add_derived_markers<T>(cx: &mut ExtCtxt, span: Span, traits: &[ast::Path]
         format: ExpnFormat::MacroAttribute(Symbol::intern(&pretty_name)),
         allow_internal_unstable: true,
         allow_internal_unsafe: false,
+        local_inner_macros: false,
         edition: hygiene::default_edition(),
     });
 
index 69c99c63aafe3e55692d41ec91785063c00879c4..23880c1270f9d1462c51f70155699c62d1dacecf 100644 (file)
@@ -542,6 +542,7 @@ fn expand_attr_invoc(&mut self,
             format: MacroAttribute(Symbol::intern(&format!("{}", attr.path))),
             allow_internal_unstable: false,
             allow_internal_unsafe: false,
+            local_inner_macros: false,
             edition: ext.edition(),
         });
 
@@ -695,6 +696,7 @@ fn expand_bang_invoc(&mut self,
                                           def_site_span: Option<Span>,
                                           allow_internal_unstable,
                                           allow_internal_unsafe,
+                                          local_inner_macros,
                                           // can't infer this type
                                           unstable_feature: Option<(Symbol, u32)>,
                                           edition| {
@@ -729,6 +731,7 @@ fn expand_bang_invoc(&mut self,
                 format: macro_bang_format(path),
                 allow_internal_unstable,
                 allow_internal_unsafe,
+                local_inner_macros,
                 edition,
             });
             Ok(())
@@ -737,7 +740,7 @@ fn expand_bang_invoc(&mut self,
         let opt_expanded = match *ext {
             DeclMacro(ref expand, def_span, edition) => {
                 if let Err(dummy_span) = validate_and_set_expn_info(self, def_span.map(|(_, s)| s),
-                                                                    false, false, None,
+                                                                    false, false, false, None,
                                                                     edition) {
                     dummy_span
                 } else {
@@ -750,12 +753,14 @@ fn expand_bang_invoc(&mut self,
                 def_info,
                 allow_internal_unstable,
                 allow_internal_unsafe,
+                local_inner_macros,
                 unstable_feature,
                 edition,
             } => {
                 if let Err(dummy_span) = validate_and_set_expn_info(self, def_info.map(|(_, s)| s),
                                                                     allow_internal_unstable,
                                                                     allow_internal_unsafe,
+                                                                    local_inner_macros,
                                                                     unstable_feature,
                                                                     edition) {
                     dummy_span
@@ -777,6 +782,7 @@ fn expand_bang_invoc(&mut self,
                         format: macro_bang_format(path),
                         allow_internal_unstable,
                         allow_internal_unsafe: false,
+                        local_inner_macros: false,
                         edition: hygiene::default_edition(),
                     });
 
@@ -816,6 +822,7 @@ fn expand_bang_invoc(&mut self,
                         // FIXME probably want to follow macro_rules macros here.
                         allow_internal_unstable,
                         allow_internal_unsafe: false,
+                        local_inner_macros: false,
                         edition,
                     });
 
@@ -890,6 +897,7 @@ fn expand_derive_invoc(&mut self,
             format: MacroAttribute(pretty_name),
             allow_internal_unstable: false,
             allow_internal_unsafe: false,
+            local_inner_macros: false,
             edition: ext.edition(),
         };
 
index 4ee5357f4766cc1186d36299a0e78f19e2d47d5e..3b3892729d93cdcc0315b36b7f8229e6b615642d 100644 (file)
@@ -286,6 +286,12 @@ pub fn compile(sess: &ParseSess, features: &Features, def: &ast::Item, edition:
     if body.legacy {
         let allow_internal_unstable = attr::contains_name(&def.attrs, "allow_internal_unstable");
         let allow_internal_unsafe = attr::contains_name(&def.attrs, "allow_internal_unsafe");
+        let mut local_inner_macros = false;
+        if let Some(macro_export) = attr::find_by_name(&def.attrs, "macro_export") {
+            if let Some(l) = macro_export.meta_item_list() {
+                local_inner_macros = attr::list_contains_name(&l, "local_inner_macros");
+            }
+        }
 
         let unstable_feature = attr::find_stability(&sess.span_diagnostic,
                                                     &def.attrs, def.span).and_then(|stability| {
@@ -301,6 +307,7 @@ pub fn compile(sess: &ParseSess, features: &Features, def: &ast::Item, edition:
             def_info: Some((def.id, def.span)),
             allow_internal_unstable,
             allow_internal_unsafe,
+            local_inner_macros,
             unstable_feature,
             edition,
         }
index ccb2f51f9641bd0d3a11c669b9e2e492bdacb7ed..c813ec1977b881bc00ee8cb3f6379af7f89c9c79 100644 (file)
@@ -28,6 +28,7 @@
 use rustc_target::spec::abi::Abi;
 use ast::{self, NodeId, PatKind, RangeEnd};
 use attr;
+use codemap::Spanned;
 use edition::{ALL_EDITIONS, Edition};
 use syntax_pos::{Span, DUMMY_SP};
 use errors::{DiagnosticBuilder, Handler, FatalError};
@@ -458,6 +459,9 @@ pub fn walk_feature_fields<F>(&self, mut f: F)
     // Scoped attributes
     (active, tool_attributes, "1.25.0", Some(44690), None),
 
+    // allow irrefutable patterns in if-let and while-let statements (RFC 2086)
+    (active, irrefutable_let_patterns, "1.27.0", Some(44495), None),
+
     // Allows use of the :literal macro fragment specifier (RFC 1576)
     (active, macro_literal_matcher, "1.27.0", Some(35625), None),
 
@@ -1749,7 +1753,7 @@ fn visit_pat(&mut self, pattern: &'a ast::Pat) {
                                   pattern.span,
                                   "box pattern syntax is experimental");
             }
-            PatKind::Range(_, _, RangeEnd::Excluded) => {
+            PatKind::Range(_, _, Spanned { node: RangeEnd::Excluded, .. }) => {
                 gate_feature_post!(&self, exclusive_range_pattern, pattern.span,
                                    "exclusive range pattern syntax is experimental");
             }
index ffea713f4ec76a359082178993b6fa09e1b5796e..712d00fde32db9293496c68b0716a1c064b56a83 100644 (file)
@@ -1137,10 +1137,10 @@ pub fn noop_fold_pat<T: Folder>(p: P<Pat>, folder: &mut T) -> P<Pat> {
             }
             PatKind::Box(inner) => PatKind::Box(folder.fold_pat(inner)),
             PatKind::Ref(inner, mutbl) => PatKind::Ref(folder.fold_pat(inner), mutbl),
-            PatKind::Range(e1, e2, end) => {
+            PatKind::Range(e1, e2, Spanned { span, node: end }) => {
                 PatKind::Range(folder.fold_expr(e1),
                                folder.fold_expr(e2),
-                               folder.fold_range_end(end))
+                               Spanned { span, node: folder.fold_range_end(end) })
             },
             PatKind::Slice(before, slice, after) => {
                 PatKind::Slice(before.move_map(|x| folder.fold_pat(x)),
index 5353ff9a1e13dd3c58950902b5879cf5dac31b2a..c09cfd910d207adf8efba17bf785781876fdc5c4 100644 (file)
@@ -266,7 +266,7 @@ fn err_span_(&self, from_pos: BytePos, to_pos: BytePos, m: &str) {
     /// Pushes a character to a message string for error reporting
     fn push_escaped_char_for_msg(m: &mut String, c: char) {
         match c {
-            '\u{20}'...'\u{7e}' => {
+            '\u{20}'..='\u{7e}' => {
                 // Don't escape \, ' or " for user-facing messages
                 m.push(c);
             }
@@ -779,7 +779,7 @@ fn scan_number(&mut self, c: char) -> token::Lit {
                     base = 16;
                     num_digits = self.scan_digits(16, 16);
                 }
-                '0'...'9' | '_' | '.' | 'e' | 'E' => {
+                '0'..='9' | '_' | '.' | 'e' | 'E' => {
                     num_digits = self.scan_digits(10, 10) + 1;
                 }
                 _ => {
index 955bdbdcf917765d8620b4a730070b1da4812d2e..21bd6c083244d0f8050d67dcf29bd313d5dee087 100644 (file)
@@ -4024,12 +4024,14 @@ fn parse_pat_with_range_pat(&mut self, allow_range_pat: bool) -> PResult<'a, P<P
                             _ => panic!("can only parse `..`/`...`/`..=` for ranges \
                                          (checked above)"),
                         };
+                        let op_span = self.span;
                         // Parse range
                         let span = lo.to(self.prev_span);
                         let begin = self.mk_expr(span, ExprKind::Path(qself, path), ThinVec::new());
                         self.bump();
                         let end = self.parse_pat_range_end()?;
-                        pat = PatKind::Range(begin, end, end_kind);
+                        let op = Spanned { span: op_span, node: end_kind };
+                        pat = PatKind::Range(begin, end, op);
                     }
                     token::OpenDelim(token::Brace) => {
                         if qself.is_some() {
@@ -4065,17 +4067,22 @@ fn parse_pat_with_range_pat(&mut self, allow_range_pat: bool) -> PResult<'a, P<P
                 // Try to parse everything else as literal with optional minus
                 match self.parse_literal_maybe_minus() {
                     Ok(begin) => {
-                        if self.eat(&token::DotDotDot) {
+                        let op_span = self.span;
+                        if self.check(&token::DotDot) || self.check(&token::DotDotEq) ||
+                                self.check(&token::DotDotDot) {
+                            let end_kind = if self.eat(&token::DotDotDot) {
+                                RangeEnd::Included(RangeSyntax::DotDotDot)
+                            } else if self.eat(&token::DotDotEq) {
+                                RangeEnd::Included(RangeSyntax::DotDotEq)
+                            } else if self.eat(&token::DotDot) {
+                                RangeEnd::Excluded
+                            } else {
+                                panic!("impossible case: we already matched \
+                                        on a range-operator token")
+                            };
                             let end = self.parse_pat_range_end()?;
-                            pat = PatKind::Range(begin, end,
-                                    RangeEnd::Included(RangeSyntax::DotDotDot));
-                        } else if self.eat(&token::DotDotEq) {
-                            let end = self.parse_pat_range_end()?;
-                            pat = PatKind::Range(begin, end,
-                                    RangeEnd::Included(RangeSyntax::DotDotEq));
-                        } else if self.eat(&token::DotDot) {
-                            let end = self.parse_pat_range_end()?;
-                            pat = PatKind::Range(begin, end, RangeEnd::Excluded);
+                            let op = Spanned { span: op_span, node: end_kind };
+                            pat = PatKind::Range(begin, end, op);
                         } else {
                             pat = PatKind::Lit(begin);
                         }
@@ -4096,7 +4103,9 @@ fn parse_pat_with_range_pat(&mut self, allow_range_pat: bool) -> PResult<'a, P<P
 
         if !allow_range_pat {
             match pat.node {
-                PatKind::Range(_, _, RangeEnd::Included(RangeSyntax::DotDotDot)) => {}
+                PatKind::Range(
+                    _, _, Spanned { node: RangeEnd::Included(RangeSyntax::DotDotDot), .. }
+                ) => {},
                 PatKind::Range(..) => {
                     let mut err = self.struct_span_err(
                         pat.span,
index 70c4324a056a0ff62028a7bddf1dcc234b81a1d6..3359225e1596595647c813057f791f73c1e9375e 100644 (file)
@@ -16,7 +16,7 @@
 use ast::{Attribute, MacDelimiter, GenericArg};
 use util::parser::{self, AssocOp, Fixity};
 use attr;
-use codemap::{self, CodeMap};
+use codemap::{self, CodeMap, Spanned};
 use syntax_pos::{self, BytePos};
 use syntax_pos::hygiene::{Mark, SyntaxContext};
 use parse::token::{self, BinOpToken, Token};
@@ -2624,7 +2624,7 @@ pub fn print_pat(&mut self, pat: &ast::Pat) -> io::Result<()> {
                 self.print_pat(inner)?;
             }
             PatKind::Lit(ref e) => self.print_expr(&**e)?,
-            PatKind::Range(ref begin, ref end, ref end_kind) => {
+            PatKind::Range(ref begin, ref end, Spanned { node: ref end_kind, .. }) => {
                 self.print_expr(begin)?;
                 self.s.space()?;
                 match *end_kind {
index 66e8e0d7a9c6c76e52dcaa0b0b850d62cce71ba9..68121d42b69c64698bb4dd07a2684b85fb25b075 100644 (file)
@@ -29,6 +29,7 @@ fn ignored_span(sp: Span) -> Span {
         format: MacroAttribute(Symbol::intern("std_inject")),
         allow_internal_unstable: true,
         allow_internal_unsafe: false,
+        local_inner_macros: false,
         edition: hygiene::default_edition(),
     });
     sp.with_ctxt(SyntaxContext::empty().apply_mark(mark))
index 141fd122ff57b6647cea156804d3da4b15322f8b..51fbe34028e8f66b8af6cdb48eadef73bf684bde 100644 (file)
@@ -311,6 +311,7 @@ fn generate_test_harness(sess: &ParseSess,
         format: MacroAttribute(Symbol::intern("test")),
         allow_internal_unstable: true,
         allow_internal_unsafe: false,
+        local_inner_macros: false,
         edition: hygiene::default_edition(),
     });
 
index 0dd8f0c55d8d496b668c25704ed99a84f231f8cc..2393af76c340b9e13f10caf5081a42f17bbab480 100644 (file)
@@ -374,7 +374,7 @@ macro_rules! move_to {
 
         if let Start = state {
             match c {
-                '1'...'9' => {
+                '1'..='9' => {
                     let end = at_next_cp_while(next, is_digit);
                     match end.next_cp() {
                         // Yes, this *is* the parameter.
@@ -416,7 +416,7 @@ macro_rules! move_to {
                     state = WidthArg;
                     move_to!(next);
                 },
-                '1' ... '9' => {
+                '1' ..= '9' => {
                     let end = at_next_cp_while(next, is_digit);
                     state = Prec;
                     width = Some(Num::from_str(at.slice_between(end).unwrap(), None));
@@ -477,7 +477,7 @@ macro_rules! move_to {
                         }
                     }
                 },
-                '0' ... '9' => {
+                '0' ..= '9' => {
                     let end = at_next_cp_while(next, is_digit);
                     state = Length;
                     precision = Some(Num::from_str(at.slice_between(end).unwrap(), None));
@@ -570,7 +570,7 @@ fn at_next_cp_while<F>(mut cur: Cur, mut pred: F) -> Cur
 
     fn is_digit(c: char) -> bool {
         match c {
-            '0' ... '9' => true,
+            '0' ..= '9' => true,
             _ => false
         }
     }
@@ -799,7 +799,7 @@ pub fn parse_next_substitution(s: &str) -> Option<(Substitution, &str)> {
             let start = s.find('$')?;
             match s[start+1..].chars().next()? {
                 '$' => return Some((Substitution::Escape, &s[start+2..])),
-                c @ '0' ... '9' => {
+                c @ '0' ..= '9' => {
                     let n = (c as u8) - b'0';
                     return Some((Substitution::Ordinal(n), &s[start+2..]));
                 },
@@ -836,14 +836,14 @@ fn at_next_cp_while<F>(mut cur: Cur, mut pred: F) -> Cur
 
     fn is_ident_head(c: char) -> bool {
         match c {
-            'a' ... 'z' | 'A' ... 'Z' | '_' => true,
+            'a' ..= 'z' | 'A' ..= 'Z' | '_' => true,
             _ => false
         }
     }
 
     fn is_ident_tail(c: char) -> bool {
         match c {
-            '0' ... '9' => true,
+            '0' ..= '9' => true,
             c => is_ident_head(c)
         }
     }
index af3ef181c59dc9a7808e97cf198b6f769b258d84..311251832664e960e25285aee14d6c6bb80c3233 100644 (file)
@@ -76,6 +76,7 @@ macro_rules! register {
                         def_info: None,
                         allow_internal_unstable: false,
                         allow_internal_unsafe: false,
+                        local_inner_macros: false,
                         unstable_feature: None,
                         edition: hygiene::default_edition(),
                     });
@@ -132,6 +133,7 @@ macro_rules! register {
                 def_info: None,
                 allow_internal_unstable: true,
                 allow_internal_unsafe: false,
+                local_inner_macros: false,
                 unstable_feature: None,
                 edition: hygiene::default_edition(),
             });
index ee343e47bd8905c5d44c4ce6bee4bdc892df6879..ef29e5a6b022b624498854b93e13b4d81be48a22 100644 (file)
@@ -368,6 +368,7 @@ fn mk_registrar(cx: &mut ExtCtxt,
         format: MacroAttribute(Symbol::intern("proc_macro")),
         allow_internal_unstable: true,
         allow_internal_unsafe: false,
+        local_inner_macros: false,
         edition: hygiene::default_edition(),
     });
     let span = DUMMY_SP.apply_mark(mark);
index 08b7f7c76cb65782f76a38d23538e65d32cce809..d1b9c7a84d16f21330508244ade40026df5b4ce0 100644 (file)
@@ -496,6 +496,9 @@ pub struct ExpnInfo {
     /// Whether the macro is allowed to use `unsafe` internally
     /// even if the user crate has `#![forbid(unsafe_code)]`.
     pub allow_internal_unsafe: bool,
+    /// Enables the macro helper hack (`ident!(...)` -> `$crate::ident!(...)`)
+    /// for a given macro.
+    pub local_inner_macros: bool,
     /// Edition of the crate in which the macro is defined.
     pub edition: Edition,
 }
@@ -540,7 +543,7 @@ pub fn name(self) -> Symbol {
             CompilerDesugaringKind::DotFill => "...",
             CompilerDesugaringKind::QuestionMark => "?",
             CompilerDesugaringKind::Catch => "do catch",
-            CompilerDesugaringKind::ExistentialReturnType => "existental type",
+            CompilerDesugaringKind::ExistentialReturnType => "existential type",
         })
     }
 }
index a4fb9571ecbe9a75e260e9c40be19a74ceb9815d..756e0c059a729a57ddf00b52c78a43cbfc31901d 100644 (file)
@@ -818,8 +818,8 @@ fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
                     };
 
                     let bytes_per_diff: u8 = match max_line_length {
-                        0 ... 0xFF => 1,
-                        0x100 ... 0xFFFF => 2,
+                        0 ..= 0xFF => 1,
+                        0x100 ..= 0xFFFF => 2,
                         _ => 4
                     };
 
index bd5ab92e8b078fd14d9b873351a3f8ac5e2e2949..b720d55594fd17f5e4ad89f4ac0820b5f91a5758 100644 (file)
@@ -215,7 +215,7 @@ pub fn expand(cap: &[u8], params: &[Param], vars: &mut Variables) -> Result<Vec<
                             return Err("stack is empty".to_string());
                         }
                     }
-                    ':' | '#' | ' ' | '.' | '0'...'9' => {
+                    ':' | '#' | ' ' | '.' | '0'..='9' => {
                         let mut flags = Flags::new();
                         let mut fstate = FormatStateFlags;
                         match cur {
@@ -223,7 +223,7 @@ pub fn expand(cap: &[u8], params: &[Param], vars: &mut Variables) -> Result<Vec<
                             '#' => flags.alternate = true,
                             ' ' => flags.space = true,
                             '.' => fstate = FormatStatePrecision,
-                            '0'...'9' => {
+                            '0'..='9' => {
                                 flags.width = cur as usize - '0' as usize;
                                 fstate = FormatStateWidth;
                             }
@@ -337,14 +337,14 @@ pub fn expand(cap: &[u8], params: &[Param], vars: &mut Variables) -> Result<Vec<
                     (FormatStateFlags, ' ') => {
                         flags.space = true;
                     }
-                    (FormatStateFlags, '0'...'9') => {
+                    (FormatStateFlags, '0'..='9') => {
                         flags.width = cur as usize - '0' as usize;
                         *fstate = FormatStateWidth;
                     }
                     (FormatStateFlags, '.') => {
                         *fstate = FormatStatePrecision;
                     }
-                    (FormatStateWidth, '0'...'9') => {
+                    (FormatStateWidth, '0'..='9') => {
                         let old = flags.width;
                         flags.width = flags.width * 10 + (cur as usize - '0' as usize);
                         if flags.width < old {
@@ -354,7 +354,7 @@ pub fn expand(cap: &[u8], params: &[Param], vars: &mut Variables) -> Result<Vec<
                     (FormatStateWidth, '.') => {
                         *fstate = FormatStatePrecision;
                     }
-                    (FormatStatePrecision, '0'...'9') => {
+                    (FormatStatePrecision, '0'..='9') => {
                         let old = flags.precision;
                         flags.precision = flags.precision * 10 + (cur as usize - '0' as usize);
                         if flags.precision < old {
index 64afd702f5d82cd50a49cfa1819ab2f72ff658d0..7daf0d3c4e29758522cab5cd06e86d4dc2b1c120 100644 (file)
@@ -14,7 +14,7 @@ fn main() {
     let _: <<A>::B>::C; //~ ERROR cannot find type `A` in this scope
     let _ = <<A>::B>::C; //~ ERROR cannot find type `A` in this scope
     let <<A>::B>::C; //~ ERROR cannot find type `A` in this scope
-    let 0 ... <<A>::B>::C; //~ ERROR cannot find type `A` in this scope
+    let 0 ..= <<A>::B>::C; //~ ERROR cannot find type `A` in this scope
                            //~^ ERROR only char and numeric types are allowed in range patterns
     <<A>::B>::C; //~ ERROR cannot find type `A` in this scope
 }
index 847a82c082651f1a4550cc7bfc34aefa873f2fa3..7c76cf475d29afe415b27502c5451252a11eb354 100644 (file)
@@ -18,6 +18,6 @@ impl Trait for Foo {}
 pub fn main() {
     let x: Box<Trait> = Box::new(Foo);
     let _y: &Trait = x; //~ ERROR E0308
-                        //~| expected type `&Trait`
-                        //~| found type `std::boxed::Box<Trait>`
+                        //~| expected type `&dyn Trait`
+                        //~| found type `std::boxed::Box<dyn Trait>`
 }
index 09bd3a2fc57d97a4f02744a84621c97622f16baa..b5acdc12ca048679c0f8ebe259a77995c66e02a0 100644 (file)
@@ -33,23 +33,23 @@ fn main() {
     let &&x = &&(&1isize as &T);
 
     // n == m
-    let &x = &1isize as &T;      //~ ERROR type `&T` cannot be dereferenced
-    let &&x = &(&1isize as &T);  //~ ERROR type `&T` cannot be dereferenced
-    let box x = box 1isize as Box<T>; //~ ERROR type `std::boxed::Box<T>` cannot be dereferenced
+    let &x = &1isize as &T;      //~ ERROR type `&dyn T` cannot be dereferenced
+    let &&x = &(&1isize as &T);  //~ ERROR type `&dyn T` cannot be dereferenced
+    let box x = box 1isize as Box<T>; //~ ERROR type `std::boxed::Box<dyn T>` cannot be dereferenced
 
     // n > m
     let &&x = &1isize as &T;
     //~^ ERROR mismatched types
-    //~| expected type `T`
+    //~| expected type `dyn T`
     //~| found type `&_`
     //~| expected trait T, found reference
     let &&&x = &(&1isize as &T);
     //~^ ERROR mismatched types
-    //~| expected type `T`
+    //~| expected type `dyn T`
     //~| found type `&_`
     //~| expected trait T, found reference
     let box box x = box 1isize as Box<T>;
     //~^ ERROR mismatched types
-    //~| expected type `T`
+    //~| expected type `dyn T`
     //~| found type `std::boxed::Box<_>`
 }
index 5bc6c6cda263afe3ca4762d48c83bd742198d714..2a209a2959bfd7bf08c84b4338d92a636de68c28 100644 (file)
@@ -42,7 +42,7 @@ pub fn main() {
     let z: Box<ToBar> = Box::new(Bar1 {f: 36});
     f5.2 = Bar1 {f: 36};
     //~^ ERROR mismatched types
-    //~| expected type `ToBar`
+    //~| expected type `dyn ToBar`
     //~| found type `Bar1`
     //~| expected trait ToBar, found struct `Bar1`
     //~| ERROR the size for value values of type
index 37b6056d1a762328eea2d61e52f245bdbd109547..e28586c4755e872320a026ee9b195ab5b623e1d6 100644 (file)
@@ -44,7 +44,7 @@ pub fn main() {
     let z: Box<ToBar> = Box::new(Bar1 {f: 36});
     f5.ptr = Bar1 {f: 36};
     //~^ ERROR mismatched types
-    //~| expected type `ToBar`
+    //~| expected type `dyn ToBar`
     //~| found type `Bar1`
     //~| expected trait ToBar, found struct `Bar1`
     //~| ERROR the size for value values of type
diff --git a/src/test/compile-fail/feature-gate-without_gate_irrefutable_pattern.rs b/src/test/compile-fail/feature-gate-without_gate_irrefutable_pattern.rs
new file mode 100644 (file)
index 0000000..7bcddbb
--- /dev/null
@@ -0,0 +1,17 @@
+// gate-test-irrefutable_let_patterns
+
+// 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(irrefutable_let_patterns)]
+fn main() {
+    if let _ = 5 {}
+    //~^ ERROR 15:12: 15:13: irrefutable if-let pattern [E0162]
+}
index 6d70f54edb4292a680f2ca0f5c0daf302934f987..56d64d77ee2581bccf1b10b293e23d3218defdd4 100644 (file)
@@ -16,15 +16,15 @@ fn main() {
     let _: () = (box |_: isize| {}) as Box<FnOnce(isize)>;
     //~^ ERROR mismatched types
     //~| expected type `()`
-    //~| found type `std::boxed::Box<std::ops::FnOnce(isize)>`
+    //~| found type `std::boxed::Box<dyn std::ops::FnOnce(isize)>`
     let _: () = (box |_: isize, isize| {}) as Box<Fn(isize, isize)>;
     //~^ ERROR mismatched types
     //~| expected type `()`
-    //~| found type `std::boxed::Box<std::ops::Fn(isize, isize)>`
+    //~| found type `std::boxed::Box<dyn std::ops::Fn(isize, isize)>`
     let _: () = (box || -> isize { unimplemented!() }) as Box<FnMut() -> isize>;
     //~^ ERROR mismatched types
     //~| expected type `()`
-    //~| found type `std::boxed::Box<std::ops::FnMut() -> isize>`
+    //~| found type `std::boxed::Box<dyn std::ops::FnMut() -> isize>`
 
     needs_fn(1);
     //~^ ERROR : std::ops::Fn<(isize,)>`
index 3d9d81471cb1e40da806c9348464d193ff9cfa98..f1fd617717a5ee5af533bf7bf3b51c44259688d2 100644 (file)
@@ -17,8 +17,8 @@ trait Foo {
 impl Foo for Baz {
     fn bar(&mut self, other: &Foo) {}
     //~^ ERROR method `bar` has an incompatible type for trait
-    //~| expected type `fn(&mut Baz, &mut Foo)`
-    //~| found type `fn(&mut Baz, &Foo)`
+    //~| expected type `fn(&mut Baz, &mut dyn Foo)`
+    //~| found type `fn(&mut Baz, &dyn Foo)`
 }
 
 fn main() {}
index 88197166ee08215b50af4204f551a269283c93e2..5282ce4bb8897dd43d09c6a61416193fe6b752e1 100644 (file)
@@ -11,6 +11,6 @@
 trait Foo {}
 
 impl<'a> Foo for Foo+'a {}
-//~^ ERROR the object type `Foo + 'a` automatically implements the trait `Foo`
+//~^ ERROR the object type `(dyn Foo + 'a)` automatically implements the trait `Foo`
 
 fn main() {}
index be76796c5c465b936404ca001d5cb17f9f2596bb..6063755c04f2873f8d24707ff237b3bf8e7a5a43 100644 (file)
@@ -13,7 +13,7 @@ fn main() {
     let index = 6;
 
     match i {
-        0...index => println!("winner"),
+        0..=index => println!("winner"),
         //~^ ERROR runtime values cannot be referenced in patterns
         _ => println!("hello"),
     }
index e97e5a86a9d7d88567f4fd8249ddf996e9d83ddd..24db822f89ca0fc91cb443602836b7630b99712e 100644 (file)
@@ -17,5 +17,5 @@ fn size_of_copy<T: Copy+?Sized>() -> usize { mem::size_of::<T>() }
 fn main() {
     size_of_copy::<Misc+Copy>();
     //~^ ERROR only auto traits can be used as additional traits in a trait object
-    //~| ERROR the trait bound `Misc: std::marker::Copy` is not satisfied
+    //~| ERROR the trait bound `dyn Misc: std::marker::Copy` is not satisfied
 }
index 15ca151c49a79b5079763d6b8029af21c17d88f8..0509a4387bae415f5999a640f5f55f477edd0626 100644 (file)
@@ -14,5 +14,5 @@ fn get_function<'a>() -> &'a Fn() -> Trait { panic!("") }
 
 fn main() {
     let t : &Trait = &get_function()();
-    //~^ ERROR cannot move a value of type Trait + 'static
+    //~^ ERROR cannot move a value of type (dyn Trait + 'static)
 }
index bdd502d442036bf751a32fe291c2fe704628fa76..29912de37eb0e793c1aa4c365e8f7009393a6069 100644 (file)
@@ -27,7 +27,7 @@ fn main() {
                            //~| WARNING hard error
                            //~| ERROR floating-point types cannot be used in patterns
                            //~| WARNING hard error
-        39.0 ... 70.0 => {}, //~ ERROR floating-point types cannot be used in patterns
+        39.0 ..= 70.0 => {}, //~ ERROR floating-point types cannot be used in patterns
                              //~| WARNING hard error
                              //~| ERROR floating-point types cannot be used in patterns
                              //~| WARNING hard error
index b1d96f9b5277885dbb62dea04ef58c23e3b11f34..9b49886961d7b12b1655d172748e7c0c14521ba8 100644 (file)
@@ -18,5 +18,5 @@ fn foo(self: Box<isize>) { }
 
 fn main() {
     (&5isize as &Foo).foo();
-    //~^ ERROR: no method named `foo` found for type `&Foo` in the current scope
+    //~^ ERROR: no method named `foo` found for type `&dyn Foo` in the current scope
 }
index a3eb47be3eed8a4212e2a9a7e233b5c0b25f6dee..82b97878549032dff3dc57a10051f0f7766d2628 100644 (file)
@@ -20,12 +20,12 @@ trait Message : Send { }
 
 fn object_ref_with_static_bound_not_ok() {
     assert_send::<&'static (Dummy+'static)>();
-    //~^ ERROR `Dummy + 'static` cannot be shared between threads safely [E0277]
+    //~^ ERROR `(dyn Dummy + 'static)` cannot be shared between threads safely [E0277]
 }
 
 fn box_object_with_no_bound_not_ok<'a>() {
     assert_send::<Box<Dummy>>();
-    //~^ ERROR `Dummy` cannot be sent between threads safely
+    //~^ ERROR `dyn Dummy` cannot be sent between threads safely
 }
 
 fn object_with_send_bound_ok() {
index 673a6abc5f03df178b0abbf78bf8efc120e75c5b..853630aa41628a90f2c98d35dab6ee746a328d01 100644 (file)
@@ -18,7 +18,7 @@ trait Dummy { }
 // careful with object types, who knows what they close over...
 fn test51<'a>() {
     assert_send::<&'a Dummy>();
-    //~^ ERROR `Dummy + 'a` cannot be shared between threads safely [E0277]
+    //~^ ERROR `(dyn Dummy + 'a)` cannot be shared between threads safely [E0277]
 }
 fn test52<'a>() {
     assert_send::<&'a (Dummy+Sync)>();
@@ -37,7 +37,7 @@ fn test61() {
 // them not ok
 fn test_71<'a>() {
     assert_send::<Box<Dummy+'a>>();
-    //~^ ERROR `Dummy + 'a` cannot be sent between threads safely
+    //~^ ERROR `(dyn Dummy + 'a)` cannot be sent between threads safely
 }
 
 fn main() { }
index 3a935af200054a0e3d6f20460fb88038cbe15090..0265f888e7c317411a728d9e0021bc80add29c0d 100644 (file)
@@ -15,12 +15,12 @@ trait Dummy { }
 
 fn test50() {
     assert_send::<&'static Dummy>();
-    //~^ ERROR `Dummy + 'static` cannot be shared between threads safely [E0277]
+    //~^ ERROR `(dyn Dummy + 'static)` cannot be shared between threads safely [E0277]
 }
 
 fn test53() {
     assert_send::<Box<Dummy>>();
-    //~^ ERROR `Dummy` cannot be sent between threads safely
+    //~^ ERROR `dyn Dummy` cannot be sent between threads safely
 }
 
 // ...unless they are properly bounded
index 9dcf902a69f916c7f343ebcd3de73f1853519ff9..e8ff9e817af2ca9d67bda5eda4bb9d4a2731fea1 100644 (file)
@@ -25,5 +25,5 @@ fn main() {
     let x: Box<HashMap<isize, isize>> = box HashMap::new();
     let x: Box<Map<isize, isize>> = x;
     let y: Box<Map<usize, isize>> = Box::new(x);
-    //~^ ERROR `std::boxed::Box<Map<isize, isize>>: Map<usize, isize>` is not satisfied
+    //~^ ERROR `std::boxed::Box<dyn Map<isize, isize>>: Map<usize, isize>` is not satisfied
 }
index 91ad2b3507abdf6304359ba9bf6cec62da2e7a69..b42e2ff919acbd958005f45670d130f5deaa9f70 100644 (file)
@@ -12,7 +12,7 @@
 
 fn main() {
     match 5 {
-        6 ... 1 => { }
+        6 ..= 1 => { }
         _ => { }
     };
     //~^^^ ERROR lower range bound must be less than or equal to upper
@@ -24,7 +24,7 @@ fn main() {
     //~^^^ ERROR lower range bound must be less than upper
 
     match 5u64 {
-        0xFFFF_FFFF_FFFF_FFFF ... 1 => { }
+        0xFFFF_FFFF_FFFF_FFFF ..= 1 => { }
         _ => { }
     };
     //~^^^ ERROR lower range bound must be less than or equal to upper
index f89b3e39390d31de8b22d29cbea8c112ede25b71..ca99b0c7b8938fa72e561f3e81acbd4d40946066 100644 (file)
 
 fn main() {
     match "wow" {
-        "bar" ... "foo" => { }
+        "bar" ..= "foo" => { }
     };
     //~^^ ERROR only char and numeric types are allowed in range
     //~| start type: &'static str
     //~| end type: &'static str
 
     match "wow" {
-        10 ... "what" => ()
+        10 ..= "what" => ()
     };
     //~^^ ERROR only char and numeric types are allowed in range
     //~| start type: {integer}
     //~| end type: &'static str
 
     match 5 {
-        'c' ... 100 => { }
+        'c' ..= 100 => { }
         _ => { }
     };
     //~^^^ ERROR mismatched types
index fe88ab4e11798b39467d7b791895d4fa9924935b..1aae25105a8132f3662396a72fa6e18aede433a1 100644 (file)
@@ -11,7 +11,7 @@
 fn main() {
     let x = 0;
     match 1 {
-        0 ... x => {}
+        0 ..= x => {}
         //~^ ERROR runtime values cannot be referenced in patterns
     };
 }
index a51a9e518ce5fe7e0d7aac6fd9f6b9b7922ac72f..2a6e148ca791157c491d92fecbcfe9e1951b0708 100644 (file)
@@ -61,22 +61,22 @@ pub unsafe fn test_Foo_cxchg(p: &mut Foo, v: Foo) {
 
 pub unsafe fn test_Bar_load(p: &mut Bar, v: Bar) {
     intrinsics::atomic_load(p);
-    //~^ ERROR expected basic integer type, found `&std::ops::Fn()`
+    //~^ ERROR expected basic integer type, found `&dyn std::ops::Fn()`
 }
 
 pub unsafe fn test_Bar_store(p: &mut Bar, v: Bar) {
     intrinsics::atomic_store(p, v);
-    //~^ ERROR expected basic integer type, found `&std::ops::Fn()`
+    //~^ ERROR expected basic integer type, found `&dyn std::ops::Fn()`
 }
 
 pub unsafe fn test_Bar_xchg(p: &mut Bar, v: Bar) {
     intrinsics::atomic_xchg(p, v);
-    //~^ ERROR expected basic integer type, found `&std::ops::Fn()`
+    //~^ ERROR expected basic integer type, found `&dyn std::ops::Fn()`
 }
 
 pub unsafe fn test_Bar_cxchg(p: &mut Bar, v: Bar) {
     intrinsics::atomic_cxchg(p, v, v);
-    //~^ ERROR expected basic integer type, found `&std::ops::Fn()`
+    //~^ ERROR expected basic integer type, found `&dyn std::ops::Fn()`
 }
 
 pub unsafe fn test_Quux_load(p: &mut Quux, v: Quux) {
index 8babc734c84cc13afdf33ec6fcaf74f757461362..30f8d5e2f45698c5f37d1dd2b8b33d3f1c59c88a 100644 (file)
@@ -14,5 +14,5 @@
 trait Foo {}
 fn take_foo<F:Foo>(f: F) {}
 fn take_object(f: Box<Foo>) { take_foo(f); }
-//~^ ERROR `std::boxed::Box<Foo>: Foo` is not satisfied
+//~^ ERROR `std::boxed::Box<dyn Foo>: Foo` is not satisfied
 fn main() {}
index 36356cb7d527e2442b1bfdccdf7ca520acc1bc49..e575bbb6ceab102fe8f29e008412915a22962641 100644 (file)
@@ -22,7 +22,7 @@ trait Baz {
 }
 
 fn use_bar(t: Box<Bar>) {
-    t.bar() //~ ERROR cannot move a value of type Bar
+    t.bar() //~ ERROR cannot move a value of type (dyn Bar + 'static)
 }
 
 fn main() { }
index d57a23f26c4791b4553b9566d1ca59ceb2dbb43b..8fef98f815f22511b748e10fcee465555edfdad8 100644 (file)
@@ -17,7 +17,7 @@ enum $name {
         fn foo(value: i32) -> Option<$name> {
             match value {
                 $( $value => Some($name::$variant), )* // PatKind::Lit
-                $( $value ... 42 => Some($name::$variant), )* // PatKind::Range
+                $( $value ..= 42 => Some($name::$variant), )* // PatKind::Range
                 _ => None
             }
         }
@@ -32,4 +32,3 @@ fn foo(value: i32) -> Option<$name> {
 });
 
 fn main() {}
-
index c25616c54354d9f0d856927e915e1f383f5c83ba..6019369aa2ebb5111d556194a70186b9974e09c1 100644 (file)
@@ -19,19 +19,19 @@ pub trait PubTr: PrivTr {}
 
     pub macro mac1() {
         let _: Box<PubTr<AssocTy = u8>>;
-        //~^ ERROR type `priv_trait::PubTr<AssocTy=u8> + '<empty>` is private
-        //~| ERROR type `priv_trait::PubTr<AssocTy=u8> + '<empty>` is private
+        //~^ ERROR type `(dyn priv_trait::PubTr<AssocTy=u8> + '<empty>)` is private
+        //~| ERROR type `(dyn priv_trait::PubTr<AssocTy=u8> + '<empty>)` is private
         type InSignatureTy2 = Box<PubTr<AssocTy = u8>>;
-        //~^ ERROR type `priv_trait::PubTr<AssocTy=u8> + 'static` is private
+        //~^ ERROR type `(dyn priv_trait::PubTr<AssocTy=u8> + 'static)` is private
         trait InSignatureTr2: PubTr<AssocTy = u8> {}
         //~^ ERROR trait `priv_trait::PrivTr` is private
     }
     pub macro mac2() {
         let _: Box<PrivTr<AssocTy = u8>>;
-        //~^ ERROR type `priv_trait::PrivTr<AssocTy=u8> + '<empty>` is private
-        //~| ERROR type `priv_trait::PrivTr<AssocTy=u8> + '<empty>` is private
+        //~^ ERROR type `(dyn priv_trait::PrivTr<AssocTy=u8> + '<empty>)` is private
+        //~| ERROR type `(dyn priv_trait::PrivTr<AssocTy=u8> + '<empty>)` is private
         type InSignatureTy1 = Box<PrivTr<AssocTy = u8>>;
-        //~^ ERROR type `priv_trait::PrivTr<AssocTy=u8> + 'static` is private
+        //~^ ERROR type `(dyn priv_trait::PrivTr<AssocTy=u8> + 'static)` is private
         trait InSignatureTr1: PrivTr<AssocTy = u8> {}
         //~^ ERROR trait `priv_trait::PrivTr` is private
     }
index 5af8b063c1629f12e0fb6c3f348337b1bef51357..3ca8b1eb2ed3a3d61b36484b2deb13d96a512d41 100644 (file)
@@ -129,7 +129,7 @@ fn main() {
     m::leak_anon2(); //~ ERROR type `m::Priv` is private
     m::leak_anon3(); //~ ERROR type `m::Priv` is private
 
-    m::leak_dyn1(); //~ ERROR type `m::Trait + 'static` is private
+    m::leak_dyn1(); //~ ERROR type `(dyn m::Trait + 'static)` is private
     m::leak_dyn2(); //~ ERROR type `m::Priv` is private
     m::leak_dyn3(); //~ ERROR type `m::Priv` is private
 
index a7bc27e1749182e0f1de42ab64f52992979e4216..018a3b2ae32580aabb67e1933f836c6b1ad70863 100644 (file)
@@ -29,6 +29,6 @@ fn main() {
     match 10 {
         <S as Tr>::A::f::<u8> => {}
         //~^ ERROR expected unit struct/variant or constant, found method `<<S as Tr>::A>::f<u8>`
-        0 ... <S as Tr>::A::f::<u8> => {} //~ ERROR only char and numeric types are allowed in range
+        0 ..= <S as Tr>::A::f::<u8> => {} //~ ERROR only char and numeric types are allowed in range
     }
 }
index ce93e1875ae5a9ce9761a175a8cfeec4dd1a119c..7b4009481abd473eb44847f7db62f7a2ccd2df48 100644 (file)
@@ -9,10 +9,10 @@
 // except according to those terms.
 
 
-fn func((1, (Some(1), 2...3)): (isize, (Option<isize>, isize))) { }
+fn func((1, (Some(1), 2..=3)): (isize, (Option<isize>, isize))) { }
 //~^ ERROR refutable pattern in function argument: `(_, _)` not covered
 
 fn main() {
-    let (1, (Some(1), 2...3)) = (1, (None, 2));
+    let (1, (Some(1), 2..=3)) = (1, (None, 2));
     //~^ ERROR refutable pattern in local binding: `(_, _)` not covered
 }
diff --git a/src/test/compile-fail/should-fail-no_gate_irrefutable_if_let_pattern.rs b/src/test/compile-fail/should-fail-no_gate_irrefutable_if_let_pattern.rs
new file mode 100644 (file)
index 0000000..8c9a24f
--- /dev/null
@@ -0,0 +1,15 @@
+// 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.
+
+// should-fail-irrefutable_let_patterns
+fn main() {
+    if let _ = 5 {}
+    //~^ ERROR irrefutable if-let pattern [E0162]
+}
diff --git a/src/test/compile-fail/should-fail-with_gate_irrefutable_pattern_deny.rs b/src/test/compile-fail/should-fail-with_gate_irrefutable_pattern_deny.rs
new file mode 100644 (file)
index 0000000..6f95f10
--- /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.
+
+#![feature(irrefutable_let_patterns)]
+
+// should-fail-irrefutable_let_patterns_with_gate
+fn main() {
+    if let _ = 5 {}
+    //~^ ERROR irrefutable if-let pattern [irrefutable_let_patterns]
+}
index be0f7dd4e1cd73f34d35a8b2c7f1cbf3443eda21..f8e4f0d596e20d3a005514552b5ea0eecaa42e64 100644 (file)
@@ -110,9 +110,9 @@ fn check_assoc_const() {
     // A, B, C are resolved as inherent items, their traits don't need to be in scope
     C::A; //~ ERROR associated constant `A` is private
           //~^ ERROR the trait `assoc_const::C` cannot be made into an object
-          //~| ERROR the trait bound `assoc_const::C: assoc_const::A` is not satisfied
+          //~| ERROR the trait bound `dyn assoc_const::C: assoc_const::A` is not satisfied
     C::B; // ERROR the trait `assoc_const::C` cannot be made into an object
-          //~^ ERROR the trait bound `assoc_const::C: assoc_const::B` is not satisfied
+          //~^ ERROR the trait bound `dyn assoc_const::C: assoc_const::B` is not satisfied
     C::C; // OK
 }
 
index 3fc0d638dd6f1880be39caa81b4c71bdb4e4e35c..559871af72ed630e8b0e5d32f38930a077d974e8 100644 (file)
@@ -33,7 +33,7 @@ fn same_as(&self, t: u64) -> bool { *self == (t as i64) }
 impl CompareToInts for i64 { }
 
 fn with_obj(c: &CompareToInts) -> bool {
-    c.same_as(22) //~ ERROR `CompareToInts: CompareTo<i32>` is not satisfied
+    c.same_as(22) //~ ERROR `dyn CompareToInts: CompareTo<i32>` is not satisfied
 }
 
 fn with_trait<C:CompareToInts>(c: &C) -> bool {
@@ -41,7 +41,7 @@ fn with_trait<C:CompareToInts>(c: &C) -> bool {
 }
 
 fn with_ufcs1<C:CompareToInts>(c: &C) -> bool {
-    CompareToInts::same_as(c, 22) //~ ERROR `CompareToInts: CompareTo<i32>` is not satisfied
+    CompareToInts::same_as(c, 22) //~ ERROR `dyn CompareToInts: CompareTo<i32>` is not satisfied
 }
 
 fn with_ufcs2<C:CompareToInts>(c: &C) -> bool {
index aabf0d26d5ba7db921d144fd43df73d2ab35edb5..3f2bd2ffabf4bad00cd416e10feec06f5092466d 100644 (file)
@@ -59,25 +59,25 @@ pub fn main() {
 
     // unsize trait
     let x: &Bar = &Bar;
-    let _ = x as &Foo; //~ERROR trivial cast: `&Bar` as `&Foo`
-    let _ = x as *const Foo; //~ERROR trivial cast: `&Bar` as `*const Foo`
+    let _ = x as &Foo; //~ERROR trivial cast: `&Bar` as `&dyn Foo`
+    let _ = x as *const Foo; //~ERROR trivial cast: `&Bar` as `*const dyn Foo`
     let _: &Foo = x;
     let _: *const Foo = x;
 
     let x: &mut Bar = &mut Bar;
-    let _ = x as &mut Foo; //~ERROR trivial cast: `&mut Bar` as `&mut Foo`
-    let _ = x as *mut Foo; //~ERROR trivial cast: `&mut Bar` as `*mut Foo`
+    let _ = x as &mut Foo; //~ERROR trivial cast: `&mut Bar` as `&mut dyn Foo`
+    let _ = x as *mut Foo; //~ERROR trivial cast: `&mut Bar` as `*mut dyn Foo`
     let _: &mut Foo = x;
     let _: *mut Foo = x;
 
     let x: Box<Bar> = Box::new(Bar);
-    let _ = x as Box<Foo>; //~ERROR trivial cast: `std::boxed::Box<Bar>` as `std::boxed::Box<Foo>`
+    let _ = x as Box<Foo>; //~ERROR `std::boxed::Box<Bar>` as `std::boxed::Box<dyn Foo>`
     let x: Box<Bar> = Box::new(Bar);
     let _: Box<Foo> = x;
 
     // functions
     fn baz(_x: i32) {}
-    let _ = &baz as &Fn(i32); //~ERROR trivial cast: `&fn(i32) {main::baz}` as `&std::ops::Fn(i32)`
+    let _ = &baz as &Fn(i32); //~ERROR `&fn(i32) {main::baz}` as `&dyn std::ops::Fn(i32)`
     let _: &Fn(i32) = &baz;
     let x = |_x: i32| {};
     let _ = &x as &Fn(i32); //~ERROR trivial cast
index 4295d08a4709c701eaa8e63336ff5fac086e9e4d..7e93f626cfcfb38ef65c00769270576ecb249950 100644 (file)
@@ -33,7 +33,7 @@ fn main() {
         //~^ ERROR mismatched types
         //~| Perhaps two different versions of crate `crate_a1`
         //~| expected trait `main::a::Bar`
-        //~| expected type `std::boxed::Box<main::a::Bar + 'static>`
-        //~| found type `std::boxed::Box<main::a::Bar>`
+        //~| expected type `std::boxed::Box<(dyn main::a::Bar + 'static)>`
+        //~| found type `std::boxed::Box<dyn main::a::Bar>`
     }
 }
index 09687724656fa8febe373f1f01ed750e45efed27..08988353886451992f644ceac9ab7dcb2ca2a85c 100644 (file)
@@ -23,5 +23,5 @@ fn main() {
     let x: i32 = 5;
     let y = x as MyAdd<i32>;
     //~^ ERROR E0038
-    //~| ERROR cast to unsized type: `i32` as `MyAdd<i32>`
+    //~| ERROR cast to unsized type: `i32` as `dyn MyAdd<i32>`
 }
index dadc755eb8c579a571932815bdeb1511e0d60246..30ba14c1bab3af49902b8133b503418a14552e8f 100644 (file)
@@ -68,17 +68,17 @@ fn foo<F>(f: F) where F: FnOnce() -> i32 {
 // fn main::{{closure}}(_1: [closure@NodeId(22) d:&'19s D]) -> i32 {
 //     let mut _0: i32;
 //     ...
-//     let _2: &'15_0rs D;
+//     let _2: &'16_0rs D;
 //     ...
 //     let mut _3: i32;
 //     bb0: {
 //         StorageLive(_2);
-//         _2 = &'15_0rs (*(_1.0: &'19s D));
+//         _2 = &'16_0rs (*(_1.0: &'19s D));
 //         StorageLive(_3);
 //         _3 = ((*_2).0: i32);
 //         _0 = move _3;
 //         StorageDead(_3);
-//         EndRegion('15_0rs);
+//         EndRegion('16_0rs);
 //         StorageDead(_2);
 //         return;
 //     }
index 1426174b482b64af54495f376ab182502ea48096..6d6afa25ae30e4c788b424de4907026cb9db1493 100644 (file)
@@ -76,17 +76,17 @@ fn foo<F>(f: F) where F: FnOnce() -> i32 {
 // fn main::{{closure}}(_1: [closure@NodeId(22) d:D]) -> i32 {
 //     let mut _0: i32;
 //     ...
-//     let _2: &'15_0rs D;
+//     let _2: &'16_0rs D;
 //     ...
 //     let mut _3: i32;
 //     bb0: {
 //         StorageLive(_2);
-//         _2 = &'15_0rs (_1.0: D);
+//         _2 = &'16_0rs (_1.0: D);
 //         StorageLive(_3);
 //         _3 = ((*_2).0: i32);
 //         _0 = move _3;
 //         StorageDead(_3);
-//         EndRegion('15_0rs);
+//         EndRegion('16_0rs);
 //         StorageDead(_2);
 //         drop(_1) -> [return: bb2, unwind: bb1];
 //     }
index e6cd535500055f1bac85ef56e3ef6f9f9c9eb7c2..c331276aade7756857cef58b821cff228c4b0222 100644 (file)
@@ -64,14 +64,14 @@ fn main() {
 //     bb0: {
 //         Validate(Acquire, [_1: &ReFree(DefId(0/1:11 ~ validate_1[317d]::main[0]::{{closure}}[0]), BrEnv) [closure@NodeId(50)], _2: &ReFree(DefId(0/1:11 ~ validate_1[317d]::main[0]::{{closure}}[0]), BrAnon(0)) mut i32]);
 //         StorageLive(_3);
-//         Validate(Suspend(ReScope(Remainder(BlockRemainder { block: ItemLocalId(22), first_statement_index: 0 }))), [(*_2): i32]);
+//         Validate(Suspend(ReScope(Remainder(BlockRemainder { block: ItemLocalId(25), first_statement_index: 0 }))), [(*_2): i32]);
 //         _3 = &ReErased (*_2);
-//         Validate(Acquire, [(*_3): i32/ReScope(Remainder(BlockRemainder { block: ItemLocalId(22), first_statement_index: 0 })) (imm)]);
+//         Validate(Acquire, [(*_3): i32/ReScope(Remainder(BlockRemainder { block: ItemLocalId(25), first_statement_index: 0 })) (imm)]);
 //         StorageLive(_4);
 //         _4 = (*_3);
 //         _0 = move _4;
 //         StorageDead(_4);
-//         EndRegion(ReScope(Remainder(BlockRemainder { block: ItemLocalId(22), first_statement_index: 0 })));
+//         EndRegion(ReScope(Remainder(BlockRemainder { block: ItemLocalId(25), first_statement_index: 0 })));
 //         StorageDead(_3);
 //         return;
 //     }
index d8d83fb5b453707c69d2c8b46de919495d893358..b4d4479bab94a62eeed89817efd827950a8b72ce 100644 (file)
@@ -53,12 +53,12 @@ fn main() {
 //         StorageLive(_3);
 //         StorageLive(_4);
 //         StorageLive(_5);
-//         Validate(Suspend(ReScope(Node(ItemLocalId(9)))), [(*_2): i32]);
+//         Validate(Suspend(ReScope(Node(ItemLocalId(12)))), [(*_2): i32]);
 //         _5 = &ReErased mut (*_2);
-//         Validate(Acquire, [(*_5): i32/ReScope(Node(ItemLocalId(9)))]);
+//         Validate(Acquire, [(*_5): i32/ReScope(Node(ItemLocalId(12)))]);
 //         _4 = move _5 as *mut i32 (Misc);
 //         _3 = move _4;
-//         EndRegion(ReScope(Node(ItemLocalId(9))));
+//         EndRegion(ReScope(Node(ItemLocalId(12))));
 //         StorageDead(_4);
 //         StorageDead(_5);
 //         Validate(Release, [_0: bool, _3: *mut i32]);
index 62cb870c7bb47b0010fb23397423bfb86b31b72b..2ef7eba6c05d13ecd46c181a0e90d3aada71f1a5 100644 (file)
@@ -284,18 +284,20 @@ fn run() {
 
     // FIXME: Allow attributes in pattern constexprs?
     // would require parens in patterns to allow disambiguation...
+    // â€”which is now available under the `pattern_parentheses` feature gate
+    // (tracking issue #51087)
 
     reject_expr_parse("match 0 {
-        0...#[attr] 10 => ()
+        0..=#[attr] 10 => ()
     }");
     reject_expr_parse("match 0 {
-        0...#[attr] -10 => ()
+        0..=#[attr] -10 => ()
     }");
     reject_expr_parse("match 0 {
-        0...-#[attr] 10 => ()
+        0..=-#[attr] 10 => ()
     }");
     reject_expr_parse("match 0 {
-        0...#[attr] FOO => ()
+        0..=#[attr] FOO => ()
     }");
 
     // make sure we don't catch this bug again...
index d7ede763838687f79a620e7f4982329364bce61c..ac39118c5f1e01e0b96295e2207f319f5ae67ddd 100644 (file)
@@ -54,6 +54,7 @@ pub fn plugin_registrar(reg: &mut Registry) {
             def_info: None,
             allow_internal_unstable: false,
             allow_internal_unsafe: false,
+            local_inner_macros: false,
             unstable_feature: None,
             edition: hygiene::default_edition(),
         });
index 914e3dd4932488b7f8c3dbb49e58b50e4a83c3aa..4f419e70074fc673a329cecb20e89b9f859b2612 100644 (file)
@@ -41,17 +41,16 @@ enum WireProtocol {
 fn encode_json<T: Encodable>(val: &T, wr: &mut Cursor<Vec<u8>>) {
     write!(wr, "{}", json::as_json(val));
 }
-fn encode_opaque<T: Encodable>(val: &T, wr: &mut Cursor<Vec<u8>>) {
+fn encode_opaque<T: Encodable>(val: &T, wr: Vec<u8>) {
     let mut encoder = opaque::Encoder::new(wr);
     val.encode(&mut encoder);
 }
 
 pub fn main() {
     let target = Foo{baz: false,};
-    let mut wr = Cursor::new(Vec::new());
     let proto = WireProtocol::JSON;
     match proto {
-        WireProtocol::JSON => encode_json(&target, &mut wr),
-        WireProtocol::Opaque => encode_opaque(&target, &mut wr)
+        WireProtocol::JSON => encode_json(&target, &mut Cursor::new(Vec::new())),
+        WireProtocol::Opaque => encode_opaque(&target, Vec::new())
     }
 }
diff --git a/src/test/run-pass/allow_irrefutable_let_patterns.rs b/src/test/run-pass/allow_irrefutable_let_patterns.rs
new file mode 100644 (file)
index 0000000..ea114b6
--- /dev/null
@@ -0,0 +1,21 @@
+// 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(irrefutable_let_patterns)]
+
+// must-compile-successfully-irrefutable_let_patterns_with_gate
+#[allow(irrefutable_let_patterns)]
+fn main() {
+    if let _ = 5 {}
+
+    while let _ = 5 {
+        break;
+    }
+}
index ad779d26f9e463d77fdffa6bcad1fc8aaca0fd32..f5acb72429ae077754a26378cc602f7eac0f5aee 100644 (file)
@@ -36,7 +36,7 @@ pub fn main() {
     }
 
     match 100 {
-        b'a' ... b'z' => {},
+        b'a' ..= b'z' => {},
         _ => panic!()
     }
 
index 22369c77ed33fdc5b82689ed339f148c72802b75..89d26aade2ec3de1dbebe0b7902727f75da520ba 100644 (file)
 pub fn main() {
     let x = 2;
     let x_message = match x {
-      0 ... 1    => { "not many".to_string() }
+      0 ..= 1    => { "not many".to_string() }
       _          => { "lots".to_string() }
     };
     assert_eq!(x_message, "lots".to_string());
 
     let y = 2;
     let y_message = match y {
-      0 ... 1    => { "not many".to_string() }
+      0 ..= 1    => { "not many".to_string() }
       _          => { "lots".to_string() }
     };
     assert_eq!(y_message, "lots".to_string());
 
     let z = 1u64;
     let z_message = match z {
-      0 ... 1    => { "not many".to_string() }
+      0 ..= 1    => { "not many".to_string() }
       _          => { "lots".to_string() }
     };
     assert_eq!(z_message, "not many".to_string());
index 7bab2ddfed06bbc429c95063ed1ab68cb2d9eb8b..b89964d968e8438f8f5bd10d363c08d0a25e6b76 100644 (file)
@@ -16,7 +16,7 @@ pub fn main() {
     assert_eq!(3, match (x, y) {
         (1, 1) => 1,
         (2, 2) => 2,
-        (1...2, 2) => 3,
+        (1..=2, 2) => 3,
         _ => 4,
     });
 
@@ -24,7 +24,7 @@ pub fn main() {
     assert_eq!(3, match ((x, y),) {
         ((1, 1),) => 1,
         ((2, 2),) => 2,
-        ((1...2, 2),) => 3,
+        ((1..=2, 2),) => 3,
         _ => 4,
     });
 }
index d28ea94ec1a0dfc7f038926c419e423350cac6fe..2c460900ef6288c687220e0d7ee777904b3d0cb5 100644 (file)
@@ -30,7 +30,7 @@ pub fn main() {
 fn lit_shadow_range() {
     assert_eq!(2, match 1 {
         1 if false => 1,
-        1...2 => 2,
+        1..=2 => 2,
         _ => 3
     });
 
@@ -38,34 +38,34 @@ fn lit_shadow_range() {
     assert_eq!(2, match x+1 {
         0 => 0,
         1 if false => 1,
-        1...2 => 2,
+        1..=2 => 2,
         _ => 3
     });
 
     assert_eq!(2, match val() {
         1 if false => 1,
-        1...2 => 2,
+        1..=2 => 2,
         _ => 3
     });
 
     assert_eq!(2, match CONST {
         0 => 0,
         1 if false => 1,
-        1...2 => 2,
+        1..=2 => 2,
         _ => 3
     });
 
     // value is out of the range of second arm, should match wildcard pattern
     assert_eq!(3, match 3 {
         1 if false => 1,
-        1...2 => 2,
+        1..=2 => 2,
         _ => 3
     });
 }
 
 fn range_shadow_lit() {
     assert_eq!(2, match 1 {
-        1...2 if false => 1,
+        1..=2 if false => 1,
         1 => 2,
         _ => 3
     });
@@ -73,27 +73,27 @@ fn range_shadow_lit() {
     let x = 0;
     assert_eq!(2, match x+1 {
         0 => 0,
-        1...2 if false => 1,
+        1..=2 if false => 1,
         1 => 2,
         _ => 3
     });
 
     assert_eq!(2, match val() {
-        1...2 if false => 1,
+        1..=2 if false => 1,
         1 => 2,
         _ => 3
     });
 
     assert_eq!(2, match CONST {
         0 => 0,
-        1...2 if false => 1,
+        1..=2 if false => 1,
         1 => 2,
         _ => 3
     });
 
     // ditto
     assert_eq!(3, match 3 {
-        1...2 if false => 1,
+        1..=2 if false => 1,
         1 => 2,
         _ => 3
     });
@@ -101,36 +101,36 @@ fn range_shadow_lit() {
 
 fn range_shadow_range() {
     assert_eq!(2, match 1 {
-        0...2 if false => 1,
-        1...3 => 2,
+        0..=2 if false => 1,
+        1..=3 => 2,
         _ => 3,
     });
 
     let x = 0;
     assert_eq!(2, match x+1 {
         100 => 0,
-        0...2 if false => 1,
-        1...3 => 2,
+        0..=2 if false => 1,
+        1..=3 => 2,
         _ => 3,
     });
 
     assert_eq!(2, match val() {
-        0...2 if false => 1,
-        1...3 => 2,
+        0..=2 if false => 1,
+        1..=3 => 2,
         _ => 3,
     });
 
     assert_eq!(2, match CONST {
         100 => 0,
-        0...2 if false => 1,
-        1...3 => 2,
+        0..=2 if false => 1,
+        1..=3 => 2,
         _ => 3,
     });
 
     // ditto
     assert_eq!(3, match 5 {
-        0...2 if false => 1,
-        1...3 => 2,
+        0..=2 if false => 1,
+        1..=3 => 2,
         _ => 3,
     });
 }
@@ -138,7 +138,7 @@ fn range_shadow_range() {
 fn multi_pats_shadow_lit() {
     assert_eq!(2, match 1 {
         100 => 0,
-        0 | 1...10 if false => 1,
+        0 | 1..=10 if false => 1,
         1 => 2,
         _ => 3,
     });
@@ -147,8 +147,8 @@ fn multi_pats_shadow_lit() {
 fn multi_pats_shadow_range() {
     assert_eq!(2, match 1 {
         100 => 0,
-        0 | 1...10 if false => 1,
-        1...3 => 2,
+        0 | 1..=10 if false => 1,
+        1..=3 => 2,
         _ => 3,
     });
 }
@@ -157,7 +157,7 @@ fn lit_shadow_multi_pats() {
     assert_eq!(2, match 1 {
         100 => 0,
         1 if false => 1,
-        0 | 1...10 => 2,
+        0 | 1..=10 => 2,
         _ => 3,
     });
 }
@@ -165,8 +165,8 @@ fn lit_shadow_multi_pats() {
 fn range_shadow_multi_pats() {
     assert_eq!(2, match 1 {
         100 => 0,
-        1...3 if false => 1,
-        0 | 1...10 => 2,
+        1..=3 if false => 1,
+        0 | 1..=10 => 2,
         _ => 3,
     });
 }
index e21070e2eafa18fc169a9a17b6c943d83abaafc9..bc28dc54de6f66e57aa74eb501446f0f23ef0365 100644 (file)
@@ -19,14 +19,14 @@ enum Foo {
 
 fn main() {
     let r = match (Foo::FooNullary, 'a') {
-        (Foo::FooUint(..), 'a'...'z') => 1,
+        (Foo::FooUint(..), 'a'..='z') => 1,
         (Foo::FooNullary, 'x') => 2,
         _ => 0
     };
     assert_eq!(r, 0);
 
     let r = match (Foo::FooUint(0), 'a') {
-        (Foo::FooUint(1), 'a'...'z') => 1,
+        (Foo::FooUint(1), 'a'..='z') => 1,
         (Foo::FooUint(..), 'x') => 2,
         (Foo::FooNullary, 'a') => 3,
         _ => 0
@@ -34,7 +34,7 @@ fn main() {
     assert_eq!(r, 0);
 
     let r = match ('a', Foo::FooUint(0)) {
-        ('a'...'z', Foo::FooUint(1)) => 1,
+        ('a'..='z', Foo::FooUint(1)) => 1,
         ('x', Foo::FooUint(..)) => 2,
         ('a', Foo::FooNullary) => 3,
         _ => 0
@@ -42,15 +42,15 @@ fn main() {
     assert_eq!(r, 0);
 
     let r = match ('a', 'a') {
-        ('a'...'z', 'b') => 1,
-        ('x', 'a'...'z') => 2,
+        ('a'..='z', 'b') => 1,
+        ('x', 'a'..='z') => 2,
         _ => 0
     };
     assert_eq!(r, 0);
 
     let r = match ('a', 'a') {
-        ('a'...'z', 'b') => 1,
-        ('x', 'a'...'z') => 2,
+        ('a'..='z', 'b') => 1,
+        ('x', 'a'..='z') => 2,
         ('a', 'a') => 3,
         _ => 0
     };
index d6c9a92ca02910f226b1276317a435f27cce96d5..322a3d8c9bb2e3240414fc661265fad70ed36182 100644 (file)
@@ -11,7 +11,7 @@
 // Regression test for #18060: match arms were matching in the wrong order.
 
 fn main() {
-    assert_eq!(2, match (1, 3) { (0, 2...5) => 1, (1, 3) => 2, (_, 2...5) => 3, (_, _) => 4 });
-    assert_eq!(2, match (1, 3) {                  (1, 3) => 2, (_, 2...5) => 3, (_, _) => 4 });
-    assert_eq!(2, match (1, 7) { (0, 2...5) => 1, (1, 7) => 2, (_, 2...5) => 3, (_, _) => 4 });
+    assert_eq!(2, match (1, 3) { (0, 2..=5) => 1, (1, 3) => 2, (_, 2..=5) => 3, (_, _) => 4 });
+    assert_eq!(2, match (1, 3) {                  (1, 3) => 2, (_, 2..=5) => 3, (_, _) => 4 });
+    assert_eq!(2, match (1, 7) { (0, 2..=5) => 1, (1, 7) => 2, (_, 2..=5) => 3, (_, _) => 4 });
 }
index dff86bc1b4527ea583ce85e1bec2608775a302db..f4faab5e468539aff003f005751acf989fddb491 100644 (file)
@@ -15,7 +15,7 @@
 
 fn main() {
     match '5' {
-        LOW_RANGE...HIGH_RANGE => (),
+        LOW_RANGE..=HIGH_RANGE => (),
         _ => ()
     };
 }
index 19cd1cf3df717721c9bbfcdb85825b0699aa437a..862439e21f4f3737743737ac08e6ab66dcc36ade 100644 (file)
@@ -26,5 +26,5 @@ fn main() {
         std::intrinsics::type_name::<NT>(),
         // DST
         std::intrinsics::type_name::<DST>()
-    )}, ("[u8]", "str", "std::marker::Send", "NT", "DST"));
+    )}, ("[u8]", "str", "dyn std::marker::Send", "NT", "DST"));
 }
index 0666a1f133f2e144b5c7143fbc020c20f96b38d8..99839b56506f997c7c1a8e0d8749725735f6749d 100644 (file)
@@ -14,9 +14,9 @@
 
 fn main() {
     match 42 {
-        m::START...m::END => {},
-        0...m::END => {},
-        m::START...59 => {},
+        m::START..=m::END => {},
+        0..=m::END => {},
+        m::START..=59 => {},
         _  => {},
     }
 }
index 1e77d54fbf9346e9769ecfef34896004a55167c9..3735d36147d1fb6629c69d348b5c0fa740bd64d4 100644 (file)
@@ -12,9 +12,9 @@ fn main() {
     let x = 'a';
 
     let y = match x {
-        'a'...'b' if false => "one",
+        'a'..='b' if false => "one",
         'a' => "two",
-        'a'...'b' => "three",
+        'a'..='b' => "three",
         _ => panic!("what?"),
     };
 
index 35d0c305ed8348449d0518b1fef033b1d6b6d52f..34cb2930db0cf7d821bd1e2cbd47e1ed97ddd6ee 100644 (file)
@@ -12,7 +12,7 @@ fn main () {
     let x = 4;
     match x {
         ref r if *r < 0 => println!("got negative num {} < 0", r),
-        e @ 1 ... 100 => println!("got number within range [1,100] {}", e),
+        e @ 1 ..= 100 => println!("got number within range [1,100] {}", e),
         _ => println!("no"),
     }
 }
index 1bf343e23f0c1617c6635ab9e27e399784ad1ffa..3eb39ad6aad595e36c39ef4cb44ba5e51e8d7452 100644 (file)
@@ -14,7 +14,7 @@ pub fn main() {
     const FOO: f64 = 10.0;
 
     match 0.0 {
-        0.0 ... FOO => (),
+        0.0 ..= FOO => (),
         _ => ()
     }
 }
index 0bcda7bc1447aa2b112ac25ed6687136c90cc645..6d5e8bc97c0e9b481a64e84e8074d2bfe61aafc4 100644 (file)
@@ -41,18 +41,18 @@ macro_rules! mtester_dbg {
 }
 
 macro_rules! catch_range {
-    ($s:literal ... $e:literal) => {
-        &format!("macro caught literal: {} ... {}", $s, $e)
+    ($s:literal ..= $e:literal) => {
+        &format!("macro caught literal: {} ..= {}", $s, $e)
     };
-    (($s:expr) ... ($e:expr)) => { // Must use ')' before '...'
-        &format!("macro caught expr: {} ... {}", $s, $e)
+    (($s:expr) ..= ($e:expr)) => { // Must use ')' before '..='
+        &format!("macro caught expr: {} ..= {}", $s, $e)
     };
 }
 
 macro_rules! pat_match {
-    ($s:literal ... $e:literal) => {
+    ($s:literal ..= $e:literal) => {
         match 3 {
-            $s ... $e => "literal, in range",
+            $s ..= $e => "literal, in range",
             _ => "literal, other",
         }
     };
@@ -115,22 +115,22 @@ pub fn main() {
     assert_eq!(mtester!('c'), "macro caught literal: c");
     assert_eq!(mtester!(-1.2), "macro caught literal: -1.2");
     assert_eq!(two_negative_literals!(-2 -3), "macro caught literals: -2, -3");
-    assert_eq!(catch_range!(2 ... 3), "macro caught literal: 2 ... 3");
+    assert_eq!(catch_range!(2 ..= 3), "macro caught literal: 2 ..= 3");
     assert_eq!(match_attr!(#[attr] 1), "attr matched literal");
     assert_eq!(test_user!(10, 20), "literal");
     assert_eq!(mtester!(false), "macro caught literal: false");
     assert_eq!(mtester!(true), "macro caught literal: true");
     match_produced_attr!("a");
     let _a = LiteralProduced;
-    assert_eq!(pat_match!(1 ... 3), "literal, in range");
-    assert_eq!(pat_match!(4 ... 6), "literal, other");
+    assert_eq!(pat_match!(1 ..= 3), "literal, in range");
+    assert_eq!(pat_match!(4 ..= 6), "literal, other");
 
     // Cases where 'expr' catches
     assert_eq!(mtester!((-1.2)), "macro caught expr: -1.2");
     assert_eq!(only_expr!(-1.2), "macro caught expr: -1.2");
     assert_eq!(mtester!((1 + 3)), "macro caught expr: 4");
     assert_eq!(mtester_dbg!(()), "macro caught expr: ()");
-    assert_eq!(catch_range!((1 + 1) ... (2 + 2)), "macro caught expr: 2 ... 4");
+    assert_eq!(catch_range!((1 + 1) ..= (2 + 2)), "macro caught expr: 2 ..= 4");
     assert_eq!(match_attr!(#[attr] (1 + 2)), "attr matched expr");
     assert_eq!(test_user!(10, (20 + 2)), "expr");
 
index 74f513ef0814f621fcb8db1dfd2ba204aa2aeb72..cf07345d3433a4d4cff04aa336cfb6665274e138 100644 (file)
 
 pub fn main() {
     match 1 {
-        1 ... 3 => {}
+        1 ..= 3 => {}
         _ => panic!("should match range")
     }
     match 1 {
-        1 ... 3u16 => {}
+        1 ..= 3u16 => {}
         _ => panic!("should match range with inferred start type")
     }
     match 1 {
-        1u16 ... 3 => {}
+        1u16 ..= 3 => {}
         _ => panic!("should match range with inferred end type")
     }
 }
index 9aafcda1b02add7506e0697b741d176ef0658806..b63ca7defd61a252ea0d9b56771b03dcafd5f727 100644 (file)
@@ -15,7 +15,7 @@
 
 pub fn main() {
     match 7 {
-        s...e => (),
+        s..=e => (),
         _ => (),
     }
 }
index cf695a77ce1f1c86fef565b26e27c96a0358b844..859edb80a07438ca51be080cba7c18cf2fa01241 100644 (file)
@@ -12,7 +12,7 @@
 
 pub fn main() {
     match 5_usize {
-      1_usize...5_usize => {}
+      1_usize..=5_usize => {}
       _ => panic!("should match range"),
     }
     match 1_usize {
@@ -20,7 +20,7 @@ pub fn main() {
         _ => panic!("should match range start"),
     }
     match 5_usize {
-      6_usize...7_usize => panic!("shouldn't match range"),
+      6_usize..=7_usize => panic!("shouldn't match range"),
       _ => {}
     }
     match 7_usize {
@@ -29,23 +29,23 @@ pub fn main() {
     }
     match 5_usize {
       1_usize => panic!("should match non-first range"),
-      2_usize...6_usize => {}
+      2_usize..=6_usize => {}
       _ => panic!("math is broken")
     }
     match 'c' {
-      'a'...'z' => {}
+      'a'..='z' => {}
       _ => panic!("should suppport char ranges")
     }
     match -3 {
-      -7...5 => {}
+      -7..=5 => {}
       _ => panic!("should match signed range")
     }
     match 3.0f64 {
-      1.0...5.0 => {}
+      1.0..=5.0 => {}
       _ => panic!("should match float range")
     }
     match -1.5f64 {
-      -3.6...3.6 => {}
+      -3.6..=3.6 => {}
       _ => panic!("should match negative float range")
     }
     match 3.5 {
index 2292d97eaf4e5812f9943f81437e3547f344bca6..f38bd2de869712dcd976e21d6d40988fbd4ba527 100644 (file)
@@ -11,8 +11,8 @@
 pub fn main() {
     let i = 5;
     match &&&&i {
-        1 ... 3 => panic!(),
-        3 ... 8 => {},
+        1 ..= 3 => panic!(),
+        3 ..= 8 => {},
         _ => panic!(),
     }
 }
index 82f527f8cca88f6d6a286a2b5f88e3a66dca4618..809d111d74e65e2ac921756ffcadb05b68e4fae8 100644 (file)
@@ -74,7 +74,7 @@ error[E0631]: type mismatch in closure arguments
 LL |     g1(|_: (), _: ()| {}); //~ ERROR type mismatch
    |     ^^ -------------- found signature of `fn((), ()) -> _`
    |     |
-   |     expected signature of `for<'r> fn(&'r (), std::boxed::Box<for<'s> std::ops::Fn(&'s ()) + 'static>) -> _`
+   |     expected signature of `for<'r> fn(&'r (), std::boxed::Box<(dyn for<'s> std::ops::Fn(&'s ()) + 'static)>) -> _`
    |
 note: required by `g1`
   --> $DIR/anonymous-higher-ranked-lifetime.rs:33:1
@@ -102,7 +102,7 @@ error[E0631]: type mismatch in closure arguments
 LL |     g3(|_: (), _: ()| {}); //~ ERROR type mismatch
    |     ^^ -------------- found signature of `fn((), ()) -> _`
    |     |
-   |     expected signature of `for<'s> fn(&'s (), std::boxed::Box<for<'r> std::ops::Fn(&'r ()) + 'static>) -> _`
+   |     expected signature of `for<'s> fn(&'s (), std::boxed::Box<(dyn for<'r> std::ops::Fn(&'r ()) + 'static)>) -> _`
    |
 note: required by `g3`
   --> $DIR/anonymous-higher-ranked-lifetime.rs:35:1
@@ -130,7 +130,7 @@ error[E0631]: type mismatch in closure arguments
 LL |     h1(|_: (), _: (), _: (), _: ()| {}); //~ ERROR type mismatch
    |     ^^ ---------------------------- found signature of `fn((), (), (), ()) -> _`
    |     |
-   |     expected signature of `for<'r, 's> fn(&'r (), std::boxed::Box<for<'t0> std::ops::Fn(&'t0 ()) + 'static>, &'s (), for<'t0, 't1> fn(&'t0 (), &'t1 ())) -> _`
+   |     expected signature of `for<'r, 's> fn(&'r (), std::boxed::Box<(dyn for<'t0> std::ops::Fn(&'t0 ()) + 'static)>, &'s (), for<'t0, 't1> fn(&'t0 (), &'t1 ())) -> _`
    |
 note: required by `h1`
   --> $DIR/anonymous-higher-ranked-lifetime.rs:39:1
@@ -144,7 +144,7 @@ error[E0631]: type mismatch in closure arguments
 LL |     h2(|_: (), _: (), _: (), _: ()| {}); //~ ERROR type mismatch
    |     ^^ ---------------------------- found signature of `fn((), (), (), ()) -> _`
    |     |
-   |     expected signature of `for<'r, 't0> fn(&'r (), std::boxed::Box<for<'s> std::ops::Fn(&'s ()) + 'static>, &'t0 (), for<'s, 't1> fn(&'s (), &'t1 ())) -> _`
+   |     expected signature of `for<'r, 't0> fn(&'r (), std::boxed::Box<(dyn for<'s> std::ops::Fn(&'s ()) + 'static)>, &'t0 (), for<'s, 't1> fn(&'s (), &'t1 ())) -> _`
    |
 note: required by `h2`
   --> $DIR/anonymous-higher-ranked-lifetime.rs:40:1
index b3f9cbc587bac86053d5c1bd287267b6a86f5d5f..ec9e65fc4c62d3fb8717c1886e4a5d13bfdf4a76 100644 (file)
@@ -13,7 +13,7 @@ LL |     let x = Box::new(5usize) as Box<Foo>;
    |             ^^^^^^^^^^^^^^^^ the trait `Foo` cannot be made into an object
    |
    = note: method `foo` has a non-standard `self` type
-   = note: required because of the requirements on the impl of `std::ops::CoerceUnsized<std::boxed::Box<Foo>>` for `std::boxed::Box<usize>`
+   = note: required because of the requirements on the impl of `std::ops::CoerceUnsized<std::boxed::Box<dyn Foo>>` for `std::boxed::Box<usize>`
 
 error: aborting due to 2 previous errors
 
index 67c33740f19695d772211396bb5b6ddbc23150ba..1e871d472842097a4df8383d24716837ed788c2b 100644 (file)
@@ -1,4 +1,4 @@
-error[E0620]: cast to unsized type: `&{integer}` as `std::marker::Send`
+error[E0620]: cast to unsized type: `&{integer}` as `dyn std::marker::Send`
   --> $DIR/cast-to-unsized-trait-object-suggestion.rs:12:5
    |
 LL |     &1 as Send; //~ ERROR cast to unsized
@@ -6,7 +6,7 @@ LL |     &1 as Send; //~ ERROR cast to unsized
    |           |
    |           help: try casting to a reference instead: `&Send`
 
-error[E0620]: cast to unsized type: `std::boxed::Box<{integer}>` as `std::marker::Send`
+error[E0620]: cast to unsized type: `std::boxed::Box<{integer}>` as `dyn std::marker::Send`
   --> $DIR/cast-to-unsized-trait-object-suggestion.rs:13:5
    |
 LL |     Box::new(1) as Send; //~ ERROR cast to unsized
index a01ebb768b49b5f5cf62533d63cfdb6e3c80e0d0..aace8c0c02b20bfc9b447a3f3280948c9ec4ca23 100644 (file)
@@ -23,13 +23,13 @@ fn main() {
 
     match 10 {
         1..10 => {},
-        9...10 => {},
+        9..=10 => {},
         _ => {},
     }
 
     match 10 {
         1..10 => {},
-        10...10 => {},
+        10..=10 => {},
         _ => {},
     }
 
@@ -42,13 +42,13 @@ fn main() {
 
     match 10 {
         1..10 => {},
-        8...9 => {},
+        8..=9 => {},
         _ => {},
     }
 
     match 10 {
         1..10 => {},
-        9...9 => {},
+        9..=9 => {},
         _ => {},
     }
 }
index 111f4e44ee9c1192621e38cce53775bcfe24f6a9..2af6a2a636841989909e6b48f80fb1f843de0849 100644 (file)
@@ -13,12 +13,12 @@ LL | #![warn(unreachable_patterns)]
 warning: unreachable pattern
   --> $DIR/issue-43253.rs:45:9
    |
-LL |         8...9 => {},
+LL |         8..=9 => {},
    |         ^^^^^
 
 warning: unreachable pattern
   --> $DIR/issue-43253.rs:51:9
    |
-LL |         9...9 => {},
+LL |         9..=9 => {},
    |         ^^^^^
 
diff --git a/src/test/ui/closure-array-break-length.rs b/src/test/ui/closure-array-break-length.rs
new file mode 100644 (file)
index 0000000..2e99921
--- /dev/null
@@ -0,0 +1,17 @@
+// Copyright 2018 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() {
+    |_: [_; continue]| {}; //~ ERROR: `continue` outside of loop
+
+    while |_: [_; continue]| {} {} //~ ERROR: `break` or `continue` with no label
+
+    while |_: [_; break]| {} {} //~ ERROR: `break` or `continue` with no label
+}
diff --git a/src/test/ui/closure-array-break-length.stderr b/src/test/ui/closure-array-break-length.stderr
new file mode 100644 (file)
index 0000000..1391539
--- /dev/null
@@ -0,0 +1,22 @@
+error[E0268]: `continue` outside of loop
+  --> $DIR/closure-array-break-length.rs:12:13
+   |
+LL |     |_: [_; continue]| {}; //~ ERROR: `continue` outside of loop
+   |             ^^^^^^^^ cannot break outside of a loop
+
+error[E0590]: `break` or `continue` with no label in the condition of a `while` loop
+  --> $DIR/closure-array-break-length.rs:14:19
+   |
+LL |     while |_: [_; continue]| {} {} //~ ERROR: `break` or `continue` with no label
+   |                   ^^^^^^^^ unlabeled `continue` in the condition of a `while` loop
+
+error[E0590]: `break` or `continue` with no label in the condition of a `while` loop
+  --> $DIR/closure-array-break-length.rs:16:19
+   |
+LL |     while |_: [_; break]| {} {} //~ ERROR: `break` or `continue` with no label
+   |                   ^^^^^ unlabeled `break` in the condition of a `while` loop
+
+error: aborting due to 3 previous errors
+
+Some errors occurred: E0268, E0590.
+For more information about an error, try `rustc --explain E0268`.
index f53d6f3fa0a153fe132ba608bc00f66352c31d49..008ebf13c6354faf27666c63a5ecad42543d27d7 100644 (file)
@@ -13,7 +13,7 @@
 fn main() {
     const MIN: i8 = -5;
     match 5i8 {
-        MIN...-1 => {},
+        MIN..=-1 => {},
         _ => {},
     }
 }
diff --git a/src/test/ui/const-eval/ice-generic-assoc-const.rs b/src/test/ui/const-eval/ice-generic-assoc-const.rs
new file mode 100644 (file)
index 0000000..31e056b
--- /dev/null
@@ -0,0 +1,28 @@
+// Copyright 2018 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-pass
+
+pub trait Nullable {
+    const NULL: Self;
+
+    fn is_null(&self) -> bool;
+}
+
+impl<T> Nullable for *const T {
+    const NULL: Self = 0 as *const T;
+
+    fn is_null(&self) -> bool {
+        *self == Self::NULL
+    }
+}
+
+fn main() {
+}
index 4c5fc6c3797623983bda6f58c13ad1d1211c088b..8ad7f11f0cee8ebe2978cf09362aa58925ef906b 100644 (file)
@@ -11,8 +11,8 @@
 fn main() {
     let n: Int = 40;
     match n {
-        0...10 => {},
-        10...BAR => {}, //~ ERROR lower range bound must be less than or equal to upper
+        0..=10 => {},
+        10..=BAR => {}, //~ ERROR lower range bound must be less than or equal to upper
         _ => {},
     }
 }
index eef7b6df252fe5f21d48ce32fb7a362d41cc37b2..64ea57702d7063b595624f28f0d1c3636cec080e 100644 (file)
@@ -1,7 +1,7 @@
 error[E0030]: lower range bound must be less than or equal to upper
   --> $DIR/ref_to_int_match.rs:15:9
    |
-LL |         10...BAR => {}, //~ ERROR lower range bound must be less than or equal to upper
+LL |         10..=BAR => {}, //~ ERROR lower range bound must be less than or equal to upper
    |         ^^ lower bound larger than upper bound
 
 error: aborting due to previous error
index 2cde4aec2b5d47b84e1fb8cc67a1264fbe88394f..d6fc5391ba83111c1f1c3f55461d65b3e99951dc 100644 (file)
@@ -1,10 +1,10 @@
-error[E0277]: the size for value values of type `std::fmt::Debug + std::marker::Sync + 'static` cannot be known at compilation time
+error[E0277]: the size for value values of type `(dyn std::fmt::Debug + std::marker::Sync + 'static)` cannot be known at compilation time
   --> $DIR/const-unsized.rs:13:29
    |
 LL | const CONST_0: Debug+Sync = *(&0 as &(Debug+Sync));
    |                             ^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
    |
-   = help: the trait `std::marker::Sized` is not implemented for `std::fmt::Debug + std::marker::Sync + 'static`
+   = help: the trait `std::marker::Sized` is not implemented for `(dyn std::fmt::Debug + std::marker::Sync + 'static)`
    = note: to learn more, visit <https://doc.rust-lang.org/book/second-edition/ch19-04-advanced-types.html#dynamically-sized-types--sized>
    = note: constant expressions must have a statically known size
 
@@ -18,13 +18,13 @@ LL | const CONST_FOO: str = *"foo";
    = note: to learn more, visit <https://doc.rust-lang.org/book/second-edition/ch19-04-advanced-types.html#dynamically-sized-types--sized>
    = note: constant expressions must have a statically known size
 
-error[E0277]: the size for value values of type `std::fmt::Debug + std::marker::Sync + 'static` cannot be known at compilation time
+error[E0277]: the size for value values of type `(dyn std::fmt::Debug + std::marker::Sync + 'static)` cannot be known at compilation time
   --> $DIR/const-unsized.rs:19:31
    |
 LL | static STATIC_1: Debug+Sync = *(&1 as &(Debug+Sync));
    |                               ^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
    |
-   = help: the trait `std::marker::Sized` is not implemented for `std::fmt::Debug + std::marker::Sync + 'static`
+   = help: the trait `std::marker::Sized` is not implemented for `(dyn std::fmt::Debug + std::marker::Sync + 'static)`
    = note: to learn more, visit <https://doc.rust-lang.org/book/second-edition/ch19-04-advanced-types.html#dynamically-sized-types--sized>
    = note: constant expressions must have a statically known size
 
index 169a12ef92e987c1f8b6ad24aae7026ee01f52dd..33792d4f5b3fa4cb62efff4fe2ae71a42a6b3469 100644 (file)
@@ -92,7 +92,7 @@ error[E0223]: ambiguous associated type
 LL | type G = 'static + (Send)::AssocTy;
    |          ^^^^^^^^^^^^^^^^^^^^^^^^^ ambiguous associated type
    |
-   = note: specify the type using the syntax `<std::marker::Send + 'static as Trait>::AssocTy`
+   = note: specify the type using the syntax `<(dyn std::marker::Send + 'static) as Trait>::AssocTy`
 
 error[E0223]: ambiguous associated type
   --> $DIR/bad-assoc-ty.rs:43:10
@@ -100,7 +100,7 @@ error[E0223]: ambiguous associated type
 LL | type H = Fn(u8) -> (u8)::Output;
    |          ^^^^^^^^^^^^^^^^^^^^^^ ambiguous associated type
    |
-   = note: specify the type using the syntax `<std::ops::Fn(u8) -> u8 + 'static as Trait>::Output`
+   = note: specify the type using the syntax `<(dyn std::ops::Fn(u8) -> u8 + 'static) as Trait>::Output`
 
 error: aborting due to 15 previous errors
 
index 1bc2c2d58b1947c606dc0b04889cc525d1b6810b..328c46311af56b774177620d6979579ae4bb4db3 100644 (file)
@@ -14,7 +14,7 @@ fn main() {
     let s = "hoho";
 
     match s {
-        "hello" ... "world" => {}
+        "hello" ..= "world" => {}
         //~^ ERROR only char and numeric types are allowed in range patterns
         _ => {}
     }
index 4bb71f68a98b9bde2a83af0f0fce00a955bdfc4e..bb4fac9a4cb4c8d89031c188706a040f753a11f6 100644 (file)
@@ -1,7 +1,7 @@
 error[E0029]: only char and numeric types are allowed in range patterns
   --> $DIR/E0029-teach.rs:17:9
    |
-LL |         "hello" ... "world" => {}
+LL |         "hello" ..= "world" => {}
    |         ^^^^^^^^^^^^^^^^^^^ ranges require char or numeric types
    |
    = note: start type: &'static str
index 29b6fe44113582fca7e71ee40191c831a85d4ede..c89b4f5b3771f3e64238763be377b0fd6c958a60 100644 (file)
@@ -12,7 +12,7 @@ fn main() {
     let s = "hoho";
 
     match s {
-        "hello" ... "world" => {}
+        "hello" ..= "world" => {}
         //~^ ERROR only char and numeric types are allowed in range patterns
         _ => {}
     }
index bcdfa3871110752ac051a00e498d5f192fa2f97c..d25666f9cf84aae1d33a2dfb07ba6e263c810cd1 100644 (file)
@@ -1,7 +1,7 @@
 error[E0029]: only char and numeric types are allowed in range patterns
   --> $DIR/E0029.rs:15:9
    |
-LL |         "hello" ... "world" => {}
+LL |         "hello" ..= "world" => {}
    |         ^^^^^^^^^^^^^^^^^^^ ranges require char or numeric types
    |
    = note: start type: &'static str
index 2af32eda62be9043f47149c046768e301618d042..cf860cea24c86e17d7daffa2bef5a7e009229c28 100644 (file)
@@ -12,7 +12,7 @@
 
 fn main() {
     match 5u32 {
-        1000 ... 5 => {}
+        1000 ..= 5 => {}
         //~^ ERROR lower range bound must be less than or equal to upper
     }
 }
index 8b262d5b296b698aaccfdacabf7b65fc9fb36092..2a7243a95690e3f723717d513e242566fd29f289 100644 (file)
@@ -1,7 +1,7 @@
 error[E0030]: lower range bound must be less than or equal to upper
   --> $DIR/E0030-teach.rs:15:9
    |
-LL |         1000 ... 5 => {}
+LL |         1000 ..= 5 => {}
    |         ^^^^ lower bound larger than upper bound
    |
    = note: When matching against a range, the compiler verifies that the range is non-empty. Range patterns include both end-points, so this is equivalent to requiring the start of the range to be less than or equal to the end of the range.
index ef3bded4beffbfb8dd9badf22ca7691c997b6e8c..e147dd932b0ddf34b413baeadd7f1fa289bc5ce5 100644 (file)
@@ -11,7 +11,7 @@
 
 fn main() {
     match 5u32 {
-        1000 ... 5 => {}
+        1000 ..= 5 => {}
         //~^ ERROR lower range bound must be less than or equal to upper
     }
 }
index 0949cfb50b680ceb2dd7acb88a0de91f22e83a6f..020655ee45b541526433221583fdf6bbfe96bb34 100644 (file)
@@ -1,7 +1,7 @@
 error[E0030]: lower range bound must be less than or equal to upper
   --> $DIR/E0030.rs:14:9
    |
-LL |         1000 ... 5 => {}
+LL |         1000 ..= 5 => {}
    |         ^^^^ lower bound larger than upper bound
 
 error: aborting due to previous error
index c74485781c123db6f0b12848b97881aeac3a3064..2fac6080f496a263edec158d5909b59270fd88bc 100644 (file)
@@ -12,11 +12,11 @@ LL |     let trait_obj: &SomeTrait = SomeTrait;
    |
    = note: method `foo` has no receiver
 
-error[E0033]: type `&SomeTrait` cannot be dereferenced
+error[E0033]: type `&dyn SomeTrait` cannot be dereferenced
   --> $DIR/E0033-teach.rs:23:9
    |
 LL |     let &invalid = trait_obj;
-   |         ^^^^^^^^ type `&SomeTrait` cannot be dereferenced
+   |         ^^^^^^^^ type `&dyn SomeTrait` cannot be dereferenced
    |
    = note: This error indicates that a pointer to a trait type cannot be implicitly dereferenced by a pattern. Every trait defines a type, but because the size of trait implementors isn't fixed, this type has no compile-time size. Therefore, all accesses to trait types must be through pointers. If you encounter this error you should try to avoid dereferencing the pointer.
            
index a1e72d6f6695557da20d0500a1ee16393a35d3a4..5d789566beb066e9f0da6536ad9884840fe0123e 100644 (file)
@@ -12,11 +12,11 @@ LL |     let trait_obj: &SomeTrait = SomeTrait;
    |
    = note: method `foo` has no receiver
 
-error[E0033]: type `&SomeTrait` cannot be dereferenced
+error[E0033]: type `&dyn SomeTrait` cannot be dereferenced
   --> $DIR/E0033.rs:21:9
    |
 LL |     let &invalid = trait_obj;
-   |         ^^^^^^^^ type `&SomeTrait` cannot be dereferenced
+   |         ^^^^^^^^ type `&dyn SomeTrait` cannot be dereferenced
 
 error: aborting due to 3 previous errors
 
index bb4cd1434167b56b617e4b3c9fc0aca3339a3d7e..106c55817c11af4c8a580233f2de768f2845a2e7 100644 (file)
@@ -11,7 +11,7 @@
 fn main() {
     let x = 1u8;
     match x {
-        0u8...3i8 => (), //~ ERROR E0308
+        0u8..=3i8 => (), //~ ERROR E0308
         _ => ()
     }
 }
index 31875349bace08e6412dd029c9780f2b353572e6..8943c7332e94d21c5e0a119f3b1ce6599eb48ef9 100644 (file)
@@ -1,7 +1,7 @@
 error[E0308]: mismatched types
   --> $DIR/E0308-4.rs:14:9
    |
-LL |         0u8...3i8 => (), //~ ERROR E0308
+LL |         0u8..=3i8 => (), //~ ERROR E0308
    |         ^^^^^^^^^ expected u8, found i8
 
 error: aborting due to previous error
index 0cb8af9929418245cd5f0f91e58bb9e3658adc38..0777c44058fe81e3cf682c9448413d6789dfff45 100644 (file)
@@ -1,4 +1,4 @@
-error[E0558]: export_name attribute has invalid format
+error[E0558]: `export_name` attribute has invalid format
   --> $DIR/E0558.rs:11:1
    |
 LL | #[export_name]
diff --git a/src/test/ui/error-codes/E0648.rs b/src/test/ui/error-codes/E0648.rs
new file mode 100644 (file)
index 0000000..d3eac60
--- /dev/null
@@ -0,0 +1,14 @@
+// Copyright 2018 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.
+
+#[export_name="\0foo"] //~ ERROR E0648
+pub fn bar() {}
+
+fn main() {}
diff --git a/src/test/ui/error-codes/E0648.stderr b/src/test/ui/error-codes/E0648.stderr
new file mode 100644 (file)
index 0000000..1e11705
--- /dev/null
@@ -0,0 +1,9 @@
+error[E0648]: `export_name` may not contain null characters
+  --> $DIR/E0648.rs:11:1
+   |
+LL | #[export_name="/0foo"] //~ ERROR E0648
+   | ^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0648`.
index 05a4b8b3544f5dc1932017abf18d767305525af7..af91c9e26491185231b6cb16547b696e2465fa0b 100644 (file)
@@ -19,7 +19,7 @@ fn free_fn_capture_hrtb_in_impl_trait()
     -> Box<for<'a> Id<impl Lt<'a>>>
         //~^ ERROR `impl Trait` can only capture lifetimes bound at the fn or impl level [E0657]
 {
-    () //~ ERROR mismatched types
+    Box::new(())
 }
 
 struct Foo;
@@ -28,7 +28,7 @@ fn impl_fn_capture_hrtb_in_impl_trait()
         -> Box<for<'a> Id<impl Lt<'a>>>
             //~^ ERROR `impl Trait` can only capture lifetimes bound at the fn or impl level
     {
-        () //~ ERROR mismatched types
+        Box::new(())
     }
 }
 
index 23b9666de3cd9f0ea1e059125172bbb43825d062..737ae3a163ac20c219e2ed3db3929f9a4f184aae 100644 (file)
@@ -10,25 +10,6 @@ error[E0657]: `impl Trait` can only capture lifetimes bound at the fn or impl le
 LL |         -> Box<for<'a> Id<impl Lt<'a>>>
    |                                   ^^
 
-error[E0308]: mismatched types
-  --> $DIR/E0657.rs:22:5
-   |
-LL |     () //~ ERROR mismatched types
-   |     ^^ expected struct `std::boxed::Box`, found ()
-   |
-   = note: expected type `std::boxed::Box<Id<_> + 'static>`
-              found type `()`
-
-error[E0308]: mismatched types
-  --> $DIR/E0657.rs:31:9
-   |
-LL |         () //~ ERROR mismatched types
-   |         ^^ expected struct `std::boxed::Box`, found ()
-   |
-   = note: expected type `std::boxed::Box<Id<_> + 'static>`
-              found type `()`
-
-error: aborting due to 4 previous errors
+error: aborting due to 2 previous errors
 
-Some errors occurred: E0308, E0657.
-For more information about an error, try `rustc --explain E0308`.
+For more information about this error, try `rustc --explain E0657`.
index cf1dcfcb8ade39447de0a0951a0f477d469251b4..778a4cf1fa01f16de791a08cea0222409da44a71 100644 (file)
@@ -52,7 +52,7 @@ error[E0607]: cannot cast thin pointer `*const i32` to fat pointer `*const [i32]
 LL |     q as *const [i32]; //~ ERROR cannot cast
    |     ^^^^^^^^^^^^^^^^^
 
-error[E0606]: casting `usize` as `*mut Trait + 'static` is invalid
+error[E0606]: casting `usize` as `*mut (dyn Trait + 'static)` is invalid
   --> $DIR/fat-ptr-cast.rs:32:37
    |
 LL |     let t: *mut (Trait + 'static) = 0 as *mut _; //~ ERROR casting
index db280f2d1f763540068c4d73fd5712b36ba610e8..19a6a8637957eb91de7eb2e4c15ea9d9ab5ae67d 100644 (file)
@@ -98,7 +98,7 @@ LL | struct TwoStrs(str, str) where str: Sized; //~ ERROR
    = help: see issue #48214
    = help: add #![feature(trivial_bounds)] to the crate attributes to enable
 
-error[E0277]: the size for value values of type `A + 'static` cannot be known at compilation time
+error[E0277]: the size for value values of type `(dyn A + 'static)` cannot be known at compilation time
   --> $DIR/feature-gate-trivial_bounds.rs:65:1
    |
 LL | / fn unsized_local() where Dst<A>: Sized { //~ ERROR
@@ -106,9 +106,9 @@ LL | |     let x: Dst<A> = *(Box::new(Dst { x: 1 }) as Box<Dst<A>>);
 LL | | }
    | |_^ doesn't have a size known at compile-time
    |
-   = help: within `Dst<A + 'static>`, the trait `std::marker::Sized` is not implemented for `A + 'static`
+   = help: within `Dst<(dyn A + 'static)>`, the trait `std::marker::Sized` is not implemented for `(dyn A + 'static)`
    = note: to learn more, visit <https://doc.rust-lang.org/book/second-edition/ch19-04-advanced-types.html#dynamically-sized-types--sized>
-   = note: required because it appears within the type `Dst<A + 'static>`
+   = note: required because it appears within the type `Dst<(dyn A + 'static)>`
    = help: see issue #48214
    = help: add #![feature(trivial_bounds)] to the crate attributes to enable
 
index 807b499155b855955c11df69b719a14717e25f6e..0d9239d72276e899c6424bd26de45e4666faf111 100644 (file)
@@ -1,11 +1,11 @@
-error[E0277]: `*mut std::ops::Fn() + 'static` cannot be shared between threads safely
+error[E0277]: `*mut (dyn std::ops::Fn() + 'static)` cannot be shared between threads safely
   --> $DIR/send-sync.rs:18:5
    |
 LL |     send(format_args!("{:?}", c)); //~ ERROR E0277
-   |     ^^^^ `*mut std::ops::Fn() + 'static` cannot be shared between threads safely
+   |     ^^^^ `*mut (dyn std::ops::Fn() + 'static)` cannot be shared between threads safely
    |
-   = help: within `[std::fmt::ArgumentV1<'_>]`, the trait `std::marker::Sync` is not implemented for `*mut std::ops::Fn() + 'static`
-   = note: required because it appears within the type `std::marker::PhantomData<*mut std::ops::Fn() + 'static>`
+   = help: within `[std::fmt::ArgumentV1<'_>]`, the trait `std::marker::Sync` is not implemented for `*mut (dyn std::ops::Fn() + 'static)`
+   = note: required because it appears within the type `std::marker::PhantomData<*mut (dyn std::ops::Fn() + 'static)>`
    = note: required because it appears within the type `core::fmt::Void`
    = note: required because it appears within the type `&core::fmt::Void`
    = note: required because it appears within the type `std::fmt::ArgumentV1<'_>`
@@ -18,14 +18,14 @@ note: required by `send`
 LL | fn send<T: Send>(_: T) {}
    | ^^^^^^^^^^^^^^^^^^^^^^
 
-error[E0277]: `*mut std::ops::Fn() + 'static` cannot be shared between threads safely
+error[E0277]: `*mut (dyn std::ops::Fn() + 'static)` cannot be shared between threads safely
   --> $DIR/send-sync.rs:19:5
    |
 LL |     sync(format_args!("{:?}", c)); //~ ERROR E0277
-   |     ^^^^ `*mut std::ops::Fn() + 'static` cannot be shared between threads safely
+   |     ^^^^ `*mut (dyn std::ops::Fn() + 'static)` cannot be shared between threads safely
    |
-   = help: within `std::fmt::Arguments<'_>`, the trait `std::marker::Sync` is not implemented for `*mut std::ops::Fn() + 'static`
-   = note: required because it appears within the type `std::marker::PhantomData<*mut std::ops::Fn() + 'static>`
+   = help: within `std::fmt::Arguments<'_>`, the trait `std::marker::Sync` is not implemented for `*mut (dyn std::ops::Fn() + 'static)`
+   = note: required because it appears within the type `std::marker::PhantomData<*mut (dyn std::ops::Fn() + 'static)>`
    = note: required because it appears within the type `core::fmt::Void`
    = note: required because it appears within the type `&core::fmt::Void`
    = note: required because it appears within the type `std::fmt::ArgumentV1<'_>`
diff --git a/src/test/ui/hygiene/auxiliary/local_inner_macros.rs b/src/test/ui/hygiene/auxiliary/local_inner_macros.rs
new file mode 100644 (file)
index 0000000..caa2903
--- /dev/null
@@ -0,0 +1,29 @@
+// Copyright 2018 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.
+
+#[macro_export]
+macro_rules! helper1 {
+    () => ( struct S; )
+}
+
+#[macro_export(local_inner_macros)]
+macro_rules! helper2 {
+    () => ( helper1!(); )
+}
+
+#[macro_export(local_inner_macros)]
+macro_rules! public_macro {
+    () => ( helper2!(); )
+}
+
+#[macro_export(local_inner_macros)]
+macro_rules! public_macro_dynamic {
+    ($helper: ident) => ( $helper!(); )
+}
diff --git a/src/test/ui/hygiene/local_inner_macros.rs b/src/test/ui/hygiene/local_inner_macros.rs
new file mode 100644 (file)
index 0000000..787e2df
--- /dev/null
@@ -0,0 +1,31 @@
+// Copyright 2018 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-pass
+// aux-build:local_inner_macros.rs
+
+#![feature(use_extern_macros)]
+
+extern crate local_inner_macros;
+
+use local_inner_macros::{public_macro, public_macro_dynamic};
+
+public_macro!();
+
+macro_rules! local_helper {
+    () => ( struct Z; )
+}
+
+public_macro_dynamic!(local_helper);
+
+fn main() {
+    let s = S;
+    let z = Z;
+}
diff --git a/src/test/ui/hygiene/local_inner_macros_disabled.rs b/src/test/ui/hygiene/local_inner_macros_disabled.rs
new file mode 100644 (file)
index 0000000..00b3878
--- /dev/null
@@ -0,0 +1,21 @@
+// Copyright 2018 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.
+
+// `local_inner_macros` has no effect if `feature(use_extern_macros)` is not enabled
+
+// aux-build:local_inner_macros.rs
+// error-pattern: cannot find macro `helper2!` in this scope
+
+#[macro_use(public_macro)]
+extern crate local_inner_macros;
+
+public_macro!();
+
+fn main() {}
diff --git a/src/test/ui/hygiene/local_inner_macros_disabled.stderr b/src/test/ui/hygiene/local_inner_macros_disabled.stderr
new file mode 100644 (file)
index 0000000..64cb6c4
--- /dev/null
@@ -0,0 +1,10 @@
+error: cannot find macro `helper2!` in this scope
+  --> $DIR/local_inner_macros_disabled.rs:19:1
+   |
+LL | public_macro!();
+   | ^^^^^^^^^^^^^^^^
+   |
+   = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
+
+error: aborting due to previous error
+
index f6b64b394fc12580dfceb696ee1799170aea1713..a594ee8aab42a7033de49326de2e48e50b895234 100644 (file)
@@ -23,9 +23,7 @@ fn main() {
 // return type, which can't depend on the obligation.
 fn cycle1() -> impl Clone {
     //~^ ERROR cycle detected
-    //~| ERROR cycle detected
     send(cycle2().clone());
-    //~^ ERROR `std::rc::Rc<std::string::String>` cannot be sent between threads safely
 
     Rc::new(Cell::new(5))
 }
index b34facd2d39ce471e76832022c5f3ca92d66377f..490817c46f811368843c77c315dda72cb07cda53 100644 (file)
@@ -1,67 +1,29 @@
-error[E0391]: cycle detected when processing `cycle1::{{exist-impl-Trait}}`
-  --> $DIR/auto-trait-leak.rs:24:16
-   |
-LL | fn cycle1() -> impl Clone {
-   |                ^^^^^^^^^^
-   |
-note: ...which requires processing `cycle1`...
+error[E0391]: cycle detected when processing `cycle1`
   --> $DIR/auto-trait-leak.rs:24:1
    |
 LL | fn cycle1() -> impl Clone {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
 note: ...which requires evaluating trait selection obligation `impl std::clone::Clone: std::marker::Send`...
 note: ...which requires processing `cycle2::{{exist-impl-Trait}}`...
-  --> $DIR/auto-trait-leak.rs:33:16
+  --> $DIR/auto-trait-leak.rs:31:16
    |
 LL | fn cycle2() -> impl Clone {
    |                ^^^^^^^^^^
 note: ...which requires processing `cycle2`...
-  --> $DIR/auto-trait-leak.rs:33:1
+  --> $DIR/auto-trait-leak.rs:31:1
    |
 LL | fn cycle2() -> impl Clone {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^
 note: ...which requires evaluating trait selection obligation `impl std::clone::Clone: std::marker::Send`...
-   = note: ...which again requires processing `cycle1::{{exist-impl-Trait}}`, completing the cycle
-
-error[E0391]: cycle detected when processing `cycle1::{{exist-impl-Trait}}`
+note: ...which requires processing `cycle1::{{exist-impl-Trait}}`...
   --> $DIR/auto-trait-leak.rs:24:16
    |
 LL | fn cycle1() -> impl Clone {
    |                ^^^^^^^^^^
-   |
-note: ...which requires processing `cycle1`...
-  --> $DIR/auto-trait-leak.rs:24:1
-   |
-LL | fn cycle1() -> impl Clone {
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^
-note: ...which requires evaluating trait selection obligation `impl std::clone::Clone: std::marker::Send`...
-note: ...which requires processing `cycle2::{{exist-impl-Trait}}`...
-  --> $DIR/auto-trait-leak.rs:33:16
-   |
-LL | fn cycle2() -> impl Clone {
-   |                ^^^^^^^^^^
-note: ...which requires processing `cycle2`...
-  --> $DIR/auto-trait-leak.rs:33:1
-   |
-LL | fn cycle2() -> impl Clone {
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^
-   = note: ...which again requires processing `cycle1::{{exist-impl-Trait}}`, completing the cycle
-
-error[E0277]: `std::rc::Rc<std::string::String>` cannot be sent between threads safely
-  --> $DIR/auto-trait-leak.rs:27:5
-   |
-LL |     send(cycle2().clone());
-   |     ^^^^ `std::rc::Rc<std::string::String>` cannot be sent between threads safely
-   |
-   = help: within `impl std::clone::Clone`, the trait `std::marker::Send` is not implemented for `std::rc::Rc<std::string::String>`
-   = note: required because it appears within the type `impl std::clone::Clone`
-note: required by `send`
-  --> $DIR/auto-trait-leak.rs:16:1
-   |
-LL | fn send<T: Send>(_: T) {}
-   | ^^^^^^^^^^^^^^^^^^^^^^
+   = note: ...which again requires processing `cycle1`, completing the cycle
+note: cycle used when type-checking all item bodies
 
-error: aborting due to 3 previous errors
+error: aborting due to previous error
 
-Some errors occurred: E0277, E0391.
-For more information about an error, try `rustc --explain E0277`.
+For more information about this error, try `rustc --explain E0391`.
index b64caccd98abef8311b646deb96affdb375a3aeb..57a0040600a255d506e893c997c8b983494b9479 100644 (file)
@@ -34,9 +34,8 @@ fn projection_with_named_trait_is_disallowed(x: impl Iterator)
 fn projection_with_named_trait_inside_path_is_disallowed()
     -> <::std::ops::Range<impl Debug> as Iterator>::Item
 //~^ ERROR `impl Trait` is not allowed in path parameters
-//~| ERROR trait bound `impl std::fmt::Debug: std::iter::Step` is not satisfied
-{ //~ ERROR trait bound `impl std::fmt::Debug: std::iter::Step` is not satisfied
-    (1i32..100).next().unwrap() //~ ERROR mismatched types
+{
+    (1i32..100).next().unwrap()
 }
 
 fn projection_from_impl_trait_inside_dyn_trait_is_disallowed()
index b495d4b4b010b82890183f7631cea963eedc3ab4..f6d58984ecef747ae3994640d005c6380d7ae928 100644 (file)
@@ -17,7 +17,7 @@ LL |     -> <::std::ops::Range<impl Debug> as Iterator>::Item
    |                           ^^^^^^^^^^
 
 error[E0667]: `impl Trait` is not allowed in path parameters
-  --> $DIR/impl_trait_projections.rs:43:29
+  --> $DIR/impl_trait_projections.rs:42:29
    |
 LL |     -> <dyn Iterator<Item = impl Debug> as Iterator>::Item
    |                             ^^^^^^^^^^
@@ -30,34 +30,7 @@ LL | fn projection_is_disallowed(x: impl Iterator) -> <impl Iterator>::Item {
    |
    = note: specify the type using the syntax `<impl std::iter::Iterator as Trait>::Item`
 
-error[E0277]: the trait bound `impl std::fmt::Debug: std::iter::Step` is not satisfied
-  --> $DIR/impl_trait_projections.rs:38:1
-   |
-LL | / { //~ ERROR trait bound `impl std::fmt::Debug: std::iter::Step` is not satisfied
-LL | |     (1i32..100).next().unwrap() //~ ERROR mismatched types
-LL | | }
-   | |_^ the trait `std::iter::Step` is not implemented for `impl std::fmt::Debug`
-   |
-   = note: required because of the requirements on the impl of `std::iter::Iterator` for `std::ops::Range<impl std::fmt::Debug>`
-
-error[E0308]: mismatched types
-  --> $DIR/impl_trait_projections.rs:39:5
-   |
-LL |     (1i32..100).next().unwrap() //~ ERROR mismatched types
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected anonymized type, found i32
-   |
-   = note: expected type `impl std::fmt::Debug`
-              found type `i32`
-
-error[E0277]: the trait bound `impl std::fmt::Debug: std::iter::Step` is not satisfied
-  --> $DIR/impl_trait_projections.rs:35:8
-   |
-LL |     -> <::std::ops::Range<impl Debug> as Iterator>::Item
-   |        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::iter::Step` is not implemented for `impl std::fmt::Debug`
-   |
-   = note: required because of the requirements on the impl of `std::iter::Iterator` for `std::ops::Range<impl std::fmt::Debug>`
-
-error: aborting due to 8 previous errors
+error: aborting due to 5 previous errors
 
-Some errors occurred: E0223, E0277, E0308, E0667.
+Some errors occurred: E0223, E0667.
 For more information about an error, try `rustc --explain E0223`.
index 201470abe674cde98effb422f391cf95108a27a3..07b86228f61182466b75c15c17d784d6a8303cce 100644 (file)
@@ -10,8 +10,8 @@ note: first, the lifetime cannot outlive the lifetime 'a as defined on the funct
 LL | fn with_dyn_debug_static<'a>(x: Box<dyn Debug + 'a>) {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    = note: ...so that the expression is assignable:
-           expected std::boxed::Box<std::fmt::Debug>
-              found std::boxed::Box<std::fmt::Debug + 'a>
+           expected std::boxed::Box<dyn std::fmt::Debug>
+              found std::boxed::Box<(dyn std::fmt::Debug + 'a)>
    = note: but, the lifetime must be valid for the static lifetime...
    = note: ...so that the types are compatible:
            expected StaticTrait
index 37b586e1e3bd004dfb2e74007a750233aa0f85a1..169369c304eb22092fbfebaa2bc3ef638d08c3d3 100644 (file)
@@ -13,8 +13,8 @@ LL | |     }
    | |_____^
    = note: ...but the lifetime must also be valid for the static lifetime...
    = note: ...so that the method type is compatible with trait:
-           expected fn(&Struct) -> &Trait + 'static
-              found fn(&Struct) -> &Trait
+           expected fn(&Struct) -> &(dyn Trait + 'static)
+              found fn(&Struct) -> &dyn Trait
 
 error: aborting due to previous error
 
index c7b077014616c725793202a48b7b3cf415834337..5432d5f5ed910007cd5b76c1505801a7ad7bc86f 100644 (file)
@@ -13,10 +13,10 @@ fn main() {
     //~^ ERROR cast to unsized type: `&[usize; 2]` as `[usize]`
 
     let _bar = Box::new(1_usize) as std::fmt::Debug;
-    //~^ ERROR cast to unsized type: `std::boxed::Box<usize>` as `std::fmt::Debug`
+    //~^ ERROR cast to unsized type: `std::boxed::Box<usize>` as `dyn std::fmt::Debug`
 
     let _baz = 1_usize as std::fmt::Debug;
-    //~^ ERROR cast to unsized type: `usize` as `std::fmt::Debug`
+    //~^ ERROR cast to unsized type: `usize` as `dyn std::fmt::Debug`
 
     let _quux = [1_usize, 2] as [usize];
     //~^ ERROR cast to unsized type: `[usize; 2]` as `[usize]`
index 80ba49cce1a0cc5091469a2c11589463db269268..6c7e883f9f9c2c118c5354a6ec93cd9673a9e2c6 100644 (file)
@@ -10,7 +10,7 @@ help: consider using an implicit coercion to `&[usize]` instead
 LL |     let _foo = &[1_usize, 2] as [usize];
    |                ^^^^^^^^^^^^^^^^^^^^^^^^
 
-error[E0620]: cast to unsized type: `std::boxed::Box<usize>` as `std::fmt::Debug`
+error[E0620]: cast to unsized type: `std::boxed::Box<usize>` as `dyn std::fmt::Debug`
   --> $DIR/issue-17441.rs:15:16
    |
 LL |     let _bar = Box::new(1_usize) as std::fmt::Debug;
@@ -18,7 +18,7 @@ LL |     let _bar = Box::new(1_usize) as std::fmt::Debug;
    |                                     |
    |                                     help: try casting to a `Box` instead: `Box<std::fmt::Debug>`
 
-error[E0620]: cast to unsized type: `usize` as `std::fmt::Debug`
+error[E0620]: cast to unsized type: `usize` as `dyn std::fmt::Debug`
   --> $DIR/issue-17441.rs:18:16
    |
 LL |     let _baz = 1_usize as std::fmt::Debug;
index 1316773f6b789d3e088279779c94f1b9ac92c7f7..156ebd920f0d95e0955076b931625c61bd7a105e 100644 (file)
@@ -13,7 +13,7 @@ LL |     let _ = x
    |             ^ the trait `Array` cannot be made into an object
    |
    = note: the trait cannot require that `Self : Sized`
-   = note: required because of the requirements on the impl of `std::ops::CoerceUnsized<&Array>` for `&T`
+   = note: required because of the requirements on the impl of `std::ops::CoerceUnsized<&dyn Array>` for `&T`
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/issue-50577.rs b/src/test/ui/issue-50577.rs
new file mode 100644 (file)
index 0000000..a3bb687
--- /dev/null
@@ -0,0 +1,15 @@
+// Copyright 2018 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() {
+    enum Foo {
+        Drop = assert_eq!(1, 1)
+    }
+}
diff --git a/src/test/ui/issue-50577.stderr b/src/test/ui/issue-50577.stderr
new file mode 100644 (file)
index 0000000..8751303
--- /dev/null
@@ -0,0 +1,13 @@
+error[E0317]: if may be missing an else clause
+  --> $DIR/issue-50577.rs:13:16
+   |
+LL |         Drop = assert_eq!(1, 1)
+   |                ^^^^^^^^^^^^^^^^ expected (), found isize
+   |
+   = note: expected type `()`
+              found type `isize`
+   = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0317`.
index 4b20001457f78216b5a1feeb7f29d17feddb718b..7f22dc8739e76a6a42b47382d5eb282e95103ff5 100644 (file)
@@ -59,7 +59,7 @@ pub struct StructWithProjectionAndLifetime<'a>(
     pub fn char_type(p: char); //~ ERROR uses type `char`
     pub fn i128_type(p: i128); //~ ERROR uses type `i128`
     pub fn u128_type(p: u128); //~ ERROR uses type `u128`
-    pub fn trait_type(p: &Clone); //~ ERROR uses type `std::clone::Clone`
+    pub fn trait_type(p: &Clone); //~ ERROR uses type `dyn std::clone::Clone`
     pub fn tuple_type(p: (i32, i32)); //~ ERROR uses type `(i32, i32)`
     pub fn tuple_type2(p: I32Pair); //~ ERROR uses type `(i32, i32)`
     pub fn zero_size(p: ZeroSize); //~ ERROR struct has no fields
index 76b500e7d23bfe5058ff5a8590694296a54657f2..d1ef3a7a19c294b7983399a3c4813b724197b192 100644 (file)
@@ -73,10 +73,10 @@ error: `extern` block uses type `u128` which is not FFI-safe: 128-bit integers d
 LL |     pub fn u128_type(p: u128); //~ ERROR uses type `u128`
    |                         ^^^^
 
-error: `extern` block uses type `std::clone::Clone` which is not FFI-safe: trait objects have no C equivalent
+error: `extern` block uses type `dyn std::clone::Clone` which is not FFI-safe: trait objects have no C equivalent
   --> $DIR/lint-ctypes.rs:62:26
    |
-LL |     pub fn trait_type(p: &Clone); //~ ERROR uses type `std::clone::Clone`
+LL |     pub fn trait_type(p: &Clone); //~ ERROR uses type `dyn std::clone::Clone`
    |                          ^^^^^^
 
 error: `extern` block uses type `(i32, i32)` which is not FFI-safe: tuples have unspecified layout
diff --git a/src/test/ui/lint/inclusive-range-pattern-syntax.fixed b/src/test/ui/lint/inclusive-range-pattern-syntax.fixed
new file mode 100644 (file)
index 0000000..d16859d
--- /dev/null
@@ -0,0 +1,23 @@
+// Copyright 2018 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-pass
+// run-rustfix
+
+#![warn(ellipsis_inclusive_range_patterns)]
+
+fn main() {
+    let despondency = 2;
+    match despondency {
+        1..=2 => {}
+        //~^ WARN `...` range patterns are deprecated
+        _ => {}
+    }
+}
diff --git a/src/test/ui/lint/inclusive-range-pattern-syntax.rs b/src/test/ui/lint/inclusive-range-pattern-syntax.rs
new file mode 100644 (file)
index 0000000..9d418ae
--- /dev/null
@@ -0,0 +1,23 @@
+// Copyright 2018 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-pass
+// run-rustfix
+
+#![warn(ellipsis_inclusive_range_patterns)]
+
+fn main() {
+    let despondency = 2;
+    match despondency {
+        1...2 => {}
+        //~^ WARN `...` range patterns are deprecated
+        _ => {}
+    }
+}
diff --git a/src/test/ui/lint/inclusive-range-pattern-syntax.stderr b/src/test/ui/lint/inclusive-range-pattern-syntax.stderr
new file mode 100644 (file)
index 0000000..de04fed
--- /dev/null
@@ -0,0 +1,12 @@
+warning: `...` range patterns are deprecated
+  --> $DIR/inclusive-range-pattern-syntax.rs:19:10
+   |
+LL |         1...2 => {}
+   |          ^^^ help: use `..=` for an inclusive range
+   |
+note: lint level defined here
+  --> $DIR/inclusive-range-pattern-syntax.rs:14:9
+   |
+LL | #![warn(ellipsis_inclusive_range_patterns)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
index 6a69e7cc717208a2c0a19970802ff4d1ef9e0005..79442bd108a6759fe1ef27761d6e5309935bbf50 100644 (file)
@@ -9,8 +9,8 @@ LL | |         _ => y,
 LL | |     };
    | |_____^ expected bound lifetime parameter 'a, found concrete lifetime
    |
-   = note: expected type `&for<'a, 'b> Foo<&'a u8, &'b u8>`
-              found type `&for<'a> Foo<&'a u8, &'a u8>`
+   = note: expected type `&dyn for<'a, 'b> Foo<&'a u8, &'b u8>`
+              found type `&dyn for<'a> Foo<&'a u8, &'a u8>`
    = note: this was previously accepted by the compiler but has been phased out
    = note: for more information, see https://github.com/rust-lang/rust/issues/45852
 
index feaf492837f7f83b795717934763cd8890f760e8..9335795f6b8f322c0d3d0e6355f6ff61d0a025c1 100644 (file)
@@ -162,13 +162,13 @@ error[E0607]: cannot cast thin pointer `*const u8` to fat pointer `*const [u8]`
 LL |     let _ = v as *const [u8]; //~ ERROR cannot cast
    |             ^^^^^^^^^^^^^^^^
 
-error[E0606]: casting `&Foo` as `*const str` is invalid
+error[E0606]: casting `&dyn Foo` as `*const str` is invalid
   --> $DIR/cast-rfc0401.rs:64:13
    |
 LL |     let _ = foo as *const str; //~ ERROR is invalid
    |             ^^^^^^^^^^^^^^^^^
 
-error[E0606]: casting `&Foo` as `*mut str` is invalid
+error[E0606]: casting `&dyn Foo` as `*mut str` is invalid
   --> $DIR/cast-rfc0401.rs:65:13
    |
 LL |     let _ = foo as *mut str; //~ ERROR is invalid
@@ -200,7 +200,7 @@ LL |     let _ = fat_sv as usize; //~ ERROR is invalid
    |
    = help: cast through a thin pointer first
 
-error[E0606]: casting `*const Foo` as `*const [u16]` is invalid
+error[E0606]: casting `*const dyn Foo` as `*const [u16]` is invalid
   --> $DIR/cast-rfc0401.rs:78:13
    |
 LL |     let _ = cf as *const [u16]; //~ ERROR is invalid
@@ -208,7 +208,7 @@ LL |     let _ = cf as *const [u16]; //~ ERROR is invalid
    |
    = note: vtable kinds may not match
 
-error[E0606]: casting `*const Foo` as `*const Bar` is invalid
+error[E0606]: casting `*const dyn Foo` as `*const dyn Bar` is invalid
   --> $DIR/cast-rfc0401.rs:79:13
    |
 LL |     let _ = cf as *const Bar; //~ ERROR is invalid
@@ -224,7 +224,7 @@ LL |     let _ = fat_v as *const Foo; //~ ERROR the size for value values of typ
    |
    = help: the trait `std::marker::Sized` is not implemented for `[u8]`
    = note: to learn more, visit <https://doc.rust-lang.org/book/second-edition/ch19-04-advanced-types.html#dynamically-sized-types--sized>
-   = note: required for the cast to the object type `Foo`
+   = note: required for the cast to the object type `dyn Foo`
 
 error[E0277]: the size for value values of type `str` cannot be known at compilation time
   --> $DIR/cast-rfc0401.rs:72:13
@@ -234,7 +234,7 @@ LL |     let _ = a as *const Foo; //~ ERROR the size for value values of type
    |
    = help: the trait `std::marker::Sized` is not implemented for `str`
    = note: to learn more, visit <https://doc.rust-lang.org/book/second-edition/ch19-04-advanced-types.html#dynamically-sized-types--sized>
-   = note: required for the cast to the object type `Foo`
+   = note: required for the cast to the object type `dyn Foo`
 
 error[E0606]: casting `&{float}` as `f32` is invalid
   --> $DIR/cast-rfc0401.rs:81:30
index c838c617ae4534beba91cc99724e2b0b55d671e8..018ea941d12da20a3aadde361ed388a64718f0ad 100644 (file)
@@ -2,12 +2,12 @@ error[E0308]: mismatched types
   --> $DIR/issue-19109.rs:14:5
    |
 LL | fn function(t: &mut Trait) {
-   |                            - help: try adding a return type: `-> *mut Trait`
+   |                            - help: try adding a return type: `-> *mut dyn Trait`
 LL |     t as *mut Trait
    |     ^^^^^^^^^^^^^^^ expected (), found *-ptr
    |
    = note: expected type `()`
-              found type `*mut Trait`
+              found type `*mut dyn Trait`
 
 error: aborting due to previous error
 
index bbe9053430a1c8ff994b3fba02898a9d7f1cc1f9..15c9fd6bf8fe83d0ba22ea764f7eb148e854623c 100644 (file)
@@ -4,8 +4,8 @@ error[E0308]: mismatched types
 LL |     a(x); //~ ERROR mismatched types [E0308]
    |       ^ expected trait `Foo + std::marker::Send`, found trait `Foo`
    |
-   = note: expected type `std::boxed::Box<Foo + std::marker::Send + 'static>`
-              found type `std::boxed::Box<Foo + 'static>`
+   = note: expected type `std::boxed::Box<(dyn Foo + std::marker::Send + 'static)>`
+              found type `std::boxed::Box<(dyn Foo + 'static)>`
 
 error: aborting due to previous error
 
index 3689ca74adb8c304dc0b29796a0def435feba9ed..e07051135779ac6344bf4ba4fee317964e54fa76 100644 (file)
@@ -20,7 +20,7 @@ LL |     with_signature(x, |mut y| Box::new(y.next()))
                '_#1r,
                T,
                i32,
-               extern "rust-call" fn((std::boxed::Box<T>,)) -> std::boxed::Box<Anything + '_#2r>
+               extern "rust-call" fn((std::boxed::Box<T>,)) -> std::boxed::Box<(dyn Anything + '_#2r)>
            ]
    = note: number of external vids: 3
    = note: where <T as std::iter::Iterator>::Item: '_#2r
@@ -60,7 +60,7 @@ LL |     with_signature(x, |mut y| Box::new(y.next()))
                '_#1r,
                T,
                i32,
-               extern "rust-call" fn((std::boxed::Box<T>,)) -> std::boxed::Box<Anything + '_#2r>
+               extern "rust-call" fn((std::boxed::Box<T>,)) -> std::boxed::Box<(dyn Anything + '_#2r)>
            ]
    = note: number of external vids: 3
    = note: where <T as std::iter::Iterator>::Item: '_#2r
@@ -92,7 +92,7 @@ LL |     with_signature(x, |mut y| Box::new(y.next()))
                '_#2r,
                T,
                i32,
-               extern "rust-call" fn((std::boxed::Box<T>,)) -> std::boxed::Box<Anything + '_#3r>
+               extern "rust-call" fn((std::boxed::Box<T>,)) -> std::boxed::Box<(dyn Anything + '_#3r)>
            ]
    = note: number of external vids: 4
    = note: where <T as std::iter::Iterator>::Item: '_#3r
@@ -134,7 +134,7 @@ LL |     with_signature(x, |mut y| Box::new(y.next()))
                '_#2r,
                T,
                i32,
-               extern "rust-call" fn((std::boxed::Box<T>,)) -> std::boxed::Box<Anything + '_#3r>
+               extern "rust-call" fn((std::boxed::Box<T>,)) -> std::boxed::Box<(dyn Anything + '_#3r)>
            ]
    = note: number of external vids: 4
    = note: where <T as std::iter::Iterator>::Item: '_#3r
index 59a8a39a7b0857359cbf8d220c3b6ee4ed7053cf..39ad96cc6cd8e9ac47a75859080aadccc4a2df21 100644 (file)
@@ -20,7 +20,7 @@ LL |     with_signature(x, |y| y)
                '_#1r,
                T,
                i32,
-               extern "rust-call" fn((std::boxed::Box<T>,)) -> std::boxed::Box<std::fmt::Debug + '_#2r>
+               extern "rust-call" fn((std::boxed::Box<T>,)) -> std::boxed::Box<(dyn std::fmt::Debug + '_#2r)>
            ]
    = note: number of external vids: 3
    = note: where T: '_#2r
index 67a0f79ca6b82eb851d5cb399245c406571ed615..ce0c9947a05f67bb9ef281e30e421832a3528a4f 100644 (file)
 // older ... syntax is still allowed as a stability guarantee.
 
 #![feature(box_patterns)]
+#![warn(ellipsis_inclusive_range_patterns)]
+
 
 pub fn main() {
     match &12 {
         &0...9 => {}
+        //~^ WARN `...` range patterns are deprecated
+        //~| HELP use `..=` for an inclusive range
         &10..=15 => {}
         //~^ ERROR the range pattern here has ambiguous interpretation
         //~^^ HELP add parentheses to clarify the precedence
@@ -29,6 +33,8 @@ pub fn main() {
 
     match Box::new(12) {
         box 0...9 => {}
+        //~^ WARN `...` range patterns are deprecated
+        //~| HELP use `..=` for an inclusive range
         box 10..=15 => {}
         //~^ ERROR the range pattern here has ambiguous interpretation
         //~^^ HELP add parentheses to clarify the precedence
index 99e0d739036b09fea50146b29bd2222ee4de1c00..cd5ce3035c683247399ab268bbe3c0fac809c4bb 100644 (file)
@@ -1,14 +1,32 @@
 error: the range pattern here has ambiguous interpretation
-  --> $DIR/range-inclusive-pattern-precedence.rs:23:10
+  --> $DIR/range-inclusive-pattern-precedence.rs:27:10
    |
 LL |         &10..=15 => {}
    |          ^^^^^^^ help: add parentheses to clarify the precedence: `(10 ..=15)`
 
 error: the range pattern here has ambiguous interpretation
-  --> $DIR/range-inclusive-pattern-precedence.rs:32:13
+  --> $DIR/range-inclusive-pattern-precedence.rs:38:13
    |
 LL |         box 10..=15 => {}
    |             ^^^^^^^ help: add parentheses to clarify the precedence: `(10 ..=15)`
 
+warning: `...` range patterns are deprecated
+  --> $DIR/range-inclusive-pattern-precedence.rs:24:11
+   |
+LL |         &0...9 => {}
+   |           ^^^ help: use `..=` for an inclusive range
+   |
+note: lint level defined here
+  --> $DIR/range-inclusive-pattern-precedence.rs:19:9
+   |
+LL | #![warn(ellipsis_inclusive_range_patterns)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+warning: `...` range patterns are deprecated
+  --> $DIR/range-inclusive-pattern-precedence.rs:35:14
+   |
+LL |         box 0...9 => {}
+   |              ^^^ help: use `..=` for an inclusive range
+
 error: aborting due to 2 previous errors
 
index efcd0b3624811c76d4db90ee6c2329df367588ef..72bd270165fd09240f7bf584f4fff4466e0e96f5 100644 (file)
@@ -1,10 +1,10 @@
-error[E0277]: the size for value values of type `I + 'static` cannot be known at compilation time
+error[E0277]: the size for value values of type `(dyn I + 'static)` cannot be known at compilation time
   --> $DIR/issue-5035-2.rs:14:8
    |
 LL | fn foo(_x: K) {}
    |        ^^ doesn't have a size known at compile-time
    |
-   = help: the trait `std::marker::Sized` is not implemented for `I + 'static`
+   = help: the trait `std::marker::Sized` is not implemented for `(dyn I + 'static)`
    = note: to learn more, visit <https://doc.rust-lang.org/book/second-edition/ch19-04-advanced-types.html#dynamically-sized-types--sized>
    = note: all local variables must have a statically known size
 
index cf615eed55691d3fc1db747ee184707042d3c7b8..b318e778f8766b6c78f3d23290252a2bbdf67a3e 100644 (file)
@@ -2,7 +2,7 @@ error[E0596]: cannot borrow immutable item `*x` as mutable
   --> $DIR/borrowck-object-mutability.rs:19:5
    |
 LL | fn borrowed_receiver(x: &Foo) {
-   |                         ---- help: consider changing this to be a mutable reference: `&mut Foo`
+   |                         ---- help: consider changing this to be a mutable reference: `&mut dyn Foo`
 LL |     x.borrowed();
 LL |     x.borrowed_mut(); //~ ERROR cannot borrow
    |     ^ `x` is a `&` reference, so the data it refers to cannot be borrowed as mutable
index bd5efcd9fee7a756c81f25cee7e1804599eb3105..9049ffd40909007a94d56a40f5d664da56753e1c 100644 (file)
@@ -75,7 +75,7 @@ LL |     w.wrap.not_closure();
    |
    = help: did you mean to write `w.wrap.not_closure` instead of `w.wrap.not_closure(...)`?
 
-error[E0599]: no method named `closure` found for type `Obj<std::boxed::Box<std::boxed::FnBox<(), Output=u32> + 'static>>` in the current scope
+error[E0599]: no method named `closure` found for type `Obj<std::boxed::Box<(dyn std::boxed::FnBox<(), Output=u32> + 'static)>>` in the current scope
   --> $DIR/issue-2392.rs:72:24
    |
 LL | struct Obj<F> where F: FnOnce() -> u32 {
index ee2ff7d7861396d5353f2b5e9817e1ca389b2fd1..e18018c6f0c0172a074abe4e32b98f6034df6591 100644 (file)
@@ -6,7 +6,7 @@ LL | struct S(str, str) where str: Sized;
    |
    = note: #[warn(trivial_bounds)] on by default
 
-warning: Trait bound for<'a> T<A + 'a>: std::marker::Sized does not depend on any type or lifetime parameters
+warning: Trait bound for<'a> T<(dyn A + 'a)>: std::marker::Sized does not depend on any type or lifetime parameters
   --> $DIR/trivial-bounds-inconsistent-sized.rs:26:1
    |
 LL | / fn unsized_local() where for<'a> T<A + 'a>: Sized {
index ee3c7518294773e9dfee69b672440a4c2cbee720..85b16b17042f640862c23da564c98a017d038434 100644 (file)
@@ -78,7 +78,7 @@ warning: Trait bound str: std::marker::Sized does not depend on any type or life
 LL | struct TwoStrs(str, str) where str: Sized;
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-warning: Trait bound for<'a> Dst<A + 'a>: std::marker::Sized does not depend on any type or lifetime parameters
+warning: Trait bound for<'a> Dst<(dyn A + 'a)>: std::marker::Sized does not depend on any type or lifetime parameters
   --> $DIR/trivial-bounds-inconsistent.rs:65:1
    |
 LL | / fn unsized_local() where for<'a> Dst<A + 'a>: Sized {
index 98249d3f2b567cbfac23e87ff46a620e8dc97b8c..cb545ca008d6581f503d6360ece9a41723367cfc 100644 (file)
@@ -19,8 +19,8 @@ LL |     Box::new(items.iter()) //~ ERROR cannot infer an appropriate lifetime
    |              ^^^^^
    = note: but, the lifetime must be valid for the static lifetime...
    = note: ...so that the expression is assignable:
-           expected std::boxed::Box<std::iter::Iterator<Item=&T> + 'static>
-              found std::boxed::Box<std::iter::Iterator<Item=&T>>
+           expected std::boxed::Box<(dyn std::iter::Iterator<Item=&T> + 'static)>
+              found std::boxed::Box<dyn std::iter::Iterator<Item=&T>>
 
 error: aborting due to previous error
 
index ff2aa1d1ef91778321049ab8101d545a0732b494..1f30c815d30a8be7bba90b1ecee850bfa4bddff6 100644 (file)
@@ -82,43 +82,43 @@ LL |     VH{u: isize, x: [u32]},
    = note: to learn more, visit <https://doc.rust-lang.org/book/second-edition/ch19-04-advanced-types.html#dynamically-sized-types--sized>
    = note: no field of an enum variant may have a dynamically sized type
 
-error[E0277]: the size for value values of type `Foo + 'static` cannot be known at compilation time
+error[E0277]: the size for value values of type `(dyn Foo + 'static)` cannot be known at compilation time
   --> $DIR/unsized-enum2.rs:63:8
    |
 LL |     VM(Foo),
    |        ^^^ doesn't have a size known at compile-time
    |
-   = help: the trait `std::marker::Sized` is not implemented for `Foo + 'static`
+   = help: the trait `std::marker::Sized` is not implemented for `(dyn Foo + 'static)`
    = note: to learn more, visit <https://doc.rust-lang.org/book/second-edition/ch19-04-advanced-types.html#dynamically-sized-types--sized>
    = note: no field of an enum variant may have a dynamically sized type
 
-error[E0277]: the size for value values of type `Bar + 'static` cannot be known at compilation time
+error[E0277]: the size for value values of type `(dyn Bar + 'static)` cannot be known at compilation time
   --> $DIR/unsized-enum2.rs:65:8
    |
 LL |     VN{x: Bar},
    |        ^^^^^^ doesn't have a size known at compile-time
    |
-   = help: the trait `std::marker::Sized` is not implemented for `Bar + 'static`
+   = help: the trait `std::marker::Sized` is not implemented for `(dyn Bar + 'static)`
    = note: to learn more, visit <https://doc.rust-lang.org/book/second-edition/ch19-04-advanced-types.html#dynamically-sized-types--sized>
    = note: no field of an enum variant may have a dynamically sized type
 
-error[E0277]: the size for value values of type `FooBar + 'static` cannot be known at compilation time
+error[E0277]: the size for value values of type `(dyn FooBar + 'static)` cannot be known at compilation time
   --> $DIR/unsized-enum2.rs:67:15
    |
 LL |     VO(isize, FooBar),
    |               ^^^^^^ doesn't have a size known at compile-time
    |
-   = help: the trait `std::marker::Sized` is not implemented for `FooBar + 'static`
+   = help: the trait `std::marker::Sized` is not implemented for `(dyn FooBar + 'static)`
    = note: to learn more, visit <https://doc.rust-lang.org/book/second-edition/ch19-04-advanced-types.html#dynamically-sized-types--sized>
    = note: no field of an enum variant may have a dynamically sized type
 
-error[E0277]: the size for value values of type `BarFoo + 'static` cannot be known at compilation time
+error[E0277]: the size for value values of type `(dyn BarFoo + 'static)` cannot be known at compilation time
   --> $DIR/unsized-enum2.rs:69:18
    |
 LL |     VP{u: isize, x: BarFoo},
    |                  ^^^^^^^^^ doesn't have a size known at compile-time
    |
-   = help: the trait `std::marker::Sized` is not implemented for `BarFoo + 'static`
+   = help: the trait `std::marker::Sized` is not implemented for `(dyn BarFoo + 'static)`
    = note: to learn more, visit <https://doc.rust-lang.org/book/second-edition/ch19-04-advanced-types.html#dynamically-sized-types--sized>
    = note: no field of an enum variant may have a dynamically sized type
 
@@ -162,46 +162,46 @@ LL |     VT{u: isize, x: <&'static [i32] as Deref>::Target},
    = note: to learn more, visit <https://doc.rust-lang.org/book/second-edition/ch19-04-advanced-types.html#dynamically-sized-types--sized>
    = note: no field of an enum variant may have a dynamically sized type
 
-error[E0277]: the size for value values of type `PathHelper1 + 'static` cannot be known at compilation time
+error[E0277]: the size for value values of type `(dyn PathHelper1 + 'static)` cannot be known at compilation time
   --> $DIR/unsized-enum2.rs:53:8
    |
 LL |     VI(Path1),
    |        ^^^^^ doesn't have a size known at compile-time
    |
-   = help: within `Path1`, the trait `std::marker::Sized` is not implemented for `PathHelper1 + 'static`
+   = help: within `Path1`, the trait `std::marker::Sized` is not implemented for `(dyn PathHelper1 + 'static)`
    = note: to learn more, visit <https://doc.rust-lang.org/book/second-edition/ch19-04-advanced-types.html#dynamically-sized-types--sized>
    = note: required because it appears within the type `Path1`
    = note: no field of an enum variant may have a dynamically sized type
 
-error[E0277]: the size for value values of type `PathHelper2 + 'static` cannot be known at compilation time
+error[E0277]: the size for value values of type `(dyn PathHelper2 + 'static)` cannot be known at compilation time
   --> $DIR/unsized-enum2.rs:55:8
    |
 LL |     VJ{x: Path2},
    |        ^^^^^^^^ doesn't have a size known at compile-time
    |
-   = help: within `Path2`, the trait `std::marker::Sized` is not implemented for `PathHelper2 + 'static`
+   = help: within `Path2`, the trait `std::marker::Sized` is not implemented for `(dyn PathHelper2 + 'static)`
    = note: to learn more, visit <https://doc.rust-lang.org/book/second-edition/ch19-04-advanced-types.html#dynamically-sized-types--sized>
    = note: required because it appears within the type `Path2`
    = note: no field of an enum variant may have a dynamically sized type
 
-error[E0277]: the size for value values of type `PathHelper3 + 'static` cannot be known at compilation time
+error[E0277]: the size for value values of type `(dyn PathHelper3 + 'static)` cannot be known at compilation time
   --> $DIR/unsized-enum2.rs:57:15
    |
 LL |     VK(isize, Path3),
    |               ^^^^^ doesn't have a size known at compile-time
    |
-   = help: within `Path3`, the trait `std::marker::Sized` is not implemented for `PathHelper3 + 'static`
+   = help: within `Path3`, the trait `std::marker::Sized` is not implemented for `(dyn PathHelper3 + 'static)`
    = note: to learn more, visit <https://doc.rust-lang.org/book/second-edition/ch19-04-advanced-types.html#dynamically-sized-types--sized>
    = note: required because it appears within the type `Path3`
    = note: no field of an enum variant may have a dynamically sized type
 
-error[E0277]: the size for value values of type `PathHelper4 + 'static` cannot be known at compilation time
+error[E0277]: the size for value values of type `(dyn PathHelper4 + 'static)` cannot be known at compilation time
   --> $DIR/unsized-enum2.rs:59:18
    |
 LL |     VL{u: isize, x: Path4},
    |                  ^^^^^^^^ doesn't have a size known at compile-time
    |
-   = help: within `Path4`, the trait `std::marker::Sized` is not implemented for `PathHelper4 + 'static`
+   = help: within `Path4`, the trait `std::marker::Sized` is not implemented for `(dyn PathHelper4 + 'static)`
    = note: to learn more, visit <https://doc.rust-lang.org/book/second-edition/ch19-04-advanced-types.html#dynamically-sized-types--sized>
    = note: required because it appears within the type `Path4`
    = note: no field of an enum variant may have a dynamically sized type