]> git.lizzy.rs Git - rust.git/commitdiff
Rollup merge of #42159 - Havvy:doc-drop, r=steveklabnik
authorMark Simulacrum <mark.simulacrum@gmail.com>
Thu, 25 May 2017 01:50:06 +0000 (19:50 -0600)
committerGitHub <noreply@github.com>
Thu, 25 May 2017 01:50:06 +0000 (19:50 -0600)
Document drop more.

Adds two examples to Drop and describes the recursive drop on types that contain fields.

345 files changed:
src/doc/unstable-book/src/SUMMARY.md
src/doc/unstable-book/src/language-features/attr-literals.md
src/doc/unstable-book/src/language-features/catch-expr.md
src/doc/unstable-book/src/language-features/loop-break-value.md [deleted file]
src/doc/unstable-book/src/language-features/on-unimplemented.md
src/libcollections/range.rs
src/libcollections/slice.rs
src/libcore/iter/range.rs
src/libcore/ops.rs
src/libcore/option.rs
src/libcore/slice/mod.rs
src/libcore/str/mod.rs
src/libcore/tests/lib.rs
src/libcore/tests/ops.rs
src/librustc/dep_graph/dep_node.rs
src/librustc/hir/lowering.rs
src/librustc/infer/mod.rs
src/librustc/lib.rs
src/librustc/traits/README.md
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/context.rs
src/librustc/ty/flags.rs
src/librustc/ty/fold.rs
src/librustc/ty/layout.rs
src/librustc/ty/maps.rs
src/librustc/ty/mod.rs
src/librustc/ty/util.rs
src/librustc/util/ppaux.rs
src/librustc_borrowck/borrowck/check_loans.rs
src/librustc_borrowck/borrowck/mir/elaborate_drops.rs
src/librustc_borrowck/borrowck/mir/gather_moves.rs
src/librustc_borrowck/borrowck/mir/mod.rs
src/librustc_borrowck/borrowck/mod.rs
src/librustc_const_eval/check_match.rs
src/librustc_driver/lib.rs
src/librustc_errors/lib.rs
src/librustc_lint/builtin.rs
src/librustc_mir/build/expr/as_operand.rs
src/librustc_mir/build/expr/as_rvalue.rs
src/librustc_mir/build/expr/as_temp.rs
src/librustc_mir/build/mod.rs
src/librustc_mir/build/scope.rs
src/librustc_mir/hair/cx/mod.rs
src/librustc_mir/shim.rs
src/librustc_mir/transform/inline.rs
src/librustc_mir/transform/qualify_consts.rs
src/librustc_mir/transform/type_check.rs
src/librustc_mir/util/elaborate_drops.rs
src/librustc_passes/consts.rs
src/librustc_trans/context.rs
src/librustc_typeck/check/compare_method.rs
src/librustc_typeck/check/dropck.rs
src/librustc_typeck/check/method/probe.rs
src/librustc_typeck/check/mod.rs
src/librustc_typeck/check/regionck.rs
src/librustc_typeck/coherence/builtin.rs
src/librustc_typeck/lib.rs
src/librustdoc/clean/inline.rs
src/librustdoc/clean/mod.rs
src/libstd/ffi/c_str.rs
src/libstd/rt.rs
src/libstd/sync/mpsc/mpsc_queue.rs
src/libstd/sync/mpsc/spsc_queue.rs
src/libstd/sys/redox/thread_local.rs
src/libstd/thread/mod.rs
src/libsyntax/attr.rs
src/libsyntax/ext/tt/macro_parser.rs
src/libsyntax/ext/tt/macro_rules.rs
src/libsyntax/feature_gate.rs
src/libsyntax/parse/lexer/unicode_chars.rs
src/libsyntax/parse/mod.rs
src/libsyntax/parse/parser.rs
src/libsyntax/tokenstream.rs
src/test/compile-fail/E0277-2.rs
src/test/compile-fail/E0277.rs
src/test/compile-fail/const-unsized.rs
src/test/compile-fail/feature-gate-loop-break-value.rs [deleted file]
src/test/compile-fail/impl-trait/auto-trait-leak.rs
src/test/compile-fail/isssue-38821.rs [new file with mode: 0644]
src/test/compile-fail/loop-break-value.rs
src/test/compile-fail/on-unimplemented/multiple-impls.rs
src/test/compile-fail/on-unimplemented/on-impl.rs
src/test/compile-fail/on-unimplemented/on-trait.rs
src/test/compile-fail/on-unimplemented/slice-index.rs
src/test/compile-fail/partialeq_help.rs [new file with mode: 0644]
src/test/compile-fail/trait-suggest-where-clause.rs
src/test/mir-opt/storage_live_dead_in_statics.rs [new file with mode: 0644]
src/test/parse-fail/unicode-chars.rs
src/test/run-make/atomic-lock-free/atomic_lock_free.rs
src/test/run-pass/diverging-fallback-control-flow.rs
src/test/run-pass/loop-break-value.rs
src/test/run-pass/range_inclusive.rs
src/test/rustdoc/inline_cross/auxiliary/renamed-via-module.rs [new file with mode: 0644]
src/test/rustdoc/inline_cross/renamed-via-module.rs [new file with mode: 0644]
src/test/ui/borrowck/borrowck-in-static.stderr
src/test/ui/borrowck/unboxed-closures-move-upvar-from-non-once-ref-closure.stderr
src/test/ui/check_match/issue-35609.stderr
src/test/ui/codemap_tests/bad-format-args.stderr
src/test/ui/codemap_tests/coherence-overlapping-inherent-impl-trait.stderr
src/test/ui/codemap_tests/empty_span.stderr
src/test/ui/codemap_tests/huge_multispan_highlight.stderr
src/test/ui/codemap_tests/issue-11715.stderr
src/test/ui/codemap_tests/issue-28308.stderr
src/test/ui/codemap_tests/one_line.stderr
src/test/ui/codemap_tests/overlapping_inherent_impls.stderr
src/test/ui/codemap_tests/overlapping_spans.stderr
src/test/ui/codemap_tests/tab.stderr
src/test/ui/codemap_tests/unicode.stderr
src/test/ui/coercion-missing-tail-expected-type.stderr
src/test/ui/compare-method/proj-outlives-region.stderr
src/test/ui/compare-method/region-extra-2.stderr
src/test/ui/compare-method/region-extra.stderr
src/test/ui/compare-method/region-unrelated.stderr
src/test/ui/compare-method/reordered-type-param.stderr
src/test/ui/compare-method/trait-bound-on-type-parameter.stderr
src/test/ui/compare-method/traits-misc-mismatch-1.stderr
src/test/ui/compare-method/traits-misc-mismatch-2.stderr
src/test/ui/cross-crate-macro-backtrace/main.stderr
src/test/ui/did_you_mean/E0178.stderr
src/test/ui/did_you_mean/issue-21659-show-relevant-trait-impls-1.stderr
src/test/ui/did_you_mean/issue-21659-show-relevant-trait-impls-2.stderr
src/test/ui/did_you_mean/issue-31424.stderr
src/test/ui/did_you_mean/issue-34126.stderr
src/test/ui/did_you_mean/issue-34337.stderr
src/test/ui/did_you_mean/issue-35937.stderr
src/test/ui/did_you_mean/issue-36798.stderr
src/test/ui/did_you_mean/issue-36798_unknown_field.stderr
src/test/ui/did_you_mean/issue-37139.stderr
src/test/ui/did_you_mean/issue-38054-do-not-show-unresolved-names.stderr
src/test/ui/did_you_mean/issue-38147-1.stderr
src/test/ui/did_you_mean/issue-38147-2.stderr
src/test/ui/did_you_mean/issue-38147-3.stderr
src/test/ui/did_you_mean/issue-38147-4.stderr
src/test/ui/did_you_mean/issue-39544.stderr
src/test/ui/did_you_mean/issue-39802-show-5-trait-impls.stderr
src/test/ui/did_you_mean/issue-40006.stderr
src/test/ui/did_you_mean/issue-40396.stderr
src/test/ui/did_you_mean/issue-40823.stderr
src/test/ui/did_you_mean/issue-41679.stderr
src/test/ui/did_you_mean/recursion_limit.stderr
src/test/ui/did_you_mean/recursion_limit_deref.stderr
src/test/ui/did_you_mean/trait-object-reference-without-parens-suggestion.stderr
src/test/ui/dropck/dropck-eyepatch-extern-crate.stderr
src/test/ui/dropck/dropck-eyepatch-implies-unsafe-impl.stderr
src/test/ui/dropck/dropck-eyepatch-reorder.stderr
src/test/ui/dropck/dropck-eyepatch.stderr
src/test/ui/fmt/format-string-error.stderr
src/test/ui/fn_once-moved.stderr
src/test/ui/impl-trait/equality.stderr
src/test/ui/invalid-module-declaration/invalid-module-declaration.stderr
src/test/ui/issue-37311-type-length-limit/issue-37311.stderr
src/test/ui/issue-40402-ref-hints/issue-40402-1.stderr
src/test/ui/issue-40402-ref-hints/issue-40402-2.stderr
src/test/ui/issue-41652/issue_41652.stderr
src/test/ui/lifetime-errors/ex1-return-one-existing-name-if-else.stderr
src/test/ui/lifetime-errors/ex1b-return-no-names-if-else.stderr
src/test/ui/lifetime-errors/ex2a-push-one-existing-name.stderr
src/test/ui/lifetime-errors/ex2b-push-no-existing-names.stderr
src/test/ui/lifetime-errors/ex2c-push-inference-variable.stderr
src/test/ui/lifetime-errors/ex2d-push-inference-variable-2.stderr
src/test/ui/lifetime-errors/ex2e-push-inference-variable-3.stderr
src/test/ui/lifetimes/borrowck-let-suggestion.stderr
src/test/ui/lint/command-line-lint-group-deny.stderr
src/test/ui/lint/command-line-lint-group-forbid.stderr
src/test/ui/lint/lint-group-style.stderr
src/test/ui/loop-break-value-no-repeat.rs
src/test/ui/loop-break-value-no-repeat.stderr
src/test/ui/macros/bad_hello.stderr
src/test/ui/macros/format-foreign.stderr
src/test/ui/macros/macro-backtrace-invalid-internals.stderr
src/test/ui/macros/macro-backtrace-nested.stderr
src/test/ui/macros/macro-backtrace-println.stderr
src/test/ui/mismatched_types/E0053.stderr
src/test/ui/mismatched_types/E0281.stderr
src/test/ui/mismatched_types/E0409.stderr
src/test/ui/mismatched_types/abridged.stderr
src/test/ui/mismatched_types/binops.stderr
src/test/ui/mismatched_types/cast-rfc0401.stderr
src/test/ui/mismatched_types/closure-arg-count.stderr
src/test/ui/mismatched_types/closure-mismatch.stderr
src/test/ui/mismatched_types/const-fn-in-trait.stderr
src/test/ui/mismatched_types/fn-variance-1.stderr
src/test/ui/mismatched_types/issue-19109.stderr
src/test/ui/mismatched_types/issue-26480.stderr
src/test/ui/mismatched_types/issue-35030.stderr
src/test/ui/mismatched_types/issue-36053-2.stderr
src/test/ui/mismatched_types/issue-38371.stderr
src/test/ui/mismatched_types/main.stderr
src/test/ui/mismatched_types/method-help-unsatisfied-bound.stderr
src/test/ui/mismatched_types/overloaded-calls-bad.stderr
src/test/ui/mismatched_types/trait-bounds-cant-coerce.stderr
src/test/ui/mismatched_types/trait-impl-fn-incompatibility.stderr
src/test/ui/mismatched_types/unboxed-closures-vtable-mismatch.stderr
src/test/ui/missing-items/issue-40221.stderr
src/test/ui/missing-items/m2.stderr
src/test/ui/missing-items/missing-type-parameter.stderr
src/test/ui/pub/pub-restricted-error-fn.stderr
src/test/ui/pub/pub-restricted-error.stderr
src/test/ui/pub/pub-restricted-non-path.stderr
src/test/ui/pub/pub-restricted.stderr
src/test/ui/reachable/expr_add.stderr
src/test/ui/reachable/expr_again.stderr
src/test/ui/reachable/expr_array.stderr
src/test/ui/reachable/expr_assign.stderr
src/test/ui/reachable/expr_block.stderr
src/test/ui/reachable/expr_box.stderr
src/test/ui/reachable/expr_call.stderr
src/test/ui/reachable/expr_cast.stderr
src/test/ui/reachable/expr_if.stderr
src/test/ui/reachable/expr_loop.stderr
src/test/ui/reachable/expr_match.stderr
src/test/ui/reachable/expr_method.stderr
src/test/ui/reachable/expr_repeat.stderr
src/test/ui/reachable/expr_return.stderr
src/test/ui/reachable/expr_struct.stderr
src/test/ui/reachable/expr_tup.stderr
src/test/ui/reachable/expr_type.stderr
src/test/ui/reachable/expr_unary.stderr
src/test/ui/reachable/expr_while.stderr
src/test/ui/regions-fn-subtyping-return-static.stderr
src/test/ui/resolve/enums-are-namespaced-xc.stderr
src/test/ui/resolve/issue-14254.stderr
src/test/ui/resolve/issue-16058.stderr
src/test/ui/resolve/issue-17518.stderr
src/test/ui/resolve/issue-18252.stderr
src/test/ui/resolve/issue-19452.stderr
src/test/ui/resolve/issue-23305.stderr
src/test/ui/resolve/issue-2356.stderr
src/test/ui/resolve/issue-24968.stderr
src/test/ui/resolve/issue-33876.stderr
src/test/ui/resolve/issue-3907-2.stderr
src/test/ui/resolve/issue-39226.stderr
src/test/ui/resolve/issue-5035-2.stderr
src/test/ui/resolve/issue-6702.stderr
src/test/ui/resolve/levenshtein.stderr
src/test/ui/resolve/privacy-struct-ctor.stderr
src/test/ui/resolve/resolve-assoc-suggestions.stderr
src/test/ui/resolve/resolve-hint-macro.stderr
src/test/ui/resolve/resolve-speculative-adjustment.stderr
src/test/ui/resolve/suggest-path-instead-of-mod-dot-item.stderr
src/test/ui/resolve/token-error-correct-2.stderr
src/test/ui/resolve/token-error-correct-3.stderr
src/test/ui/resolve/token-error-correct.stderr
src/test/ui/resolve/tuple-struct-alias.stderr
src/test/ui/resolve/unresolved_static_type_field.stderr
src/test/ui/span/E0046.stderr
src/test/ui/span/E0057.stderr
src/test/ui/span/E0072.stderr
src/test/ui/span/E0204.stderr
src/test/ui/span/E0493.stderr
src/test/ui/span/E0535.stderr
src/test/ui/span/E0536.stderr
src/test/ui/span/E0537.stderr
src/test/ui/span/borrowck-borrow-overloaded-auto-deref-mut.stderr
src/test/ui/span/borrowck-borrow-overloaded-deref-mut.stderr
src/test/ui/span/borrowck-call-is-borrow-issue-12224.stderr
src/test/ui/span/borrowck-call-method-from-mut-aliasable.stderr
src/test/ui/span/borrowck-fn-in-const-b.stderr
src/test/ui/span/borrowck-let-suggestion-suffixes.stderr
src/test/ui/span/borrowck-object-mutability.stderr
src/test/ui/span/borrowck-ref-into-rvalue.stderr
src/test/ui/span/coerce-suggestions.stderr
src/test/ui/span/destructor-restrictions.stderr
src/test/ui/span/dropck-object-cycle.stderr
src/test/ui/span/dropck_arr_cycle_checked.stderr
src/test/ui/span/dropck_direct_cycle_with_drop.stderr
src/test/ui/span/dropck_misc_variants.stderr
src/test/ui/span/dropck_vec_cycle_checked.stderr
src/test/ui/span/impl-wrong-item-for-trait.stderr
src/test/ui/span/issue-11925.stderr
src/test/ui/span/issue-15480.stderr
src/test/ui/span/issue-23338-locals-die-before-temps-of-body.stderr
src/test/ui/span/issue-23729.stderr
src/test/ui/span/issue-23827.stderr
src/test/ui/span/issue-24356.stderr
src/test/ui/span/issue-24690.stderr
src/test/ui/span/issue-24805-dropck-child-has-items-via-parent.stderr
src/test/ui/span/issue-24805-dropck-trait-has-items.stderr
src/test/ui/span/issue-24895-copy-clone-dropck.stderr
src/test/ui/span/issue-25199.stderr
src/test/ui/span/issue-26656.stderr
src/test/ui/span/issue-27522.stderr
src/test/ui/span/issue-29106.stderr
src/test/ui/span/issue-29595.stderr
src/test/ui/span/issue-33884.stderr
src/test/ui/span/issue-34264.stderr
src/test/ui/span/issue-36530.stderr
src/test/ui/span/issue-36537.stderr
src/test/ui/span/issue-37767.stderr
src/test/ui/span/issue-39018.stderr
src/test/ui/span/issue-39698.stderr
src/test/ui/span/issue-40157.stderr
src/test/ui/span/issue-7575.stderr
src/test/ui/span/issue28498-reject-ex1.stderr
src/test/ui/span/issue28498-reject-lifetime-param.stderr
src/test/ui/span/issue28498-reject-passed-to-fn.stderr
src/test/ui/span/issue28498-reject-trait-bound.stderr
src/test/ui/span/lint-unused-unsafe.stderr
src/test/ui/span/loan-extend.stderr
src/test/ui/span/move-closure.stderr
src/test/ui/span/multiline-span-E0072.stderr
src/test/ui/span/multiline-span-simple.stderr
src/test/ui/span/mut-arg-hint.stderr
src/test/ui/span/mut-ptr-cant-outlive-ref.stderr
src/test/ui/span/pub-struct-field.stderr
src/test/ui/span/range-2.stderr
src/test/ui/span/recursive-type-field.stderr
src/test/ui/span/regionck-unboxed-closure-lifetimes.stderr
src/test/ui/span/regions-close-over-borrowed-ref-in-obj.stderr
src/test/ui/span/regions-close-over-type-parameter-2.stderr
src/test/ui/span/regions-escape-loop-via-variable.stderr
src/test/ui/span/regions-escape-loop-via-vec.stderr
src/test/ui/span/regions-infer-borrow-scope-within-loop.stderr
src/test/ui/span/send-is-not-static-ensures-scoping.stderr
src/test/ui/span/send-is-not-static-std-sync-2.stderr
src/test/ui/span/send-is-not-static-std-sync.stderr
src/test/ui/span/slice-borrow.stderr
src/test/ui/span/suggestion-non-ascii.stderr
src/test/ui/span/type-binding.stderr
src/test/ui/span/typo-suggestion.stderr
src/test/ui/span/vec-must-not-hide-type-from-dropck.stderr
src/test/ui/span/vec_refs_data_with_early_death.stderr
src/test/ui/span/wf-method-late-bound-regions.stderr
src/test/ui/static-lifetime.stderr
src/test/ui/suggestions/confuse-field-and-method/issue-18343.stderr
src/test/ui/suggestions/confuse-field-and-method/issue-2392.stderr
src/test/ui/suggestions/confuse-field-and-method/issue-32128.stderr
src/test/ui/suggestions/confuse-field-and-method/issue-33784.stderr
src/test/ui/suggestions/confuse-field-and-method/private-field.stderr
src/test/ui/suggestions/tuple-float-index.stderr
src/test/ui/token/bounds-obj-parens.stderr
src/test/ui/token/issue-10636-2.stderr
src/test/ui/token/issue-41155.stderr
src/test/ui/token/macro-incomplete-parse.stderr
src/test/ui/token/trailing-plus-in-bounds.stderr
src/test/ui/type-check/cannot_infer_local_or_array.stderr
src/test/ui/type-check/cannot_infer_local_or_vec.stderr
src/test/ui/type-check/cannot_infer_local_or_vec_in_tuples.stderr
src/test/ui/type-check/issue-22897.stderr
src/test/ui/type-check/issue-40294.stderr
src/test/ui/type-check/unknown_type_for_closure.stderr
src/tools/compiletest/src/runtest.rs

index f3fa49f4ef9d67603dd1fdb6b04d31a1b77be7a6..456a683dc33c89fcc53c5712c4510eec272028d0 100644 (file)
@@ -49,7 +49,6 @@
     - [link_llvm_intrinsics](language-features/link-llvm-intrinsics.md)
     - [linkage](language-features/linkage.md)
     - [log_syntax](language-features/log-syntax.md)
-    - [loop_break_value](language-features/loop-break-value.md)
     - [macro_reexport](language-features/macro-reexport.md)
     - [macro_vis_matcher](language-features/macro-vis-matcher.md)
     - [main](language-features/main.md)
index 67eee214a4f247e4f012fe59dd0e5574d0b60519..60741a74400d2e50007610ab1ed27b291d56ee0a 100644 (file)
@@ -6,5 +6,25 @@ The tracking issue for this feature is: [#34981]
 
 ------------------------
 
+At present, literals are only accepted as the value of a key-value pair in
+attributes. What's more, only _string_ literals are accepted. This means that
+literals can only appear in forms of `#[attr(name = "value")]` or
+`#[attr = "value"]`.
 
+The `attr_literals` unstable feature allows other types of literals to be used
+in attributes. Here are some examples of attributes that can now be used with
+this feature enabled:
+
++```rust,ignore
++#[attr]
++#[attr(true)]
++#[attr(ident)]
++#[attr(ident, 100, true, "true", ident = 100, ident = "hello", ident(100))]
++#[attr(100)]
++#[attr(enabled = true)]
++#[enabled(true)]
++#[attr("hello")]
++#[repr(C, align = 4)]
++#[repr(C, align(4))]
++```
 
index 44eb2a6dd4fdbda5f4ff346ddf8a36bbf7c85618..fbd213dca569949fc8b9e38c20f3a2de10f2778e 100644 (file)
@@ -5,3 +5,26 @@ The tracking issue for this feature is: [#31436]
 [#31436]: https://github.com/rust-lang/rust/issues/31436
 
 ------------------------
+
+The `catch_expr` feature adds support for a `catch` expression. The `catch`
+expression creates a new scope one can use the `?` operator in.
+
+```rust
+#![feature(catch_expr)]
+
+use std::num::ParseIntError;
+
+let result: Result<i32, ParseIntError> = do catch {
+    Ok("1".parse::<i32>()?
+        + "2".parse::<i32>()?
+        + "3".parse::<i32>()?)
+};
+assert_eq!(result, Ok(6));
+
+let result: Result<i32, ParseIntError> = do catch {
+    Ok("1".parse::<i32>()?
+        + "foo".parse::<i32>()?
+        + "3".parse::<i32>()?)
+};
+assert!(result.is_err());
+```
diff --git a/src/doc/unstable-book/src/language-features/loop-break-value.md b/src/doc/unstable-book/src/language-features/loop-break-value.md
deleted file mode 100644 (file)
index e8fefe3..0000000
+++ /dev/null
@@ -1,83 +0,0 @@
-# `loop_break_value`
-
-The tracking issue for this feature is: [#37339]
-
-[#37339]: https://github.com/rust-lang/rust/issues/37339
-
-Documentation to be appended to section G of the book.
-
-------------------------
-
-### Loops as expressions
-
-Like most things in Rust, loops are expressions, and have a value; normally `()` unless the loop
-never exits.
-A `loop` can instead evaluate to a useful value via *break with value*:
-
-```rust
-#![feature(loop_break_value)]
-
-// Find the first square number over 1000:
-let mut n = 1;
-let square = loop {
-    if n * n > 1000 {
-        break n * n;
-    }
-    n += 1;
-};
-```
-
-The evaluation type may be specified externally:
-
-```rust
-#![feature(loop_break_value)]
-
-// Declare that value returned is unsigned 64-bit:
-let n: u64 = loop {
-    break 1;
-};
-```
-
-It is an error if types do not agree, either between a "break" value and an external requirement,
-or between multiple "break" values:
-
-```no_compile
-#![feature(loop_break_value)]
-
-loop {
-    if true {
-        break 1u32;
-    } else {
-        break 0u8;  // error: types do not agree
-    }
-};
-
-let n: i32 = loop {
-    break 0u32; // error: type does not agree with external requirement
-};
-```
-
-#### Break: label, value
-
-Four forms of `break` are available, where EXPR is some expression which evaluates to a value:
-
-1.  `break;`
-2.  `break 'label;`
-3.  `break EXPR;`
-4.  `break 'label EXPR;`
-
-When no value is given, the value `()` is assumed, thus `break;` is equivalent to `break ();`.
-
-Using a label allows returning a value from an inner loop:
-
-```rust
-#![feature(loop_break_value)]
-
-let result = 'outer: loop {
-    for n in 1..10 {
-        if n > 4 {
-            break 'outer n;
-        }
-    }
-};
-```
index 81f284d0a6a3e0bb52573dd92ba162ea2ebb2d3a..9eea3fccbbc17e39ad591fb72f94893f0027d5f5 100644 (file)
@@ -6,5 +6,42 @@ The tracking issue for this feature is: [#29628]
 
 ------------------------
 
+The `on_unimplemented` feature provides the `#[rustc_on_unimplemented]`
+attribute, which allows trait definitions to add specialized notes to error
+messages when an implementation was expected but not found.
 
+For example:
+
+```rust,compile_fail
+#![feature(on_unimplemented)]
+
+#[rustc_on_unimplemented="a collection of type `{Self}` cannot be built from an \
+                          iterator over elements of type `{A}`"]
+trait MyIterator<A> {
+    fn next(&mut self) -> A;
+}
+
+fn iterate_chars<I: MyIterator<char>>(i: I) {
+    // ...
+}
+
+fn main() {
+    iterate_chars(&[1, 2, 3][..]);
+}
+```
+
+When the user compiles this, they will see the following;
+
+```txt
+error[E0277]: the trait bound `&[{integer}]: MyIterator<char>` is not satisfied
+  --> <anon>:14:5
+   |
+14 |     iterate_chars(&[1, 2, 3][..]);
+   |     ^^^^^^^^^^^^^ the trait `MyIterator<char>` is not implemented for `&[{integer}]`
+   |
+   = note: a collection of type `&[{integer}]` cannot be built from an iterator over elements of type `char`
+   = note: required by `iterate_chars`
+
+error: aborting due to previous error
+```
 
index 8f3209d015b159ad955f6a31ee7eac0109bd45b6..bc8566e8cbeb375b6b066b0ddd368eb7ee883dfb 100644 (file)
@@ -106,16 +106,10 @@ fn end(&self) -> Bound<&T> {
 #[unstable(feature = "inclusive_range", reason = "recently added, follows RFC", issue = "28237")]
 impl<T> RangeArgument<T> for RangeInclusive<T> {
     fn start(&self) -> Bound<&T> {
-        match *self {
-            RangeInclusive::Empty{ ref at }            => Included(at),
-            RangeInclusive::NonEmpty { ref start, .. } => Included(start),
-        }
+        Included(&self.start)
     }
     fn end(&self) -> Bound<&T> {
-        match *self {
-            RangeInclusive::Empty{ ref at }            => Excluded(at),
-            RangeInclusive::NonEmpty { ref end, .. }   => Included(end),
-        }
+        Included(&self.end)
     }
 }
 
index 3efda1faa3b56405637a31019688775ffe8254fe..5696f5fe6a7ba80bdc6d15383dbd785db3547476 100644 (file)
@@ -1410,6 +1410,9 @@ pub fn to_vec(&self) -> Vec<T>
 
     /// Converts `self` into a vector without clones or allocation.
     ///
+    /// The resulting vector can be converted back into a box via
+    /// `Vec<T>`'s `into_boxed_slice` method.
+    ///
     /// # Examples
     ///
     /// ```
index bd831d638c0c4cc24e8573501345ab809c489477..02d38ccea44eadcb2b95caee0450fbecd7d8d279 100644 (file)
@@ -403,61 +403,35 @@ impl<A: Step + Clone> Iterator for StepBy<A, ops::RangeInclusive<A>> {
 
     #[inline]
     fn next(&mut self) -> Option<A> {
-        use ops::RangeInclusive::*;
-
-        // this function has a sort of odd structure due to borrowck issues
-        // we may need to replace self.range, so borrows of start and end need to end early
-
-        let (finishing, n) = match self.range {
-            Empty { .. } => return None, // empty iterators yield no values
-
-            NonEmpty { ref mut start, ref mut end } => {
-                let rev = self.step_by.is_negative();
-
-                // march start towards (maybe past!) end and yield the old value
-                if (rev && start >= end) ||
-                   (!rev && start <= end)
-                {
-                    match start.step(&self.step_by) {
-                        Some(mut n) => {
-                            mem::swap(start, &mut n);
-                            (None, Some(n)) // yield old value, remain non-empty
-                        },
-                        None => {
-                            let mut n = end.clone();
-                            mem::swap(start, &mut n);
-                            (None, Some(n)) // yield old value, remain non-empty
-                        }
-                    }
-                } else {
-                    // found range in inconsistent state (start at or past end), so become empty
-                    (Some(end.replace_zero()), None)
-                }
-            }
-        };
+        let rev = self.step_by.is_negative();
 
-        // turn into an empty iterator if we've reached the end
-        if let Some(end) = finishing {
-            self.range = Empty { at: end };
+        if (rev && self.range.start >= self.range.end) ||
+           (!rev && self.range.start <= self.range.end)
+        {
+            match self.range.start.step(&self.step_by) {
+                Some(n) => {
+                    Some(mem::replace(&mut self.range.start, n))
+                },
+                None => {
+                    let last = self.range.start.replace_one();
+                    self.range.end.replace_zero();
+                    self.step_by.replace_one();
+                    Some(last)
+                },
+            }
+        }
+        else {
+            None
         }
-
-        n
     }
 
     #[inline]
     fn size_hint(&self) -> (usize, Option<usize>) {
-        use ops::RangeInclusive::*;
-
-        match self.range {
-            Empty { .. } => (0, Some(0)),
-
-            NonEmpty { ref start, ref end } =>
-                match Step::steps_between(start,
-                                          end,
-                                          &self.step_by) {
-                    Some(hint) => (hint.saturating_add(1), hint.checked_add(1)),
-                    None       => (0, None)
-                }
+        match Step::steps_between(&self.range.start,
+                                  &self.range.end,
+                                  &self.step_by) {
+            Some(hint) => (hint.saturating_add(1), hint.checked_add(1)),
+            None       => (0, None)
         }
     }
 }
@@ -583,56 +557,31 @@ impl<A: Step> Iterator for ops::RangeInclusive<A> where
 
     #[inline]
     fn next(&mut self) -> Option<A> {
-        use ops::RangeInclusive::*;
-
-        // this function has a sort of odd structure due to borrowck issues
-        // we may need to replace self, so borrows of self.start and self.end need to end early
-
-        let (finishing, n) = match *self {
-            Empty { .. } => (None, None), // empty iterators yield no values
-
-            NonEmpty { ref mut start, ref mut end } => {
-                if start == end {
-                    (Some(end.replace_one()), Some(start.replace_one()))
-                } else if start < end {
-                    let mut n = start.add_one();
-                    mem::swap(&mut n, start);
-
-                    // if the iterator is done iterating, it will change from
-                    // NonEmpty to Empty to avoid unnecessary drops or clones,
-                    // we'll reuse either start or end (they are equal now, so
-                    // it doesn't matter which) to pull out end, we need to swap
-                    // something back in
-
-                    (if n == *end { Some(end.replace_one()) } else { None },
-                    // ^ are we done yet?
-                    Some(n)) // < the value to output
-                } else {
-                    (Some(start.replace_one()), None)
-                }
-            }
-        };
-
-        // turn into an empty iterator if this is the last value
-        if let Some(end) = finishing {
-            *self = Empty { at: end };
+        use cmp::Ordering::*;
+
+        match self.start.partial_cmp(&self.end) {
+            Some(Less) => {
+                let n = self.start.add_one();
+                Some(mem::replace(&mut self.start, n))
+            },
+            Some(Equal) => {
+                let last = self.start.replace_one();
+                self.end.replace_zero();
+                Some(last)
+            },
+            _ => None,
         }
-
-        n
     }
 
     #[inline]
     fn size_hint(&self) -> (usize, Option<usize>) {
-        use ops::RangeInclusive::*;
-
-        match *self {
-            Empty { .. } => (0, Some(0)),
+        if !(self.start <= self.end) {
+            return (0, Some(0));
+        }
 
-            NonEmpty { ref start, ref end } =>
-                match Step::steps_between_by_one(start, end) {
-                    Some(hint) => (hint.saturating_add(1), hint.checked_add(1)),
-                    None => (0, None),
-                }
+        match Step::steps_between_by_one(&self.start, &self.end) {
+            Some(hint) => (hint.saturating_add(1), hint.checked_add(1)),
+            None => (0, None),
         }
     }
 }
@@ -644,33 +593,20 @@ impl<A: Step> DoubleEndedIterator for ops::RangeInclusive<A> where
 {
     #[inline]
     fn next_back(&mut self) -> Option<A> {
-        use ops::RangeInclusive::*;
-
-        // see Iterator::next for comments
-
-        let (finishing, n) = match *self {
-            Empty { .. } => return None,
-
-            NonEmpty { ref mut start, ref mut end } => {
-                if start == end {
-                    (Some(start.replace_one()), Some(end.replace_one()))
-                } else if start < end {
-                    let mut n = end.sub_one();
-                    mem::swap(&mut n, end);
-
-                    (if n == *start { Some(start.replace_one()) } else { None },
-                     Some(n))
-                } else {
-                    (Some(end.replace_one()), None)
-                }
-            }
-        };
-
-        if let Some(start) = finishing {
-            *self = Empty { at: start };
+        use cmp::Ordering::*;
+
+        match self.start.partial_cmp(&self.end) {
+            Some(Less) => {
+                let n = self.end.sub_one();
+                Some(mem::replace(&mut self.end, n))
+            },
+            Some(Equal) => {
+                let last = self.end.replace_zero();
+                self.start.replace_one();
+                Some(last)
+            },
+            _ => None,
         }
-
-        n
     }
 }
 
index 4fb1f1757bbf70f142d0dfe87bcdb5588c73a5b6..c76cff4dc34d10bf506188bdd29e79de45e5c9a7 100644 (file)
@@ -2315,7 +2315,7 @@ pub fn contains(&self, item: Idx) -> bool {
 /// ```
 /// #![feature(inclusive_range,inclusive_range_syntax)]
 /// fn main() {
-///     assert_eq!((3...5), std::ops::RangeInclusive::NonEmpty{ start: 3, end: 5 });
+///     assert_eq!((3...5), std::ops::RangeInclusive{ start: 3, end: 5 });
 ///     assert_eq!(3+4+5, (3...5).sum());
 ///
 ///     let arr = [0, 1, 2, 3];
@@ -2325,45 +2325,23 @@ pub fn contains(&self, item: Idx) -> bool {
 /// ```
 #[derive(Clone, PartialEq, Eq, Hash)]  // not Copy -- see #27186
 #[unstable(feature = "inclusive_range", reason = "recently added, follows RFC", issue = "28237")]
-pub enum RangeInclusive<Idx> {
-    /// Empty range (iteration has finished)
+pub struct RangeInclusive<Idx> {
+    /// The lower bound of the range (inclusive).
     #[unstable(feature = "inclusive_range",
                reason = "recently added, follows RFC",
                issue = "28237")]
-    Empty {
-        /// The point at which iteration finished
-        #[unstable(feature = "inclusive_range",
-                   reason = "recently added, follows RFC",
-                   issue = "28237")]
-        at: Idx
-    },
-    /// Non-empty range (iteration will yield value(s))
+    pub start: Idx,
+    /// The upper bound of the range (inclusive).
     #[unstable(feature = "inclusive_range",
                reason = "recently added, follows RFC",
                issue = "28237")]
-    NonEmpty {
-        /// The lower bound of the range (inclusive).
-        #[unstable(feature = "inclusive_range",
-                   reason = "recently added, follows RFC",
-                   issue = "28237")]
-        start: Idx,
-        /// The upper bound of the range (inclusive).
-        #[unstable(feature = "inclusive_range",
-                   reason = "recently added, follows RFC",
-                   issue = "28237")]
-        end: Idx,
-    },
+    pub end: Idx,
 }
 
 #[unstable(feature = "inclusive_range", reason = "recently added, follows RFC", issue = "28237")]
 impl<Idx: fmt::Debug> fmt::Debug for RangeInclusive<Idx> {
     fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
-        use self::RangeInclusive::*;
-
-        match *self {
-            Empty { ref at } => write!(fmt, "[empty range @ {:?}]", at),
-            NonEmpty { ref start, ref end } => write!(fmt, "{:?}...{:?}", start, end),
-        }
+        write!(fmt, "{:?}...{:?}", self.start, self.end)
     }
 }
 
@@ -2385,9 +2363,7 @@ impl<Idx: PartialOrd<Idx>> RangeInclusive<Idx> {
     /// }
     /// ```
     pub fn contains(&self, item: Idx) -> bool {
-        if let &RangeInclusive::NonEmpty{ref start, ref end} = self {
-            (*start <= item) && (item <= *end)
-        } else { false }
+        self.start <= item && item <= self.end
     }
 }
 
index 515f49d6f0bddc35aa41352a8675e3c8aa819572..e825acad4713e2a6973b242a0e5f11be102d266f 100644 (file)
@@ -174,7 +174,7 @@ impl<T> Option<T> {
     // Querying the contained values
     /////////////////////////////////////////////////////////////////////////
 
-    /// Returns `true` if the option is a `Some` value.
+    /// Returns `true` if the option is a [`Some`] value.
     ///
     /// # Examples
     ///
@@ -185,6 +185,8 @@ impl<T> Option<T> {
     /// let x: Option<u32> = None;
     /// assert_eq!(x.is_some(), false);
     /// ```
+    ///
+    /// [`Some`]: #variant.Some
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn is_some(&self) -> bool {
@@ -194,7 +196,7 @@ pub fn is_some(&self) -> bool {
         }
     }
 
-    /// Returns `true` if the option is a `None` value.
+    /// Returns `true` if the option is a [`None`] value.
     ///
     /// # Examples
     ///
@@ -205,6 +207,8 @@ pub fn is_some(&self) -> bool {
     /// let x: Option<u32> = None;
     /// assert_eq!(x.is_none(), true);
     /// ```
+    ///
+    /// [`None`]: #variant.None
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn is_none(&self) -> bool {
@@ -269,13 +273,14 @@ pub fn as_mut(&mut self) -> Option<&mut T> {
     // Getting to contained values
     /////////////////////////////////////////////////////////////////////////
 
-    /// Unwraps an option, yielding the content of a `Some`.
+    /// Unwraps an option, yielding the content of a [`Some`].
     ///
     /// # Panics
     ///
     /// Panics if the value is a [`None`] with a custom panic message provided by
     /// `msg`.
     ///
+    /// [`Some`]: #variant.Some
     /// [`None`]: #variant.None
     ///
     /// # Examples
@@ -298,16 +303,17 @@ pub fn expect(self, msg: &str) -> T {
         }
     }
 
-    /// Moves the value `v` out of the `Option<T>` if it is `Some(v)`.
+    /// Moves the value `v` out of the `Option<T>` if it is [`Some(v)`].
     ///
     /// In general, because this function may panic, its use is discouraged.
-    /// Instead, prefer to use pattern matching and handle the `None`
+    /// Instead, prefer to use pattern matching and handle the [`None`]
     /// case explicitly.
     ///
     /// # Panics
     ///
     /// Panics if the self value equals [`None`].
     ///
+    /// [`Some(v)`]: #variant.Some
     /// [`None`]: #variant.None
     ///
     /// # Examples
@@ -395,7 +401,9 @@ pub fn map<U, F: FnOnce(T) -> U>(self, f: F) -> Option<U> {
     }
 
     /// Applies a function to the contained value (if any),
-    /// or returns a `default` (if not).
+    /// or returns a [`default`][] (if not).
+    ///
+    /// [`default`]: ../default/trait.Default.html#tymethod.default
     ///
     /// # Examples
     ///
@@ -416,7 +424,9 @@ pub fn map_or<U, F: FnOnce(T) -> U>(self, default: U, f: F) -> U {
     }
 
     /// Applies a function to the contained value (if any),
-    /// or computes a `default` (if not).
+    /// or computes a [`default`][] (if not).
+    ///
+    /// [`default`]: ../default/trait.Default.html#tymethod.default
     ///
     /// # Examples
     ///
@@ -438,12 +448,14 @@ pub fn map_or_else<U, D: FnOnce() -> U, F: FnOnce(T) -> U>(self, default: D, f:
         }
     }
 
-    /// Transforms the `Option<T>` into a [`Result<T, E>`], mapping `Some(v)` to
-    /// [`Ok(v)`] and `None` to [`Err(err)`][Err].
+    /// Transforms the `Option<T>` into a [`Result<T, E>`], mapping [`Some(v)`] to
+    /// [`Ok(v)`] and [`None`] to [`Err(err)`].
     ///
     /// [`Result<T, E>`]: ../../std/result/enum.Result.html
     /// [`Ok(v)`]: ../../std/result/enum.Result.html#variant.Ok
-    /// [Err]: ../../std/result/enum.Result.html#variant.Err
+    /// [`Err(err)`]: ../../std/result/enum.Result.html#variant.Err
+    /// [`None`]: #variant.None
+    /// [`Some(v)`]: #variant.Some
     ///
     /// # Examples
     ///
@@ -463,12 +475,14 @@ pub fn ok_or<E>(self, err: E) -> Result<T, E> {
         }
     }
 
-    /// Transforms the `Option<T>` into a [`Result<T, E>`], mapping `Some(v)` to
-    /// [`Ok(v)`] and `None` to [`Err(err())`][Err].
+    /// Transforms the `Option<T>` into a [`Result<T, E>`], mapping [`Some(v)`] to
+    /// [`Ok(v)`] and [`None`] to [`Err(err())`].
     ///
     /// [`Result<T, E>`]: ../../std/result/enum.Result.html
     /// [`Ok(v)`]: ../../std/result/enum.Result.html#variant.Ok
-    /// [Err]: ../../std/result/enum.Result.html#variant.Err
+    /// [`Err(err())`]: ../../std/result/enum.Result.html#variant.Err
+    /// [`None`]: #variant.None
+    /// [`Some(v)`]: #variant.Some
     ///
     /// # Examples
     ///
@@ -534,7 +548,9 @@ pub fn iter_mut(&mut self) -> IterMut<T> {
     // Boolean operations on the values, eager and lazy
     /////////////////////////////////////////////////////////////////////////
 
-    /// Returns `None` if the option is `None`, otherwise returns `optb`.
+    /// Returns [`None`] if the option is [`None`], otherwise returns `optb`.
+    ///
+    /// [`None`]: #variant.None
     ///
     /// # Examples
     ///
@@ -564,11 +580,13 @@ pub fn and<U>(self, optb: Option<U>) -> Option<U> {
         }
     }
 
-    /// Returns `None` if the option is `None`, otherwise calls `f` with the
+    /// Returns [`None`] if the option is [`None`], otherwise calls `f` with the
     /// wrapped value and returns the result.
     ///
     /// Some languages call this operation flatmap.
     ///
+    /// [`None`]: #variant.None
+    ///
     /// # Examples
     ///
     /// ```
@@ -645,9 +663,11 @@ pub fn or_else<F: FnOnce() -> Option<T>>(self, f: F) -> Option<T> {
     // Entry-like operations to insert if None and return a reference
     /////////////////////////////////////////////////////////////////////////
 
-    /// Inserts `v` into the option if it is `None`, then
+    /// Inserts `v` into the option if it is [`None`], then
     /// returns a mutable reference to the contained value.
     ///
+    /// [`None`]: #variant.None
+    ///
     /// # Examples
     ///
     /// ```
@@ -678,9 +698,11 @@ pub fn get_or_insert(&mut self, v: T) -> &mut T {
         }
     }
 
-    /// Inserts a value computed from `f` into the option if it is `None`, then
+    /// Inserts a value computed from `f` into the option if it is [`None`], then
     /// returns a mutable reference to the contained value.
     ///
+    /// [`None`]: #variant.None
+    ///
     /// # Examples
     ///
     /// ```
@@ -715,7 +737,9 @@ pub fn get_or_insert_with<F: FnOnce() -> T>(&mut self, f: F) -> &mut T {
     // Misc
     /////////////////////////////////////////////////////////////////////////
 
-    /// Takes the value out of the option, leaving a `None` in its place.
+    /// Takes the value out of the option, leaving a [`None`] in its place.
+    ///
+    /// [`None`]: #variant.None
     ///
     /// # Examples
     ///
@@ -757,16 +781,16 @@ pub fn cloned(self) -> Option<T> {
 impl<T: Default> Option<T> {
     /// Returns the contained value or a default
     ///
-    /// Consumes the `self` argument then, if `Some`, returns the contained
-    /// value, otherwise if `None`, returns the default value for that
+    /// Consumes the `self` argument then, if [`Some`], returns the contained
+    /// value, otherwise if [`None`], returns the default value for that
     /// type.
     ///
     /// # Examples
     ///
     /// Convert a string to an integer, turning poorly-formed strings
-    /// into 0 (the default value for integers). `parse` converts
-    /// a string to any other type that implements `FromStr`, returning
-    /// `None` on error.
+    /// into 0 (the default value for integers). [`parse`] converts
+    /// a string to any other type that implements [`FromStr`], returning
+    /// [`None`] on error.
     ///
     /// ```
     /// let good_year_from_input = "1909";
@@ -777,6 +801,11 @@ impl<T: Default> Option<T> {
     /// assert_eq!(1909, good_year);
     /// assert_eq!(0, bad_year);
     /// ```
+    ///
+    /// [`Some`]: #variant.Some
+    /// [`None`]: #variant.None
+    /// [`parse`]: ../../std/primitive.str.html#method.parse
+    /// [`FromStr`]: ../../std/str/trait.FromStr.html
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn unwrap_or_default(self) -> T {
@@ -801,7 +830,9 @@ fn expect_failed(msg: &str) -> ! {
 
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<T> Default for Option<T> {
-    /// Returns None.
+    /// Returns [`None`].
+    ///
+    /// [`None`]: #variant.None
     #[inline]
     fn default() -> Option<T> { None }
 }
@@ -1020,8 +1051,8 @@ unsafe impl<A> TrustedLen for IntoIter<A> {}
 
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<A, V: FromIterator<A>> FromIterator<Option<A>> for Option<V> {
-    /// Takes each element in the `Iterator`: if it is `None`, no further
-    /// elements are taken, and the `None` is returned. Should no `None` occur, a
+    /// Takes each element in the [`Iterator`]: if it is [`None`], no further
+    /// elements are taken, and the [`None`] is returned. Should no [`None`] occur, a
     /// container with the values of each `Option` is returned.
     ///
     /// Here is an example which increments every integer in a vector,
@@ -1037,6 +1068,9 @@ impl<A, V: FromIterator<A>> FromIterator<Option<A>> for Option<V> {
     /// ).collect();
     /// assert!(res == Some(vec![2, 3]));
     /// ```
+    ///
+    /// [`Iterator`]: ../iter/trait.Iterator.html
+    /// [`None`]: enum.Option.html#variant.None
     #[inline]
     fn from_iter<I: IntoIterator<Item=Option<A>>>(iter: I) -> Option<V> {
         // FIXME(#11084): This could be replaced with Iterator::scan when this
index 24ebfeb62e2eec23eec5fe573fa01ed819ace068..cef3682fd94d74859a69f0207b2796555520154a 100644 (file)
@@ -981,95 +981,82 @@ impl<T> SliceIndex<[T]> for ops::RangeInclusive<usize> {
 
     #[inline]
     fn get(self, slice: &[T]) -> Option<&[T]> {
-        match self {
-            ops::RangeInclusive::Empty { .. } => Some(&[]),
-            ops::RangeInclusive::NonEmpty { end, .. } if end == usize::max_value() => None,
-            ops::RangeInclusive::NonEmpty { start, end } => (start..end + 1).get(slice),
-        }
+        if self.end == usize::max_value() { None }
+        else { (self.start..self.end + 1).get(slice) }
     }
 
     #[inline]
     fn get_mut(self, slice: &mut [T]) -> Option<&mut [T]> {
-        match self {
-            ops::RangeInclusive::Empty { .. } => Some(&mut []),
-            ops::RangeInclusive::NonEmpty { end, .. } if end == usize::max_value() => None,
-            ops::RangeInclusive::NonEmpty { start, end } => (start..end + 1).get_mut(slice),
-        }
+        if self.end == usize::max_value() { None }
+        else { (self.start..self.end + 1).get_mut(slice) }
     }
 
     #[inline]
     unsafe fn get_unchecked(self, slice: &[T]) -> &[T] {
-        match self {
-            ops::RangeInclusive::Empty { .. } => &[],
-            ops::RangeInclusive::NonEmpty { start, end } => (start..end + 1).get_unchecked(slice),
-        }
+        (self.start..self.end + 1).get_unchecked(slice)
     }
 
     #[inline]
     unsafe fn get_unchecked_mut(self, slice: &mut [T]) -> &mut [T] {
-        match self {
-            ops::RangeInclusive::Empty { .. } => &mut [],
-            ops::RangeInclusive::NonEmpty { start, end } => {
-                (start..end + 1).get_unchecked_mut(slice)
-            }
-        }
+        (self.start..self.end + 1).get_unchecked_mut(slice)
     }
 
     #[inline]
     fn index(self, slice: &[T]) -> &[T] {
-        match self {
-            ops::RangeInclusive::Empty { .. } => &[],
-            ops::RangeInclusive::NonEmpty { end, .. } if end == usize::max_value() => {
-                panic!("attempted to index slice up to maximum usize");
-            },
-            ops::RangeInclusive::NonEmpty { start, end } => (start..end + 1).index(slice),
-        }
+        assert!(self.end != usize::max_value(),
+            "attempted to index slice up to maximum usize");
+        (self.start..self.end + 1).index(slice)
     }
 
     #[inline]
     fn index_mut(self, slice: &mut [T]) -> &mut [T] {
-        match self {
-            ops::RangeInclusive::Empty { .. } => &mut [],
-            ops::RangeInclusive::NonEmpty { end, .. } if end == usize::max_value() => {
-                panic!("attempted to index slice up to maximum usize");
-            },
-            ops::RangeInclusive::NonEmpty { start, end } => (start..end + 1).index_mut(slice),
-        }
+        assert!(self.end != usize::max_value(),
+            "attempted to index slice up to maximum usize");
+        (self.start..self.end + 1).index_mut(slice)
     }
 }
 
+#[cfg(stage0)] // The bootstrap compiler has a different `...` desugar
+fn inclusive(start: usize, end: usize) -> ops::RangeInclusive<usize> {
+    ops::RangeInclusive { start, end }
+}
+#[cfg(not(stage0))]
+fn inclusive(start: usize, end: usize) -> ops::RangeInclusive<usize> {
+    start...end
+}
+
 #[unstable(feature = "inclusive_range", reason = "recently added, follows RFC", issue = "28237")]
 impl<T> SliceIndex<[T]> for ops::RangeToInclusive<usize> {
     type Output = [T];
 
     #[inline]
     fn get(self, slice: &[T]) -> Option<&[T]> {
-        (0...self.end).get(slice)
+        inclusive(0, self.end).get(slice)
     }
 
     #[inline]
     fn get_mut(self, slice: &mut [T]) -> Option<&mut [T]> {
-        (0...self.end).get_mut(slice)
+        inclusive(0, self.end).get_mut(slice)
     }
 
     #[inline]
     unsafe fn get_unchecked(self, slice: &[T]) -> &[T] {
-        (0...self.end).get_unchecked(slice)
+        inclusive(0, self.end).get_unchecked(slice)
     }
 
     #[inline]
     unsafe fn get_unchecked_mut(self, slice: &mut [T]) -> &mut [T] {
-        (0...self.end).get_unchecked_mut(slice)
+        inclusive(0, self.end).get_unchecked_mut(slice)
     }
 
     #[inline]
     fn index(self, slice: &[T]) -> &[T] {
-        (0...self.end).index(slice)
+        inclusive(0, self.end).index(slice)
     }
 
     #[inline]
     fn index_mut(self, slice: &mut [T]) -> &mut [T] {
-        (0...self.end).index_mut(slice)
+        inclusive(0, self.end).index_mut(slice)
     }
 }
 
index 7fb941c091fbc4fab90ed623b90ff54db4bb3142..547a4899c7118c85e9bf6ceffaaab190401ac988 100644 (file)
@@ -1724,15 +1724,12 @@ impl ops::Index<ops::RangeInclusive<usize>> for str {
 
         #[inline]
         fn index(&self, index: ops::RangeInclusive<usize>) -> &str {
-            match index {
-                ops::RangeInclusive::Empty { .. } => "",
-                ops::RangeInclusive::NonEmpty { end, .. } if end == usize::max_value() =>
-                    panic!("attempted to index slice up to maximum usize"),
-                ops::RangeInclusive::NonEmpty { start, end } =>
-                    self.index(start .. end+1)
-            }
+            assert!(index.end != usize::max_value(),
+                "attempted to index str up to maximum usize");
+            self.index(index.start .. index.end+1)
         }
     }
+
     #[unstable(feature = "inclusive_range",
                reason = "recently added, follows RFC",
                issue = "28237")]
@@ -1741,7 +1738,9 @@ impl ops::Index<ops::RangeToInclusive<usize>> for str {
 
         #[inline]
         fn index(&self, index: ops::RangeToInclusive<usize>) -> &str {
-            self.index(0...index.end)
+            assert!(index.end != usize::max_value(),
+                "attempted to index str up to maximum usize");
+            self.index(.. index.end+1)
         }
     }
 
@@ -1751,13 +1750,9 @@ fn index(&self, index: ops::RangeToInclusive<usize>) -> &str {
     impl ops::IndexMut<ops::RangeInclusive<usize>> for str {
         #[inline]
         fn index_mut(&mut self, index: ops::RangeInclusive<usize>) -> &mut str {
-            match index {
-                ops::RangeInclusive::Empty { .. } => &mut self[0..0], // `&mut ""` doesn't work
-                ops::RangeInclusive::NonEmpty { end, .. } if end == usize::max_value() =>
-                    panic!("attempted to index str up to maximum usize"),
-                    ops::RangeInclusive::NonEmpty { start, end } =>
-                        self.index_mut(start .. end+1)
-            }
+            assert!(index.end != usize::max_value(),
+                "attempted to index str up to maximum usize");
+            self.index_mut(index.start .. index.end+1)
         }
     }
     #[unstable(feature = "inclusive_range",
@@ -1766,7 +1761,9 @@ fn index_mut(&mut self, index: ops::RangeInclusive<usize>) -> &mut str {
     impl ops::IndexMut<ops::RangeToInclusive<usize>> for str {
         #[inline]
         fn index_mut(&mut self, index: ops::RangeToInclusive<usize>) -> &mut str {
-            self.index_mut(0...index.end)
+            assert!(index.end != usize::max_value(),
+                "attempted to index str up to maximum usize");
+            self.index_mut(.. index.end+1)
         }
     }
 
@@ -1948,45 +1945,27 @@ impl SliceIndex<str> for ops::RangeInclusive<usize> {
         type Output = str;
         #[inline]
         fn get(self, slice: &str) -> Option<&Self::Output> {
-            match self {
-                ops::RangeInclusive::Empty { .. } => 0..0,
-                ops::RangeInclusive::NonEmpty { start, end } => start..end+1,
-            }.get(slice)
+            (self.start..self.end+1).get(slice)
         }
         #[inline]
         fn get_mut(self, slice: &mut str) -> Option<&mut Self::Output> {
-            match self {
-                ops::RangeInclusive::Empty { .. } => 0..0,
-                ops::RangeInclusive::NonEmpty { start, end } => start..end+1,
-            }.get_mut(slice)
+            (self.start..self.end+1).get_mut(slice)
         }
         #[inline]
         unsafe fn get_unchecked(self, slice: &str) -> &Self::Output {
-            match self {
-                ops::RangeInclusive::Empty { .. } => 0..0,
-                ops::RangeInclusive::NonEmpty { start, end } => start..end+1,
-            }.get_unchecked(slice)
+            (self.start..self.end+1).get_unchecked(slice)
         }
         #[inline]
         unsafe fn get_unchecked_mut(self, slice: &mut str) -> &mut Self::Output {
-            match self {
-                ops::RangeInclusive::Empty { .. } => 0..0,
-                ops::RangeInclusive::NonEmpty { start, end } => start..end+1,
-            }.get_unchecked_mut(slice)
+            (self.start..self.end+1).get_unchecked_mut(slice)
         }
         #[inline]
         fn index(self, slice: &str) -> &Self::Output {
-            match self {
-                ops::RangeInclusive::Empty { .. } => 0..0,
-                ops::RangeInclusive::NonEmpty { start, end } => start..end+1,
-            }.index(slice)
+            (self.start..self.end+1).index(slice)
         }
         #[inline]
         fn index_mut(self, slice: &mut str) -> &mut Self::Output {
-            match self {
-                ops::RangeInclusive::Empty { .. } => 0..0,
-                ops::RangeInclusive::NonEmpty { start, end } => start..end+1,
-            }.index_mut(slice)
+            (self.start..self.end+1).index_mut(slice)
         }
     }
 
index c52155ead4f0b2774fe73db9cb4f73048a475dc4..8c4cd1d0c84583b20e961f9151c0e363686dbcac 100644 (file)
@@ -22,6 +22,7 @@
 #![feature(fmt_internals)]
 #![feature(iterator_step_by)]
 #![feature(i128_type)]
+#![feature(inclusive_range)]
 #![feature(iter_rfind)]
 #![feature(libc)]
 #![feature(nonzero)]
index 1c6c13b0d02e8b6e5417bbfbc900d4ca78f21f67..b81b3878c9d6e1d4c82a117f46107a17cf170b0b 100644 (file)
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use core::ops::{Range, RangeFull, RangeFrom, RangeTo};
+use core::ops::{Range, RangeFull, RangeFrom, RangeTo, RangeInclusive};
 
 // Test the Range structs without the syntactic sugar.
 
@@ -47,3 +47,24 @@ fn test_full_range() {
     // Not much to test.
     let _ = RangeFull;
 }
+
+#[test]
+fn test_range_inclusive() {
+    let mut r = RangeInclusive { start: 1i8, end: 2 };
+    assert_eq!(r.next(), Some(1));
+    assert_eq!(r.next(), Some(2));
+    assert_eq!(r.next(), None);
+
+    r = RangeInclusive { start: 127i8, end: 127 };
+    assert_eq!(r.next(), Some(127));
+    assert_eq!(r.next(), None);
+
+    r = RangeInclusive { start: -128i8, end: -128 };
+    assert_eq!(r.next_back(), Some(-128));
+    assert_eq!(r.next_back(), None);
+
+    // degenerate
+    r = RangeInclusive { start: 1, end: -1 };
+    assert_eq!(r.size_hint(), (0, Some(0)));
+    assert_eq!(r.next(), None);
+}
\ No newline at end of file
index 15c4469b74694c98d3108c0002a9840329f6b53f..291d0d7c937ed6a3a15621ee013ab8952161d449 100644 (file)
@@ -108,6 +108,10 @@ pub enum DepNode<D: Clone + Debug> {
     SymbolName(D),
     SpecializationGraph(D),
     ObjectSafety(D),
+    IsCopy(D),
+    IsSized(D),
+    IsFreeze(D),
+    NeedsDrop(D),
 
     // The set of impls for a given trait. Ultimately, it would be
     // nice to get more fine-grained here (e.g., to include a
@@ -159,6 +163,7 @@ pub enum DepNode<D: Clone + Debug> {
     // not a hotspot.
     ProjectionCache { def_ids: Vec<D> },
 
+    ParamEnv(D),
     DescribeDef(D),
     DefSpan(D),
     Stability(D),
@@ -233,6 +238,10 @@ pub fn map_def<E, OP>(&self, mut op: OP) -> Option<DepNode<E>>
             // they are always absolute.
             WorkProduct(ref id) => Some(WorkProduct(id.clone())),
 
+            IsCopy(ref d) => op(d).map(IsCopy),
+            IsSized(ref d) => op(d).map(IsSized),
+            IsFreeze(ref d) => op(d).map(IsFreeze),
+            NeedsDrop(ref d) => op(d).map(NeedsDrop),
             Hir(ref d) => op(d).map(Hir),
             HirBody(ref d) => op(d).map(HirBody),
             MetaData(ref d) => op(d).map(MetaData),
@@ -284,6 +293,7 @@ pub fn map_def<E, OP>(&self, mut op: OP) -> Option<DepNode<E>>
                 let def_ids: Option<Vec<E>> = def_ids.iter().map(op).collect();
                 def_ids.map(|d| ProjectionCache { def_ids: d })
             }
+            ParamEnv(ref d) => op(d).map(ParamEnv),
             DescribeDef(ref d) => op(d).map(DescribeDef),
             DefSpan(ref d) => op(d).map(DefSpan),
             Stability(ref d) => op(d).map(Stability),
index 8f4dce5a78303d51d2c5850fd4fceb6af612df39..d359c69d3a092842e8868c63b03d9c3fa43b9d9d 100644 (file)
@@ -1934,13 +1934,13 @@ fn lower_expr(&mut self, e: &Expr) -> hir::Expr {
             ExprKind::Range(ref e1, ref e2, lims) => {
                 use syntax::ast::RangeLimits::*;
 
-                let (path, variant) = match (e1, e2, lims) {
-                    (&None, &None, HalfOpen) => ("RangeFull", None),
-                    (&Some(..), &None, HalfOpen) => ("RangeFrom", None),
-                    (&None, &Some(..), HalfOpen) => ("RangeTo", None),
-                    (&Some(..), &Some(..), HalfOpen) => ("Range", None),
-                    (&None, &Some(..), Closed) => ("RangeToInclusive", None),
-                    (&Some(..), &Some(..), Closed) => ("RangeInclusive", Some("NonEmpty")),
+                let path = match (e1, e2, lims) {
+                    (&None, &None, HalfOpen) => "RangeFull",
+                    (&Some(..), &None, HalfOpen) => "RangeFrom",
+                    (&None, &Some(..), HalfOpen) => "RangeTo",
+                    (&Some(..), &Some(..), HalfOpen) => "Range",
+                    (&None, &Some(..), Closed) => "RangeToInclusive",
+                    (&Some(..), &Some(..), Closed) => "RangeInclusive",
                     (_, &None, Closed) =>
                         panic!(self.diagnostic().span_fatal(
                             e.span, "inclusive range with no end")),
@@ -1957,7 +1957,7 @@ fn lower_expr(&mut self, e: &Expr) -> hir::Expr {
                 let is_unit = fields.is_empty();
                 let unstable_span = self.allow_internal_unstable("...", e.span);
                 let struct_path =
-                    iter::once("ops").chain(iter::once(path)).chain(variant)
+                    iter::once("ops").chain(iter::once(path))
                     .collect::<Vec<_>>();
                 let struct_path = self.std_path(unstable_span, &struct_path, is_unit);
                 let struct_path = hir::QPath::Resolved(None, P(struct_path));
index 1ecc277c7ca4d27dd407cfc9ff39b1f910c5ecdb..270430f40df02d145ed68321d5c50f35d0516126 100644 (file)
@@ -161,7 +161,7 @@ pub struct InferCtxt<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
     // For region variables.
     region_vars: RegionVarBindings<'a, 'gcx, 'tcx>,
 
-    pub parameter_environment: ty::ParameterEnvironment<'gcx>,
+    pub param_env: ty::ParamEnv<'gcx>,
 
     /// Caches the results of trait selection. This cache is used
     /// for things that have to do with the parameters in scope.
@@ -406,41 +406,41 @@ pub trait InferEnv<'a, 'tcx> {
     fn to_parts(self, tcx: TyCtxt<'a, 'tcx, 'tcx>)
                 -> (Option<&'a ty::TypeckTables<'tcx>>,
                     Option<ty::TypeckTables<'tcx>>,
-                    Option<ty::ParameterEnvironment<'tcx>>);
+                    Option<ty::ParamEnv<'tcx>>);
 }
 
 impl<'a, 'tcx> InferEnv<'a, 'tcx> for () {
     fn to_parts(self, _: TyCtxt<'a, 'tcx, 'tcx>)
                 -> (Option<&'a ty::TypeckTables<'tcx>>,
                     Option<ty::TypeckTables<'tcx>>,
-                    Option<ty::ParameterEnvironment<'tcx>>) {
+                    Option<ty::ParamEnv<'tcx>>) {
         (None, None, None)
     }
 }
 
-impl<'a, 'tcx> InferEnv<'a, 'tcx> for ty::ParameterEnvironment<'tcx> {
+impl<'a, 'tcx> InferEnv<'a, 'tcx> for ty::ParamEnv<'tcx> {
     fn to_parts(self, _: TyCtxt<'a, 'tcx, 'tcx>)
                 -> (Option<&'a ty::TypeckTables<'tcx>>,
                     Option<ty::TypeckTables<'tcx>>,
-                    Option<ty::ParameterEnvironment<'tcx>>) {
+                    Option<ty::ParamEnv<'tcx>>) {
         (None, None, Some(self))
     }
 }
 
-impl<'a, 'tcx> InferEnv<'a, 'tcx> for (&'a ty::TypeckTables<'tcx>, ty::ParameterEnvironment<'tcx>) {
+impl<'a, 'tcx> InferEnv<'a, 'tcx> for (&'a ty::TypeckTables<'tcx>, ty::ParamEnv<'tcx>) {
     fn to_parts(self, _: TyCtxt<'a, 'tcx, 'tcx>)
                 -> (Option<&'a ty::TypeckTables<'tcx>>,
                     Option<ty::TypeckTables<'tcx>>,
-                    Option<ty::ParameterEnvironment<'tcx>>) {
+                    Option<ty::ParamEnv<'tcx>>) {
         (Some(self.0), None, Some(self.1))
     }
 }
 
-impl<'a, 'tcx> InferEnv<'a, 'tcx> for (ty::TypeckTables<'tcx>, ty::ParameterEnvironment<'tcx>) {
+impl<'a, 'tcx> InferEnv<'a, 'tcx> for (ty::TypeckTables<'tcx>, ty::ParamEnv<'tcx>) {
     fn to_parts(self, _: TyCtxt<'a, 'tcx, 'tcx>)
                 -> (Option<&'a ty::TypeckTables<'tcx>>,
                     Option<ty::TypeckTables<'tcx>>,
-                    Option<ty::ParameterEnvironment<'tcx>>) {
+                    Option<ty::ParamEnv<'tcx>>) {
         (None, Some(self.0), Some(self.1))
     }
 }
@@ -449,11 +449,11 @@ impl<'a, 'tcx> InferEnv<'a, 'tcx> for hir::BodyId {
     fn to_parts(self, tcx: TyCtxt<'a, 'tcx, 'tcx>)
                 -> (Option<&'a ty::TypeckTables<'tcx>>,
                     Option<ty::TypeckTables<'tcx>>,
-                    Option<ty::ParameterEnvironment<'tcx>>) {
+                    Option<ty::ParamEnv<'tcx>>) {
         let def_id = tcx.hir.body_owner_def_id(self);
         (Some(tcx.typeck_tables_of(def_id)),
          None,
-         Some(tcx.parameter_environment(def_id)))
+         Some(tcx.param_env(def_id)))
     }
 }
 
@@ -465,7 +465,7 @@ pub struct InferCtxtBuilder<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
     arena: DroplessArena,
     fresh_tables: Option<RefCell<ty::TypeckTables<'tcx>>>,
     tables: Option<&'a ty::TypeckTables<'gcx>>,
-    param_env: Option<ty::ParameterEnvironment<'gcx>>,
+    param_env: Option<ty::ParamEnv<'gcx>>,
     projection_mode: Reveal,
 }
 
@@ -498,7 +498,7 @@ pub fn borrowck_fake_infer_ctxt(self, body: hir::BodyId)
             int_unification_table: RefCell::new(UnificationTable::new()),
             float_unification_table: RefCell::new(UnificationTable::new()),
             region_vars: RegionVarBindings::new(self),
-            parameter_environment: param_env.unwrap(),
+            param_env: param_env.unwrap(),
             selection_cache: traits::SelectionCache::new(),
             evaluation_cache: traits::EvaluationCache::new(),
             projection_cache: RefCell::new(traits::ProjectionCache::new()),
@@ -526,9 +526,7 @@ pub fn enter<F, R>(&'tcx mut self, f: F) -> R
         let tables = tables.map(InferTables::Interned).unwrap_or_else(|| {
             fresh_tables.as_ref().map_or(InferTables::Missing, InferTables::InProgress)
         });
-        let param_env = param_env.take().unwrap_or_else(|| {
-            global_tcx.empty_parameter_environment()
-        });
+        let param_env = param_env.take().unwrap_or_else(|| ty::ParamEnv::empty());
         global_tcx.enter_local(arena, |tcx| f(InferCtxt {
             tcx: tcx,
             tables: tables,
@@ -537,7 +535,7 @@ pub fn enter<F, R>(&'tcx mut self, f: F) -> R
             int_unification_table: RefCell::new(UnificationTable::new()),
             float_unification_table: RefCell::new(UnificationTable::new()),
             region_vars: RegionVarBindings::new(tcx),
-            parameter_environment: param_env,
+            param_env: param_env,
             selection_cache: traits::SelectionCache::new(),
             evaluation_cache: traits::EvaluationCache::new(),
             reported_trait_errors: RefCell::new(FxHashSet()),
@@ -650,7 +648,7 @@ pub fn normalize_associated_type<T>(self, value: &T) -> T
     }
 
     pub fn normalize_associated_type_in_env<T>(
-        self, value: &T, env: &'a ty::ParameterEnvironment<'tcx>
+        self, value: &T, env: ty::ParamEnv<'tcx>
     ) -> T
         where T: TransNormalize<'tcx>
     {
@@ -662,7 +660,7 @@ pub fn normalize_associated_type_in_env<T>(
             return value;
         }
 
-        self.infer_ctxt(env.clone(), Reveal::All).enter(|infcx| {
+        self.infer_ctxt(env, Reveal::All).enter(|infcx| {
             value.trans_normalize(&infcx)
        })
     }
@@ -1674,8 +1672,8 @@ pub fn upvar_capture(&self, upvar_id: ty::UpvarId) -> Option<ty::UpvarCapture<'t
         self.tables.borrow().upvar_capture_map.get(&upvar_id).cloned()
     }
 
-    pub fn param_env(&self) -> &ty::ParameterEnvironment<'gcx> {
-        &self.parameter_environment
+    pub fn param_env(&self) -> ty::ParamEnv<'gcx> {
+        self.param_env
     }
 
     pub fn closure_kind(&self,
index f32ee7900646b0e4f1c82e9b415362e85dbc533d..2b4b5cc73337b7306dc5d6a9d3c3bda7ce9fd7a9 100644 (file)
@@ -30,7 +30,6 @@
 #![feature(core_intrinsics)]
 #![feature(i128_type)]
 #![feature(libc)]
-#![feature(loop_break_value)]
 #![feature(never_type)]
 #![feature(nonzero)]
 #![feature(quote)]
@@ -45,6 +44,7 @@
 #![cfg_attr(stage0, unstable(feature = "rustc_private", issue = "27812"))]
 #![cfg_attr(stage0, feature(rustc_private))]
 #![cfg_attr(stage0, feature(staged_api))]
+#![cfg_attr(stage0, feature(loop_break_value))]
 
 #![recursion_limit="128"]
 
index ff72f9dd07e36096819e2244644099a136cc63c4..c49df4b1ad9ea8bd6f564ccb08a9eb546a3cea44 100644 (file)
@@ -418,16 +418,16 @@ before, and hence the cache lookup would succeed, yielding
 One subtle interaction is that the results of trait lookup will vary
 depending on what where clauses are in scope. Therefore, we actually
 have *two* caches, a local and a global cache. The local cache is
-attached to the `ParameterEnvironment` and the global cache attached
-to the `tcx`. We use the local cache whenever the result might depend
-on the where clauses that are in scope. The determination of which
-cache to use is done by the method `pick_candidate_cache` in
-`select.rs`. At the moment, we use a very simple, conservative rule:
-if there are any where-clauses in scope, then we use the local cache.
-We used to try and draw finer-grained distinctions, but that led to a
-serious of annoying and weird bugs like #22019 and #18290. This simple
-rule seems to be pretty clearly safe and also still retains a very
-high hit rate (~95% when compiling rustc).
+attached to the `ParamEnv` and the global cache attached to the
+`tcx`. We use the local cache whenever the result might depend on the
+where clauses that are in scope. The determination of which cache to
+use is done by the method `pick_candidate_cache` in `select.rs`. At
+the moment, we use a very simple, conservative rule: if there are any
+where-clauses in scope, then we use the local cache.  We used to try
+and draw finer-grained distinctions, but that led to a serious of
+annoying and weird bugs like #22019 and #18290. This simple rule seems
+to be pretty clearly safe and also still retains a very high hit rate
+(~95% when compiling rustc).
 
 # Specialization
 
index 152e3353994b3b32315d8591d4e482f2792b461d..3c7761c6cd3bcf338373f2a5c278e5af96666048 100644 (file)
@@ -559,6 +559,23 @@ pub fn report_selection_error(&self,
                             trait_ref.to_predicate(),
                             post_message);
 
+                        let unimplemented_note = self.on_unimplemented_note(trait_ref, obligation);
+                        if let Some(ref s) = unimplemented_note {
+                            // If it has a custom "#[rustc_on_unimplemented]"
+                            // error message, let's display it as the label!
+                            err.span_label(span, s.as_str());
+                            err.help(&format!("{}the trait `{}` is not implemented for `{}`",
+                                              pre_message,
+                                              trait_ref,
+                                              trait_ref.self_ty()));
+                        } else {
+                            err.span_label(span,
+                                           &*format!("{}the trait `{}` is not implemented for `{}`",
+                                                     pre_message,
+                                                     trait_ref,
+                                                     trait_ref.self_ty()));
+                        }
+
                         // Try to report a help message
                         if !trait_ref.has_infer_types() &&
                             self.predicate_can_apply(trait_ref) {
@@ -571,21 +588,12 @@ pub fn report_selection_error(&self,
                             // which is somewhat confusing.
                             err.help(&format!("consider adding a `where {}` bound",
                                                 trait_ref.to_predicate()));
-                        } else if let Some(s) = self.on_unimplemented_note(trait_ref, obligation) {
-                            // If it has a custom "#[rustc_on_unimplemented]"
-                            // error message, let's display it!
-                            err.note(&s);
-                        } else {
+                        } else if unimplemented_note.is_none() {
                             // Can't show anything else useful, try to find similar impls.
                             let impl_candidates = self.find_similar_impl_candidates(trait_ref);
                             self.report_similar_impl_candidates(impl_candidates, &mut err);
                         }
 
-                        err.span_label(span,
-                                       format!("{}the trait `{}` is not implemented for `{}`",
-                                                pre_message,
-                                                trait_ref,
-                                                trait_ref.self_ty()));
                         err
                     }
 
index 1823373348badfb8ef177602d852f4ed29ff0217..e358f39bd9a3a1356fb2130b3ea15cb1b382bcb9 100644 (file)
@@ -437,9 +437,9 @@ pub fn type_known_to_meet_bound<'a, 'gcx, 'tcx>(infcx: &InferCtxt<'a, 'gcx, 'tcx
 /// Normalizes the parameter environment, reporting errors if they occur.
 pub fn normalize_param_env_or_error<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                                               region_context: DefId,
-                                              unnormalized_env: ty::ParameterEnvironment<'tcx>,
+                                              unnormalized_env: ty::ParamEnv<'tcx>,
                                               cause: ObligationCause<'tcx>)
-                                              -> ty::ParameterEnvironment<'tcx>
+                                              -> ty::ParamEnv<'tcx>
 {
     // I'm not wild about reporting errors here; I'd prefer to
     // have the errors get reported at a defined place (e.g.,
@@ -477,15 +477,15 @@ pub fn normalize_param_env_or_error<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
     debug!("normalize_param_env_or_error: elaborated-predicates={:?}",
            predicates);
 
-    let elaborated_env = unnormalized_env.with_caller_bounds(tcx.intern_predicates(&predicates));
+    let elaborated_env = ty::ParamEnv::new(tcx.intern_predicates(&predicates));
 
     tcx.infer_ctxt(elaborated_env, Reveal::UserFacing).enter(|infcx| {
         let predicates = match fully_normalize(
                 &infcx, cause,
-                // You would really want to pass infcx.parameter_environment.caller_bounds here,
+                // You would really want to pass infcx.param_env.caller_bounds here,
                 // but that is an interned slice, and fully_normalize takes &T and returns T, so
                 // without further refactoring, a slice can't be used. Luckily, we still have the
-                // predicate vector from which we created the ParameterEnvironment in infcx, so we
+                // predicate vector from which we created the ParamEnv in infcx, so we
                 // can pass that instead. It's roundabout and a bit brittle, but this code path
                 // ought to be refactored anyway, and until then it saves us from having to copy.
                 &predicates,
@@ -494,7 +494,7 @@ pub fn normalize_param_env_or_error<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
             Err(errors) => {
                 infcx.report_fulfillment_errors(&errors);
                 // An unnormalized env is better than nothing.
-                return infcx.parameter_environment;
+                return infcx.param_env;
             }
         };
 
@@ -516,19 +516,19 @@ pub fn normalize_param_env_or_error<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                 // all things considered.
                 tcx.sess.span_err(span, &fixup_err.to_string());
                 // An unnormalized env is better than nothing.
-                return infcx.parameter_environment;
+                return infcx.param_env;
             }
         };
 
         let predicates = match tcx.lift_to_global(&predicates) {
             Some(predicates) => predicates,
-            None => return infcx.parameter_environment
+            None => return infcx.param_env
         };
 
         debug!("normalize_param_env_or_error: resolved predicates={:?}",
             predicates);
 
-        infcx.parameter_environment.with_caller_bounds(tcx.intern_predicates(&predicates))
+        ty::ParamEnv::new(tcx.intern_predicates(&predicates))
     })
 }
 
index cccc20e5b296bd692fdd23ec52144512fd942582..7366ed45f31bd514f96279377cbd36433dfe1e26 100644 (file)
@@ -315,7 +315,7 @@ pub fn tcx(&self) -> TyCtxt<'cx, 'gcx, 'tcx> {
         self.infcx.tcx
     }
 
-    pub fn param_env(&self) -> &'cx ty::ParameterEnvironment<'gcx> {
+    pub fn param_env(&self) -> ty::ParamEnv<'gcx> {
         self.infcx.param_env()
     }
 
index 0e5779f9d17935b291fc1d72aec74fd879166c0f..e0f28e3b49e919832a56b8bc738e0b2f6d983fe2 100644 (file)
@@ -180,7 +180,7 @@ pub fn specializes<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
     }
 
     // create a parameter environment corresponding to a (skolemized) instantiation of impl1
-    let penv = tcx.parameter_environment(impl1_def_id);
+    let penv = tcx.param_env(impl1_def_id);
     let impl1_trait_ref = tcx.impl_trait_ref(impl1_def_id).unwrap();
 
     // Create a infcx, taking the predicates of impl1 as assumptions:
@@ -250,7 +250,7 @@ fn fulfill_implication<'a, 'gcx, 'tcx>(infcx: &InferCtxt<'a, 'gcx, 'tcx>,
                        source_trait_ref,
                        target_trait_ref,
                        errors,
-                       infcx.parameter_environment.caller_bounds);
+                       infcx.param_env.caller_bounds);
                 Err(())
             }
 
index b9355c264b3ef49d85c7f1d392645d7b3c6ef3ee..5ee0b1c9e5ea44ba421bc9a29b03e29e84135709 100644 (file)
@@ -138,7 +138,7 @@ fn intern_ty(&self, st: TypeVariants<'tcx>,
             let flags = super::flags::FlagComputation::for_sty(&st);
             let ty_struct = TyS {
                 sty: st,
-                flags: Cell::new(flags.flags),
+                flags: flags.flags,
                 region_depth: flags.depth,
             };
 
@@ -978,8 +978,8 @@ pub fn go(tcx: TyCtxt) {
                         ty::TyError => /* unimportant */ continue,
                         $(ty::$variant(..) => &mut $variant,)*
                     };
-                    let region = t.flags.get().intersects(ty::TypeFlags::HAS_RE_INFER);
-                    let ty = t.flags.get().intersects(ty::TypeFlags::HAS_TY_INFER);
+                    let region = t.flags.intersects(ty::TypeFlags::HAS_RE_INFER);
+                    let ty = t.flags.intersects(ty::TypeFlags::HAS_TY_INFER);
 
                     variant.total += 1;
                     total.total += 1;
index 686b99ba680942eb734f8c1578b7ca648d849eac..46afa6ee7d011d48053d892c02cd4cdc1ec65b83 100644 (file)
@@ -167,7 +167,7 @@ fn add_sty(&mut self, st: &ty::TypeVariants) {
     }
 
     fn add_ty(&mut self, ty: Ty) {
-        self.add_flags(ty.flags.get());
+        self.add_flags(ty.flags);
         self.add_depth(ty.region_depth);
     }
 
index 6de3c018bda0ebe8223760d6d7eb282553712540..c17a54f4f69bbb98717992d487c0d0c8a1e7afba 100644 (file)
@@ -625,9 +625,8 @@ struct HasTypeFlagsVisitor {
 
 impl<'tcx> TypeVisitor<'tcx> for HasTypeFlagsVisitor {
     fn visit_ty(&mut self, t: Ty) -> bool {
-        let flags = t.flags.get();
-        debug!("HasTypeFlagsVisitor: t={:?} t.flags={:?} self.flags={:?}", t, flags, self.flags);
-        flags.intersects(self.flags)
+        debug!("HasTypeFlagsVisitor: t={:?} t.flags={:?} self.flags={:?}", t, t.flags, self.flags);
+        t.flags.intersects(self.flags)
     }
 
     fn visit_region(&mut self, r: ty::Region<'tcx>) -> bool {
index bd38a6c3fd39a6edad843f3053b95fe8b4325ea4..1a8c74ff1f94323db427711be1617d01c1100a48 100644 (file)
@@ -1079,7 +1079,7 @@ pub fn compute_uncached(ty: Ty<'gcx>,
         let ptr_layout = |pointee: Ty<'gcx>| {
             let non_zero = !ty.is_unsafe_ptr();
             let pointee = infcx.normalize_projections(pointee);
-            if pointee.is_sized(tcx, &infcx.parameter_environment, DUMMY_SP) {
+            if pointee.is_sized(tcx, infcx.param_env, DUMMY_SP) {
                 Ok(Scalar { value: Pointer, non_zero: non_zero })
             } else {
                 let unsized_part = tcx.struct_tail(pointee);
@@ -1268,11 +1268,11 @@ pub fn compute_uncached(ty: Ty<'gcx>,
                     let kind = if def.is_enum() || def.variants[0].fields.len() == 0{
                         StructKind::AlwaysSizedUnivariant
                     } else {
-                        let param_env = tcx.parameter_environment(def.did);
+                        let param_env = tcx.param_env(def.did);
                         let fields = &def.variants[0].fields;
                         let last_field = &fields[fields.len()-1];
                         let always_sized = tcx.type_of(last_field.did)
-                          .is_sized(tcx, &param_env, DUMMY_SP);
+                          .is_sized(tcx, param_env, DUMMY_SP);
                         if !always_sized { StructKind::MaybeUnsizedUnivariant }
                         else { StructKind::AlwaysSizedUnivariant }
                     };
index 85462bd9b1273ca2a40946ace10c0355abcb9212..fb352e5be89383c4743522ba1abe85ab54217aea 100644 (file)
@@ -9,7 +9,7 @@
 // except according to those terms.
 
 use dep_graph::{DepGraph, DepNode, DepTrackingMap, DepTrackingMapConfig};
-use hir::def_id::{CrateNum, DefId, LOCAL_CRATE};
+use hir::def_id::{CrateNum, CRATE_DEF_INDEX, DefId, LOCAL_CRATE};
 use hir::def::Def;
 use hir;
 use middle::const_val;
@@ -136,6 +136,15 @@ fn default_span(&self, tcx: TyCtxt) -> Span {
     }
 }
 
+impl<'tcx, T: Clone + Hash + Eq + Debug> Key for ty::ParamEnvAnd<'tcx, T> {
+    fn map_crate(&self) -> CrateNum {
+        LOCAL_CRATE
+    }
+    fn default_span(&self, _: TyCtxt) -> Span {
+        DUMMY_SP
+    }
+}
+
 trait Value<'tcx>: Sized {
     fn from_cycle_error<'a>(tcx: TyCtxt<'a, 'tcx, 'tcx>) -> Self;
 }
@@ -244,6 +253,30 @@ impl<M: DepTrackingMapConfig<Key=DefId>> QueryDescription for M {
     }
 }
 
+impl<'tcx> QueryDescription for queries::is_copy_raw<'tcx> {
+    fn describe(_tcx: TyCtxt, env: ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> String {
+        format!("computing whether `{}` is `Copy`", env.value)
+    }
+}
+
+impl<'tcx> QueryDescription for queries::is_sized_raw<'tcx> {
+    fn describe(_tcx: TyCtxt, env: ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> String {
+        format!("computing whether `{}` is `Sized`", env.value)
+    }
+}
+
+impl<'tcx> QueryDescription for queries::is_freeze_raw<'tcx> {
+    fn describe(_tcx: TyCtxt, env: ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> String {
+        format!("computing whether `{}` is freeze", env.value)
+    }
+}
+
+impl<'tcx> QueryDescription for queries::needs_drop_raw<'tcx> {
+    fn describe(_tcx: TyCtxt, env: ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> String {
+        format!("computing whether `{}` needs drop", env.value)
+    }
+}
+
 impl<'tcx> QueryDescription for queries::super_predicates_of<'tcx> {
     fn describe(tcx: TyCtxt, def_id: DefId) -> String {
         format!("computing the supertraits of `{}`",
@@ -856,6 +889,15 @@ fn default() -> Self {
         -> ty::trait_def::TraitImpls,
     [] specialization_graph_of: SpecializationGraph(DefId) -> Rc<specialization_graph::Graph>,
     [] is_object_safe: ObjectSafety(DefId) -> bool,
+
+    [] param_env: ParamEnv(DefId) -> ty::ParamEnv<'tcx>,
+
+    // Trait selection queries. These are best used by invoking `ty.moves_by_default()`,
+    // `ty.is_copy()`, etc, since that will prune the environment where possible.
+    [] is_copy_raw: is_copy_dep_node(ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> bool,
+    [] is_sized_raw: is_sized_dep_node(ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> bool,
+    [] is_freeze_raw: is_freeze_dep_node(ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> bool,
+    [] needs_drop_raw: needs_drop_dep_node(ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> bool,
 }
 
 fn coherent_trait_dep_node((_, def_id): (CrateNum, DefId)) -> DepNode<DefId> {
@@ -899,3 +941,27 @@ fn crate_variances(_: CrateNum) -> DepNode<DefId> {
 fn relevant_trait_impls_for((def_id, _): (DefId, SimplifiedType)) -> DepNode<DefId> {
     DepNode::TraitImpls(def_id)
 }
+
+fn is_copy_dep_node<'tcx>(key: ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> DepNode<DefId> {
+    let def_id = ty::item_path::characteristic_def_id_of_type(key.value)
+        .unwrap_or(DefId::local(CRATE_DEF_INDEX));
+    DepNode::IsCopy(def_id)
+}
+
+fn is_sized_dep_node<'tcx>(key: ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> DepNode<DefId> {
+    let def_id = ty::item_path::characteristic_def_id_of_type(key.value)
+        .unwrap_or(DefId::local(CRATE_DEF_INDEX));
+    DepNode::IsSized(def_id)
+}
+
+fn is_freeze_dep_node<'tcx>(key: ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> DepNode<DefId> {
+    let def_id = ty::item_path::characteristic_def_id_of_type(key.value)
+        .unwrap_or(DefId::local(CRATE_DEF_INDEX));
+    DepNode::IsFreeze(def_id)
+}
+
+fn needs_drop_dep_node<'tcx>(key: ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> DepNode<DefId> {
+    let def_id = ty::item_path::characteristic_def_id_of_type(key.value)
+        .unwrap_or(DefId::local(CRATE_DEF_INDEX));
+    DepNode::NeedsDrop(def_id)
+}
index 359722ce96ec9786f0131c197805fac38806bfe7..fa731f6dde638f6fb97f3ff4acf282ad5e5239c9 100644 (file)
@@ -35,7 +35,6 @@
 use util::nodemap::{NodeSet, DefIdMap, FxHashMap, FxHashSet};
 
 use serialize::{self, Encodable, Encoder};
-use std::cell::{Cell, RefCell};
 use std::collections::BTreeMap;
 use std::cmp;
 use std::fmt;
@@ -503,22 +502,12 @@ pub enum FragmentInfo {
                                   TypeFlags::HAS_TY_CLOSURE.bits |
                                   TypeFlags::HAS_LOCAL_NAMES.bits |
                                   TypeFlags::KEEP_IN_LOCAL_TCX.bits,
-
-        // Caches for type_is_sized, type_moves_by_default
-        const SIZEDNESS_CACHED  = 1 << 16,
-        const IS_SIZED          = 1 << 17,
-        const MOVENESS_CACHED   = 1 << 18,
-        const MOVES_BY_DEFAULT  = 1 << 19,
-        const FREEZENESS_CACHED = 1 << 20,
-        const IS_FREEZE         = 1 << 21,
-        const NEEDS_DROP_CACHED = 1 << 22,
-        const NEEDS_DROP        = 1 << 23,
     }
 }
 
 pub struct TyS<'tcx> {
     pub sty: TypeVariants<'tcx>,
-    pub flags: Cell<TypeFlags>,
+    pub flags: TypeFlags,
 
     // the maximal depth of any bound regions appearing in this type.
     region_depth: u32,
@@ -1249,46 +1238,58 @@ pub fn is_empty(&self) -> bool {
     }
 }
 
-/// When type checking, we use the `ParameterEnvironment` to track
-/// details about the type/lifetime parameters that are in scope.
-/// It primarily stores the bounds information.
-///
-/// Note: This information might seem to be redundant with the data in
-/// `tcx.ty_param_defs`, but it is not. That table contains the
-/// parameter definitions from an "outside" perspective, but this
-/// struct will contain the bounds for a parameter as seen from inside
-/// the function body. Currently the only real distinction is that
-/// bound lifetime parameters are replaced with free ones, but in the
-/// future I hope to refine the representation of types so as to make
-/// more distinctions clearer.
-#[derive(Clone)]
-pub struct ParameterEnvironment<'tcx> {
+/// When type checking, we use the `ParamEnv` to track
+/// details about the set of where-clauses that are in scope at this
+/// particular point.
+#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
+pub struct ParamEnv<'tcx> {
     /// Obligations that the caller must satisfy. This is basically
     /// the set of bounds on the in-scope type parameters, translated
     /// into Obligations, and elaborated and normalized.
-    pub caller_bounds: &'tcx [ty::Predicate<'tcx>],
-
-    /// A cache for `moves_by_default`.
-    pub is_copy_cache: RefCell<FxHashMap<Ty<'tcx>, bool>>,
+    pub caller_bounds: &'tcx Slice<ty::Predicate<'tcx>>,
+}
 
-    /// A cache for `type_is_sized`
-    pub is_sized_cache: RefCell<FxHashMap<Ty<'tcx>, bool>>,
+impl<'tcx> ParamEnv<'tcx> {
+    /// Creates a suitable environment in which to perform trait
+    /// queries on the given value. This will either be `self` *or*
+    /// the empty environment, depending on whether `value` references
+    /// type parameters that are in scope. (If it doesn't, then any
+    /// judgements should be completely independent of the context,
+    /// and hence we can safely use the empty environment so as to
+    /// enable more sharing across functions.)
+    ///
+    /// NB: This is a mildly dubious thing to do, in that a function
+    /// (or other environment) might have wacky where-clauses like
+    /// `where Box<u32>: Copy`, which are clearly never
+    /// satisfiable. The code will at present ignore these,
+    /// effectively, when type-checking the body of said
+    /// function. This preserves existing behavior in any
+    /// case. --nmatsakis
+    pub fn and<T: TypeFoldable<'tcx>>(self, value: T) -> ParamEnvAnd<'tcx, T> {
+        assert!(!value.needs_infer());
+        if value.has_param_types() || value.has_self_ty() {
+            ParamEnvAnd {
+                param_env: self,
+                value: value,
+            }
+        } else {
+            ParamEnvAnd {
+                param_env: ParamEnv::empty(),
+                value: value,
+            }
+        }
+    }
+}
 
-    /// A cache for `type_is_freeze`
-    pub is_freeze_cache: RefCell<FxHashMap<Ty<'tcx>, bool>>,
+#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
+pub struct ParamEnvAnd<'tcx, T> {
+    pub param_env: ParamEnv<'tcx>,
+    pub value: T,
 }
 
-impl<'a, 'tcx> ParameterEnvironment<'tcx> {
-    pub fn with_caller_bounds(&self,
-                              caller_bounds: &'tcx [ty::Predicate<'tcx>])
-                              -> ParameterEnvironment<'tcx>
-    {
-        ParameterEnvironment {
-            caller_bounds: caller_bounds,
-            is_copy_cache: RefCell::new(FxHashMap()),
-            is_sized_cache: RefCell::new(FxHashMap()),
-            is_freeze_cache: RefCell::new(FxHashMap()),
-        }
+impl<'tcx, T> ParamEnvAnd<'tcx, T> {
+    pub fn into_parts(self) -> (ParamEnv<'tcx>, T) {
+        (self.param_env, self.value)
     }
 }
 
@@ -2357,54 +2358,6 @@ pub fn impl_of_method(self, def_id: DefId) -> Option<DefId> {
         }
     }
 
-    /// Construct a parameter environment suitable for static contexts or other contexts where there
-    /// are no free type/lifetime parameters in scope.
-    pub fn empty_parameter_environment(self) -> ParameterEnvironment<'tcx> {
-        ty::ParameterEnvironment {
-            caller_bounds: Slice::empty(),
-            is_copy_cache: RefCell::new(FxHashMap()),
-            is_sized_cache: RefCell::new(FxHashMap()),
-            is_freeze_cache: RefCell::new(FxHashMap()),
-        }
-    }
-
-    /// See `ParameterEnvironment` struct def'n for details.
-    pub fn parameter_environment(self, def_id: DefId) -> ParameterEnvironment<'gcx> {
-        //
-        // Compute the bounds on Self and the type parameters.
-        //
-
-        let tcx = self.global_tcx();
-        let bounds = tcx.predicates_of(def_id).instantiate_identity(tcx);
-        let predicates = bounds.predicates;
-
-        // Finally, we have to normalize the bounds in the environment, in
-        // case they contain any associated type projections. This process
-        // can yield errors if the put in illegal associated types, like
-        // `<i32 as Foo>::Bar` where `i32` does not implement `Foo`. We
-        // report these errors right here; this doesn't actually feel
-        // right to me, because constructing the environment feels like a
-        // kind of a "idempotent" action, but I'm not sure where would be
-        // a better place. In practice, we construct environments for
-        // every fn once during type checking, and we'll abort if there
-        // are any errors at that point, so after type checking you can be
-        // sure that this will succeed without errors anyway.
-        //
-
-        let unnormalized_env = ty::ParameterEnvironment {
-            caller_bounds: tcx.intern_predicates(&predicates),
-            is_copy_cache: RefCell::new(FxHashMap()),
-            is_sized_cache: RefCell::new(FxHashMap()),
-            is_freeze_cache: RefCell::new(FxHashMap()),
-        };
-
-        let body_id = self.hir.as_local_node_id(def_id).map_or(DUMMY_NODE_ID, |id| {
-            self.hir.maybe_body_owned_by(id).map_or(id, |body| body.node_id)
-        });
-        let cause = traits::ObligationCause::misc(tcx.def_span(def_id), body_id);
-        traits::normalize_param_env_or_error(tcx, def_id, unnormalized_env, cause)
-    }
-
     pub fn node_scope_region(self, id: NodeId) -> Region<'tcx> {
         self.mk_region(ty::ReScope(CodeExtent::Misc(id)))
     }
@@ -2564,14 +2517,45 @@ fn trait_of_item<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> Option
         })
 }
 
+/// See `ParamEnv` struct def'n for details.
+fn param_env<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
+                                   def_id: DefId)
+                                   -> ParamEnv<'tcx> {
+    // Compute the bounds on Self and the type parameters.
+
+    let bounds = tcx.predicates_of(def_id).instantiate_identity(tcx);
+    let predicates = bounds.predicates;
+
+    // Finally, we have to normalize the bounds in the environment, in
+    // case they contain any associated type projections. This process
+    // can yield errors if the put in illegal associated types, like
+    // `<i32 as Foo>::Bar` where `i32` does not implement `Foo`. We
+    // report these errors right here; this doesn't actually feel
+    // right to me, because constructing the environment feels like a
+    // kind of a "idempotent" action, but I'm not sure where would be
+    // a better place. In practice, we construct environments for
+    // every fn once during type checking, and we'll abort if there
+    // are any errors at that point, so after type checking you can be
+    // sure that this will succeed without errors anyway.
+
+    let unnormalized_env = ty::ParamEnv::new(tcx.intern_predicates(&predicates));
+
+    let body_id = tcx.hir.as_local_node_id(def_id).map_or(DUMMY_NODE_ID, |id| {
+        tcx.hir.maybe_body_owned_by(id).map_or(id, |body| body.node_id)
+    });
+    let cause = traits::ObligationCause::misc(tcx.def_span(def_id), body_id);
+    traits::normalize_param_env_or_error(tcx, def_id, unnormalized_env, cause)
+}
 
 pub fn provide(providers: &mut ty::maps::Providers) {
+    util::provide(providers);
     *providers = ty::maps::Providers {
         associated_item,
         associated_item_def_ids,
         adt_sized_constraint,
         adt_dtorck_constraint,
         def_span,
+        param_env,
         trait_of_item,
         trait_impls_of: trait_def::trait_impls_of_provider,
         relevant_trait_impls_for: trait_def::relevant_trait_impls_provider,
@@ -2585,6 +2569,7 @@ pub fn provide_extern(providers: &mut ty::maps::Providers) {
         adt_dtorck_constraint,
         trait_impls_of: trait_def::trait_impls_of_provider,
         relevant_trait_impls_for: trait_def::relevant_trait_impls_provider,
+        param_env,
         ..*providers
     };
 }
index c6c6a0e47003dbb40777d056b2ade638c6259eb7..01fed11fc97affd7e8ad22cb0f275e7b5ec1faef 100644 (file)
 use infer::InferCtxt;
 use ich::{StableHashingContext, NodeIdHashingMode};
 use traits::{self, Reveal};
-use ty::{self, Ty, TyCtxt, TypeAndMut, TypeFlags, TypeFoldable};
-use ty::ParameterEnvironment;
+use ty::{self, Ty, TyCtxt, TypeFoldable};
 use ty::fold::TypeVisitor;
 use ty::layout::{Layout, LayoutError};
 use ty::subst::{Subst, Kind};
 use ty::TypeVariants::*;
 use util::common::ErrorReported;
-use util::nodemap::{FxHashMap, FxHashSet};
 use middle::lang_items;
 
 use rustc_const_math::{ConstInt, ConstIsize, ConstUsize};
 use rustc_data_structures::stable_hasher::{StableHasher, StableHasherResult,
                                            HashStable};
-use std::cell::RefCell;
 use std::cmp;
 use std::hash::Hash;
 use std::intrinsics;
@@ -36,8 +33,6 @@
 use syntax::attr::{self, SignedInt, UnsignedInt};
 use syntax_pos::{Span, DUMMY_SP};
 
-use hir;
-
 type Disr = ConstInt;
 
 pub trait IntTypeExt {
@@ -152,7 +147,18 @@ pub enum Representability {
     SelfRecursive(Vec<Span>),
 }
 
-impl<'tcx> ParameterEnvironment<'tcx> {
+impl<'tcx> ty::ParamEnv<'tcx> {
+    /// Construct a trait environment suitable for contexts where
+    /// there are no where clauses in scope.
+    pub fn empty() -> Self {
+        Self::new(ty::Slice::empty())
+    }
+
+    /// Construct a trait environment with the given set of predicates.
+    pub fn new(caller_bounds: &'tcx ty::Slice<ty::Predicate<'tcx>>) -> Self {
+        ty::ParamEnv { caller_bounds }
+    }
+
     pub fn can_type_implement_copy<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>,
                                        self_type: Ty<'tcx>, span: Span)
                                        -> Result<(), CopyImplementationError> {
@@ -711,152 +717,28 @@ fn visit_binder<T: TypeFoldable<'tcx>>(&mut self, x: &ty::Binder<T>) -> bool {
 }
 
 impl<'a, 'tcx> ty::TyS<'tcx> {
-    fn impls_bound(&'tcx self, tcx: TyCtxt<'a, 'tcx, 'tcx>,
-                   param_env: &ParameterEnvironment<'tcx>,
-                   def_id: DefId,
-                   cache: &RefCell<FxHashMap<Ty<'tcx>, bool>>,
-                   span: Span) -> bool
-    {
-        if self.has_param_types() || self.has_self_ty() {
-            if let Some(result) = cache.borrow().get(self) {
-                return *result;
-            }
-        }
-        let result =
-            tcx.infer_ctxt(param_env.clone(), Reveal::UserFacing)
-            .enter(|infcx| {
-                traits::type_known_to_meet_bound(&infcx, self, def_id, span)
-            });
-        if self.has_param_types() || self.has_self_ty() {
-            cache.borrow_mut().insert(self, result);
-        }
-        return result;
-    }
-
-    // FIXME (@jroesch): I made this public to use it, not sure if should be private
-    pub fn moves_by_default(&'tcx self, tcx: TyCtxt<'a, 'tcx, 'tcx>,
-                            param_env: &ParameterEnvironment<'tcx>,
-                            span: Span) -> bool {
-        if self.flags.get().intersects(TypeFlags::MOVENESS_CACHED) {
-            return self.flags.get().intersects(TypeFlags::MOVES_BY_DEFAULT);
-        }
-
-        assert!(!self.needs_infer());
-
-        // Fast-path for primitive types
-        let result = match self.sty {
-            TyBool | TyChar | TyInt(..) | TyUint(..) | TyFloat(..) | TyNever |
-            TyRawPtr(..) | TyFnDef(..) | TyFnPtr(_) | TyRef(_, TypeAndMut {
-                mutbl: hir::MutImmutable, ..
-            }) => Some(false),
-
-            TyStr | TyRef(_, TypeAndMut {
-                mutbl: hir::MutMutable, ..
-            }) => Some(true),
-
-            TyArray(..) | TySlice(..) | TyDynamic(..) | TyTuple(..) |
-            TyClosure(..) | TyAdt(..) | TyAnon(..) |
-            TyProjection(..) | TyParam(..) | TyInfer(..) | TyError => None
-        }.unwrap_or_else(|| {
-            !self.impls_bound(tcx, param_env,
-                              tcx.require_lang_item(lang_items::CopyTraitLangItem),
-                              &param_env.is_copy_cache, span) });
-
-        if !self.has_param_types() && !self.has_self_ty() {
-            self.flags.set(self.flags.get() | if result {
-                TypeFlags::MOVENESS_CACHED | TypeFlags::MOVES_BY_DEFAULT
-            } else {
-                TypeFlags::MOVENESS_CACHED
-            });
-        }
-
-        result
+    pub fn moves_by_default(&'tcx self,
+                            tcx: TyCtxt<'a, 'tcx, 'tcx>,
+                            param_env: ty::ParamEnv<'tcx>,
+                            span: Span)
+                            -> bool {
+        !tcx.at(span).is_copy_raw(param_env.and(self))
     }
 
-    #[inline]
-    pub fn is_sized(&'tcx self, tcx: TyCtxt<'a, 'tcx, 'tcx>,
-                    param_env: &ParameterEnvironment<'tcx>,
-                    span: Span) -> bool
+    pub fn is_sized(&'tcx self,
+                    tcx: TyCtxt<'a, 'tcx, 'tcx>,
+                    param_env: ty::ParamEnv<'tcx>,
+                    span: Span)-> bool
     {
-        if self.flags.get().intersects(TypeFlags::SIZEDNESS_CACHED) {
-            return self.flags.get().intersects(TypeFlags::IS_SIZED);
-        }
-
-        self.is_sized_uncached(tcx, param_env, span)
-    }
-
-    fn is_sized_uncached(&'tcx self, tcx: TyCtxt<'a, 'tcx, 'tcx>,
-                         param_env: &ParameterEnvironment<'tcx>,
-                         span: Span) -> bool {
-        assert!(!self.needs_infer());
-
-        // Fast-path for primitive types
-        let result = match self.sty {
-            TyBool | TyChar | TyInt(..) | TyUint(..) | TyFloat(..) |
-            TyRawPtr(..) | TyRef(..) | TyFnDef(..) | TyFnPtr(_) |
-            TyArray(..) | TyTuple(..) | TyClosure(..) | TyNever => Some(true),
-
-            TyStr | TyDynamic(..) | TySlice(_) => Some(false),
-
-            TyAdt(..) | TyProjection(..) | TyParam(..) |
-            TyInfer(..) | TyAnon(..) | TyError => None
-        }.unwrap_or_else(|| {
-            self.impls_bound(tcx, param_env, tcx.require_lang_item(lang_items::SizedTraitLangItem),
-                              &param_env.is_sized_cache, span) });
-
-        if !self.has_param_types() && !self.has_self_ty() {
-            self.flags.set(self.flags.get() | if result {
-                TypeFlags::SIZEDNESS_CACHED | TypeFlags::IS_SIZED
-            } else {
-                TypeFlags::SIZEDNESS_CACHED
-            });
-        }
-
-        result
+        tcx.at(span).is_sized_raw(param_env.and(self))
     }
 
-    /// Returns `true` if and only if there are no `UnsafeCell`s
-    /// nested within the type (ignoring `PhantomData` or pointers).
-    #[inline]
-    pub fn is_freeze(&'tcx self, tcx: TyCtxt<'a, 'tcx, 'tcx>,
-                     param_env: &ParameterEnvironment<'tcx>,
-                     span: Span) -> bool
+    pub fn is_freeze(&'tcx self,
+                     tcx: TyCtxt<'a, 'tcx, 'tcx>,
+                     param_env: ty::ParamEnv<'tcx>,
+                     span: Span)-> bool
     {
-        if self.flags.get().intersects(TypeFlags::FREEZENESS_CACHED) {
-            return self.flags.get().intersects(TypeFlags::IS_FREEZE);
-        }
-
-        self.is_freeze_uncached(tcx, param_env, span)
-    }
-
-    fn is_freeze_uncached(&'tcx self, tcx: TyCtxt<'a, 'tcx, 'tcx>,
-                          param_env: &ParameterEnvironment<'tcx>,
-                          span: Span) -> bool {
-        assert!(!self.needs_infer());
-
-        // Fast-path for primitive types
-        let result = match self.sty {
-            TyBool | TyChar | TyInt(..) | TyUint(..) | TyFloat(..) |
-            TyRawPtr(..) | TyRef(..) | TyFnDef(..) | TyFnPtr(_) |
-            TyStr | TyNever => Some(true),
-
-            TyArray(..) | TySlice(_) |
-            TyTuple(..) | TyClosure(..) | TyAdt(..) |
-            TyDynamic(..) | TyProjection(..) | TyParam(..) |
-            TyInfer(..) | TyAnon(..) | TyError => None
-        }.unwrap_or_else(|| {
-            self.impls_bound(tcx, param_env, tcx.require_lang_item(lang_items::FreezeTraitLangItem),
-                              &param_env.is_freeze_cache, span) });
-
-        if !self.has_param_types() && !self.has_self_ty() {
-            self.flags.set(self.flags.get() | if result {
-                TypeFlags::FREEZENESS_CACHED | TypeFlags::IS_FREEZE
-            } else {
-                TypeFlags::FREEZENESS_CACHED
-            });
-        }
-
-        result
+        tcx.at(span).is_freeze_raw(param_env.and(self))
     }
 
     /// If `ty.needs_drop(...)` returns `true`, then `ty` is definitely
@@ -866,112 +748,11 @@ fn is_freeze_uncached(&'tcx self, tcx: TyCtxt<'a, 'tcx, 'tcx>,
     /// (Note that this implies that if `ty` has a destructor attached,
     /// then `needs_drop` will definitely return `true` for `ty`.)
     #[inline]
-    pub fn needs_drop(&'tcx self, tcx: TyCtxt<'a, 'tcx, 'tcx>,
-                    param_env: &ty::ParameterEnvironment<'tcx>) -> bool {
-        if self.flags.get().intersects(TypeFlags::NEEDS_DROP_CACHED) {
-            return self.flags.get().intersects(TypeFlags::NEEDS_DROP);
-        }
-
-        self.needs_drop_uncached(tcx, param_env, &mut FxHashSet())
-    }
-
-    fn needs_drop_inner(&'tcx self,
-                        tcx: TyCtxt<'a, 'tcx, 'tcx>,
-                        param_env: &ty::ParameterEnvironment<'tcx>,
-                        stack: &mut FxHashSet<Ty<'tcx>>)
-                        -> bool {
-        if self.flags.get().intersects(TypeFlags::NEEDS_DROP_CACHED) {
-            return self.flags.get().intersects(TypeFlags::NEEDS_DROP);
-        }
-
-        // This should be reported as an error by `check_representable`.
-        //
-        // Consider the type as not needing drop in the meanwhile to avoid
-        // further errors.
-        if let Some(_) = stack.replace(self) {
-            return false;
-        }
-
-        let needs_drop = self.needs_drop_uncached(tcx, param_env, stack);
-
-        // "Pop" the cycle detection "stack".
-        stack.remove(self);
-
-        needs_drop
-    }
-
-    fn needs_drop_uncached(&'tcx self,
-                           tcx: TyCtxt<'a, 'tcx, 'tcx>,
-                           param_env: &ty::ParameterEnvironment<'tcx>,
-                           stack: &mut FxHashSet<Ty<'tcx>>)
-                           -> bool {
-        assert!(!self.needs_infer());
-
-        let result = match self.sty {
-            // Fast-path for primitive types
-            ty::TyInfer(ty::FreshIntTy(_)) | ty::TyInfer(ty::FreshFloatTy(_)) |
-            ty::TyBool | ty::TyInt(_) | ty::TyUint(_) | ty::TyFloat(_) | ty::TyNever |
-            ty::TyFnDef(..) | ty::TyFnPtr(_) | ty::TyChar |
-            ty::TyRawPtr(_) | ty::TyRef(..) | ty::TyStr => false,
-
-            // Issue #22536: We first query type_moves_by_default.  It sees a
-            // normalized version of the type, and therefore will definitely
-            // know whether the type implements Copy (and thus needs no
-            // cleanup/drop/zeroing) ...
-            _ if !self.moves_by_default(tcx, param_env, DUMMY_SP) => false,
-
-            // ... (issue #22536 continued) but as an optimization, still use
-            // prior logic of asking for the structural "may drop".
-
-            // FIXME(#22815): Note that this is a conservative heuristic;
-            // it may report that the type "may drop" when actual type does
-            // not actually have a destructor associated with it. But since
-            // the type absolutely did not have the `Copy` bound attached
-            // (see above), it is sound to treat it as having a destructor.
-
-            // User destructors are the only way to have concrete drop types.
-            ty::TyAdt(def, _) if def.has_dtor(tcx) => true,
-
-            // Can refer to a type which may drop.
-            // FIXME(eddyb) check this against a ParameterEnvironment.
-            ty::TyDynamic(..) | ty::TyProjection(..) | ty::TyParam(_) |
-            ty::TyAnon(..) | ty::TyInfer(_) | ty::TyError => true,
-
-            // Structural recursion.
-            ty::TyArray(ty, _) | ty::TySlice(ty) => {
-                ty.needs_drop_inner(tcx, param_env, stack)
-            }
-
-            ty::TyClosure(def_id, ref substs) => {
-                substs.upvar_tys(def_id, tcx)
-                    .any(|ty| ty.needs_drop_inner(tcx, param_env, stack))
-            }
-
-            ty::TyTuple(ref tys, _) => {
-                tys.iter().any(|ty| ty.needs_drop_inner(tcx, param_env, stack))
-            }
-
-            // unions don't have destructors regardless of the child types
-            ty::TyAdt(def, _) if def.is_union() => false,
-
-            ty::TyAdt(def, substs) => {
-                def.variants.iter().any(|v| {
-                    v.fields.iter().any(|f| {
-                        f.ty(tcx, substs).needs_drop_inner(tcx, param_env, stack)
-                    })
-                })
-            }
-        };
-
-        if !self.has_param_types() && !self.has_self_ty() {
-            self.flags.set(self.flags.get() | if result {
-                TypeFlags::NEEDS_DROP_CACHED | TypeFlags::NEEDS_DROP
-            } else {
-                TypeFlags::NEEDS_DROP_CACHED
-            });
-        }
-
-        result
+    pub fn needs_drop(&'tcx self,
+                      tcx: TyCtxt<'a, 'tcx, 'tcx>,
+                      param_env: ty::ParamEnv<'tcx>)
+                      -> bool {
+        tcx.needs_drop_raw(param_env.and(self))
     }
 
     #[inline]
@@ -1158,3 +939,112 @@ fn is_type_structurally_recursive<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
         r
     }
 }
+
+fn is_copy_raw<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
+                         query: ty::ParamEnvAnd<'tcx, Ty<'tcx>>)
+                         -> bool
+{
+    let (param_env, ty) = query.into_parts();
+    let trait_def_id = tcx.require_lang_item(lang_items::CopyTraitLangItem);
+    tcx.infer_ctxt(param_env, Reveal::UserFacing)
+       .enter(|infcx| traits::type_known_to_meet_bound(&infcx, ty, trait_def_id, DUMMY_SP))
+}
+
+fn is_sized_raw<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
+                          query: ty::ParamEnvAnd<'tcx, Ty<'tcx>>)
+                          -> bool
+{
+    let (param_env, ty) = query.into_parts();
+    let trait_def_id = tcx.require_lang_item(lang_items::SizedTraitLangItem);
+    tcx.infer_ctxt(param_env, Reveal::UserFacing)
+       .enter(|infcx| traits::type_known_to_meet_bound(&infcx, ty, trait_def_id, DUMMY_SP))
+}
+
+fn is_freeze_raw<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
+                           query: ty::ParamEnvAnd<'tcx, Ty<'tcx>>)
+                           -> bool
+{
+    let (param_env, ty) = query.into_parts();
+    let trait_def_id = tcx.require_lang_item(lang_items::FreezeTraitLangItem);
+    tcx.infer_ctxt(param_env, Reveal::UserFacing)
+       .enter(|infcx| traits::type_known_to_meet_bound(&infcx, ty, trait_def_id, DUMMY_SP))
+}
+
+fn needs_drop_raw<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
+                            query: ty::ParamEnvAnd<'tcx, Ty<'tcx>>)
+                            -> bool
+{
+    let (param_env, ty) = query.into_parts();
+
+    let needs_drop = |ty: Ty<'tcx>| -> bool {
+        match ty::queries::needs_drop_raw::try_get(tcx, DUMMY_SP, param_env.and(ty)) {
+            Ok(v) => v,
+            Err(_) => {
+                // Cycles should be reported as an error by `check_representable`.
+                //
+                // Consider the type as not needing drop in the meanwhile to avoid
+                // further errors.
+                false
+            }
+        }
+    };
+
+    assert!(!ty.needs_infer());
+
+    match ty.sty {
+        // Fast-path for primitive types
+        ty::TyInfer(ty::FreshIntTy(_)) | ty::TyInfer(ty::FreshFloatTy(_)) |
+        ty::TyBool | ty::TyInt(_) | ty::TyUint(_) | ty::TyFloat(_) | ty::TyNever |
+        ty::TyFnDef(..) | ty::TyFnPtr(_) | ty::TyChar |
+        ty::TyRawPtr(_) | ty::TyRef(..) | ty::TyStr => false,
+
+        // Issue #22536: We first query type_moves_by_default.  It sees a
+        // normalized version of the type, and therefore will definitely
+        // know whether the type implements Copy (and thus needs no
+        // cleanup/drop/zeroing) ...
+        _ if !ty.moves_by_default(tcx, param_env, DUMMY_SP) => false,
+
+        // ... (issue #22536 continued) but as an optimization, still use
+        // prior logic of asking for the structural "may drop".
+
+        // FIXME(#22815): Note that this is a conservative heuristic;
+        // it may report that the type "may drop" when actual type does
+        // not actually have a destructor associated with it. But since
+        // the type absolutely did not have the `Copy` bound attached
+        // (see above), it is sound to treat it as having a destructor.
+
+        // User destructors are the only way to have concrete drop types.
+        ty::TyAdt(def, _) if def.has_dtor(tcx) => true,
+
+        // Can refer to a type which may drop.
+        // FIXME(eddyb) check this against a ParamEnv.
+        ty::TyDynamic(..) | ty::TyProjection(..) | ty::TyParam(_) |
+        ty::TyAnon(..) | ty::TyInfer(_) | ty::TyError => true,
+
+        // Structural recursion.
+        ty::TyArray(ty, _) | ty::TySlice(ty) => needs_drop(ty),
+
+        ty::TyClosure(def_id, ref substs) => substs.upvar_tys(def_id, tcx).any(needs_drop),
+
+        ty::TyTuple(ref tys, _) => tys.iter().cloned().any(needs_drop),
+
+        // unions don't have destructors regardless of the child types
+        ty::TyAdt(def, _) if def.is_union() => false,
+
+        ty::TyAdt(def, substs) =>
+            def.variants.iter().any(
+                |variant| variant.fields.iter().any(
+                    |field| needs_drop(field.ty(tcx, substs)))),
+    }
+}
+
+
+pub fn provide(providers: &mut ty::maps::Providers) {
+    *providers = ty::maps::Providers {
+        is_copy_raw,
+        is_sized_raw,
+        is_freeze_raw,
+        needs_drop_raw,
+        ..*providers
+    };
+}
index 8ca699339d36ecedca7a92a3e785b51fffb248bf..340e4f2cfccbcdba96cacd9f1e35f786fcfad6e3 100644 (file)
@@ -504,13 +504,7 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
     }
 }
 
-impl<'tcx> fmt::Debug for ty::ParameterEnvironment<'tcx> {
-    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        write!(f, "ParameterEnvironment({:?})", self.caller_bounds)
-    }
-}
-
-impl<'tcx> fmt::Display for ty::RegionKind {
+impl fmt::Display for ty::RegionKind {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         if verbose() {
             return write!(f, "{:?}", *self);
index eeb5a3fb957fa481f7a2ad4dc15f80b77f529950..722ec6424fecec3dc9c0393b1df4989b022e16f2 100644 (file)
@@ -90,7 +90,7 @@ struct CheckLoanCtxt<'a, 'tcx: 'a> {
     dfcx_loans: &'a LoanDataFlow<'a, 'tcx>,
     move_data: &'a move_data::FlowedMoveData<'a, 'tcx>,
     all_loans: &'a [Loan<'tcx>],
-    param_env: &'a ty::ParameterEnvironment<'tcx>,
+    param_env: &'a ty::ParamEnv<'tcx>,
 }
 
 impl<'a, 'tcx> euv::Delegate<'tcx> for CheckLoanCtxt<'a, 'tcx> {
@@ -197,7 +197,7 @@ pub fn check_loans<'a, 'b, 'c, 'tcx>(bccx: &BorrowckCtxt<'a, 'tcx>,
         dfcx_loans: dfcx_loans,
         move_data: move_data,
         all_loans: all_loans,
-        param_env: &infcx.parameter_environment
+        param_env: &infcx.param_env
     };
     euv::ExprUseVisitor::new(&mut clcx, &bccx.region_maps, &infcx).consume_body(body);
 }
index 520a90d940b3912d292448891e569244063cefef..e0d86ff23f8621a6aae97415ee2919e2990055f8 100644 (file)
@@ -44,8 +44,8 @@ fn run_pass<'a, 'tcx>(&self,
             _ => return
         }
         let id = src.item_id();
-        let param_env = tcx.parameter_environment(tcx.hir.local_def_id(id));
-        let move_data = MoveData::gather_moves(mir, tcx, &param_env);
+        let param_env = tcx.param_env(tcx.hir.local_def_id(id));
+        let move_data = MoveData::gather_moves(mir, tcx, param_env);
         let elaborate_patch = {
             let mir = &*mir;
             let env = MoveDataParamEnv {
@@ -196,7 +196,7 @@ fn tcx(&self) -> ty::TyCtxt<'a, 'tcx, 'tcx> {
         self.ctxt.tcx
     }
 
-    fn param_env(&self) -> &'a ty::ParameterEnvironment<'tcx> {
+    fn param_env(&self) -> ty::ParamEnv<'tcx> {
         self.ctxt.param_env()
     }
 
@@ -289,8 +289,9 @@ struct ElaborateDropsCtxt<'a, 'tcx: 'a> {
 
 impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> {
     fn move_data(&self) -> &'b MoveData<'tcx> { &self.env.move_data }
-    fn param_env(&self) -> &'b ty::ParameterEnvironment<'tcx> {
-        &self.env.param_env
+
+    fn param_env(&self) -> ty::ParamEnv<'tcx> {
+        self.env.param_env
     }
 
     fn initialization_data_at(&self, loc: Location) -> InitializationData {
index ed5e539f245f10fb2280d4821e8bf39f38166796..931cdf4f6861208d048fad342af8256c502ae442 100644 (file)
@@ -9,7 +9,7 @@
 // except according to those terms.
 
 
-use rustc::ty::{self, TyCtxt, ParameterEnvironment};
+use rustc::ty::{self, TyCtxt};
 use rustc::mir::*;
 use rustc::util::nodemap::FxHashMap;
 use rustc_data_structures::indexed_vec::{IndexVec};
@@ -191,7 +191,7 @@ pub struct MovePathLookup<'tcx> {
 struct MoveDataBuilder<'a, 'tcx: 'a> {
     mir: &'a Mir<'tcx>,
     tcx: TyCtxt<'a, 'tcx, 'tcx>,
-    param_env: &'a ParameterEnvironment<'tcx>,
+    param_env: ty::ParamEnv<'tcx>,
     data: MoveData<'tcx>,
 }
 
@@ -203,7 +203,7 @@ pub enum MovePathError {
 impl<'a, 'tcx> MoveDataBuilder<'a, 'tcx> {
     fn new(mir: &'a Mir<'tcx>,
            tcx: TyCtxt<'a, 'tcx, 'tcx>,
-           param_env: &'a ParameterEnvironment<'tcx>)
+           param_env: ty::ParamEnv<'tcx>)
            -> Self {
         let mut move_paths = IndexVec::new();
         let mut path_map = IndexVec::new();
@@ -370,7 +370,7 @@ pub fn find(&self, lval: &Lvalue<'tcx>) -> LookupResult {
 impl<'a, 'tcx> MoveData<'tcx> {
     pub fn gather_moves(mir: &Mir<'tcx>,
                         tcx: TyCtxt<'a, 'tcx, 'tcx>,
-                        param_env: &ParameterEnvironment<'tcx>)
+                        param_env: ty::ParamEnv<'tcx>)
                         -> Self {
         gather_moves(mir, tcx, param_env)
     }
@@ -378,7 +378,7 @@ pub fn gather_moves(mir: &Mir<'tcx>,
 
 fn gather_moves<'a, 'tcx>(mir: &Mir<'tcx>,
                           tcx: TyCtxt<'a, 'tcx, 'tcx>,
-                          param_env: &ParameterEnvironment<'tcx>)
+                          param_env: ty::ParamEnv<'tcx>)
                           -> MoveData<'tcx> {
     let mut builder = MoveDataBuilder::new(mir, tcx, param_env);
 
index fbaa60f84450b26f4596bb99728af967f47344ba..2eb064305e87c0626999e4951acf956089148332 100644 (file)
@@ -51,7 +51,7 @@ fn has_rustc_mir_with(attrs: &[ast::Attribute], name: &str) -> Option<MetaItem>
 
 pub struct MoveDataParamEnv<'tcx> {
     move_data: MoveData<'tcx>,
-    param_env: ty::ParameterEnvironment<'tcx>,
+    param_env: ty::ParamEnv<'tcx>,
 }
 
 pub fn borrowck_mir(bcx: &mut BorrowckCtxt,
@@ -65,8 +65,8 @@ pub fn borrowck_mir(bcx: &mut BorrowckCtxt,
     // steals it, but it forces the `borrowck` query.
     let mir = &tcx.mir_validated(def_id).borrow();
 
-    let param_env = tcx.parameter_environment(def_id);
-    let move_data = MoveData::gather_moves(mir, tcx, &param_env);
+    let param_env = tcx.param_env(def_id);
+    let move_data = MoveData::gather_moves(mir, tcx, param_env);
     let mdpe = MoveDataParamEnv { move_data: move_data, param_env: param_env };
     let dead_unwinds = IdxSetBuf::new_empty(mir.basic_blocks().len());
     let flow_inits =
@@ -325,7 +325,7 @@ fn on_all_drop_children_bits<'a, 'tcx, F>(
         let ty = lvalue.ty(mir, tcx).to_ty(tcx);
         debug!("on_all_drop_children_bits({:?}, {:?} : {:?})", path, lvalue, ty);
 
-        if ty.needs_drop(tcx, &ctxt.param_env) {
+        if ty.needs_drop(tcx, ctxt.param_env) {
             each_child(child);
         } else {
             debug!("on_all_drop_children_bits - skipping")
@@ -359,7 +359,7 @@ fn drop_flag_effects_for_location<'a, 'tcx, F>(
     where F: FnMut(MovePathIndex, DropFlagState)
 {
     let move_data = &ctxt.move_data;
-    let param_env = &ctxt.param_env;
+    let param_env = ctxt.param_env;
     debug!("drop_flag_effects_for_location({:?})", loc);
 
     // first, move out of the RHS
index c28d45be18d9e754ec9cdd7a93b20064f22de517..f7c20542cbf2e98c685bd4b56166d7efb22e2529 100644 (file)
@@ -535,7 +535,7 @@ pub fn report_use_of_moved_value(&self,
                                      lp: &LoanPath<'tcx>,
                                      the_move: &move_data::Move,
                                      moved_lp: &LoanPath<'tcx>,
-                                     _param_env: &ty::ParameterEnvironment<'tcx>) {
+                                     _param_env: &ty::ParamEnv<'tcx>) {
         let (verb, verb_participle) = match use_kind {
             MovedInUse => ("use", "used"),
             MovedInCapture => ("capture", "captured"),
index a18f91a9ee391408f069981f119d09ead357e618..7ed5f620816e11d5cca9c3ddf10fdabf3fdcb47c 100644 (file)
@@ -52,7 +52,7 @@ fn visit_fn(&mut self, fk: FnKind<'tcx>, fd: &'tcx hir::FnDecl,
             tcx: self.tcx,
             tables: self.tcx.body_tables(b),
             region_maps: &self.tcx.region_maps(def_id),
-            param_env: &self.tcx.parameter_environment(def_id)
+            param_env: self.tcx.param_env(def_id)
         }.visit_body(self.tcx.hir.body(b));
     }
 }
@@ -69,7 +69,7 @@ fn create_e0004<'a>(sess: &'a Session, sp: Span, error_message: String) -> Diagn
 struct MatchVisitor<'a, 'tcx: 'a> {
     tcx: TyCtxt<'a, 'tcx, 'tcx>,
     tables: &'a ty::TypeckTables<'tcx>,
-    param_env: &'a ty::ParameterEnvironment<'tcx>,
+    param_env: ty::ParamEnv<'tcx>,
     region_maps: &'a RegionMaps,
 }
 
@@ -518,7 +518,7 @@ fn check_legality_of_move_bindings(cx: &MatchVisitor,
 ///
 /// FIXME: this should be done by borrowck.
 fn check_for_mutation_in_guard(cx: &MatchVisitor, guard: &hir::Expr) {
-    cx.tcx.infer_ctxt((cx.tables, cx.param_env.clone()), Reveal::UserFacing).enter(|infcx| {
+    cx.tcx.infer_ctxt((cx.tables, cx.param_env), Reveal::UserFacing).enter(|infcx| {
         let mut checker = MutationChecker {
             cx: cx,
         };
index 18a57f78a503719e7bcc48fb26362977f8a79bcd..c5f89e861fa131b759ba227ad2b4ac448143783a 100644 (file)
@@ -23,7 +23,6 @@
 #![deny(warnings)]
 
 #![feature(box_syntax)]
-#![feature(loop_break_value)]
 #![feature(libc)]
 #![feature(quote)]
 #![feature(rustc_diagnostic_macros)]
@@ -32,6 +31,7 @@
 #![cfg_attr(stage0, unstable(feature = "rustc_private", issue = "27812"))]
 #![cfg_attr(stage0, feature(rustc_private))]
 #![cfg_attr(stage0, feature(staged_api))]
+#![cfg_attr(stage0, feature(loop_break_value))]
 
 extern crate arena;
 extern crate getopts;
 fn abort_msg(err_count: usize) -> String {
     match err_count {
         0 => "aborting with no errors (maybe a bug?)".to_owned(),
-        1 => "aborting due to previous error".to_owned(),
-        e => format!("aborting due to {} previous errors", e),
+        _ => "aborting due to previous error(s)".to_owned(),
     }
 }
 
index c91dc9d87978dedb3c1011792010971c70ab0e29..f7191e49216375c6e21da99d2a94d2805f8c00cc 100644 (file)
@@ -501,10 +501,7 @@ pub fn abort_if_errors(&self) {
 
                 return;
             }
-            1 => s = "aborting due to previous error".to_string(),
-            _ => {
-                s = format!("aborting due to {} previous errors", self.err_count.get());
-            }
+            _ => s = "aborting due to previous error(s)".to_string(),
         }
 
         panic!(self.fatal(&s));
index 6423d65a4c23fc7175ee598ef365ae7ed90c3ce1..39b8e568ab48d959f5a1e1a5a573c7b0a3b59a36 100644 (file)
@@ -527,13 +527,11 @@ fn check_item(&mut self, cx: &LateContext, item: &hir::Item) {
         if def.has_dtor(cx.tcx) {
             return;
         }
-        let parameter_environment = cx.tcx.empty_parameter_environment();
-        // FIXME (@jroesch) should probably inver this so that the parameter env still impls this
-        // method
-        if !ty.moves_by_default(cx.tcx, &parameter_environment, item.span) {
+        let param_env = ty::ParamEnv::empty();
+        if !ty.moves_by_default(cx.tcx, param_env, item.span) {
             return;
         }
-        if parameter_environment.can_type_implement_copy(cx.tcx, ty, item.span).is_ok() {
+        if param_env.can_type_implement_copy(cx.tcx, ty, item.span).is_ok() {
             cx.span_lint(MISSING_COPY_IMPLEMENTATIONS,
                          item.span,
                          "type could implement `Copy`; consider adding `impl \
@@ -990,7 +988,7 @@ fn method_call_refers_to_method<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                         traits::Obligation::new(traits::ObligationCause::misc(span, expr_id),
                                                 trait_ref.to_poly_trait_predicate());
 
-                    let param_env = tcx.parameter_environment(method.def_id);
+                    let param_env = tcx.param_env(method.def_id);
                     tcx.infer_ctxt(param_env, Reveal::UserFacing).enter(|infcx| {
                         let mut selcx = traits::SelectionContext::new(&infcx);
                         match selcx.select(&obligation) {
@@ -1258,7 +1256,8 @@ fn get_lints(&self) -> LintArray {
 impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnionsWithDropFields {
     fn check_item(&mut self, ctx: &LateContext, item: &hir::Item) {
         if let hir::ItemUnion(ref vdata, _) = item.node {
-            let param_env = &ctx.tcx.parameter_environment(ctx.tcx.hir.local_def_id(item.id));
+            let item_def_id = ctx.tcx.hir.local_def_id(item.id);
+            let param_env = ctx.tcx.param_env(item_def_id);
             for field in vdata.fields() {
                 let field_ty = ctx.tcx.type_of(ctx.tcx.hir.local_def_id(field.id));
                 if field_ty.needs_drop(ctx.tcx, param_env) {
index a368021443292b36a844039ab75b37333721c6c5..5178963179d6f80d1bf90e33e6c244ddfcc6bb00 100644 (file)
@@ -27,8 +27,8 @@ pub fn as_local_operand<M>(&mut self, block: BasicBlock, expr: M)
                              -> BlockAnd<Operand<'tcx>>
         where M: Mirror<'tcx, Output = Expr<'tcx>>
     {
-        let topmost_scope = self.topmost_scope(); // FIXME(#6393)
-        self.as_operand(block, Some(topmost_scope), expr)
+        let local_scope = self.local_scope();
+        self.as_operand(block, local_scope, expr)
     }
 
     /// Compile `expr` into a value that can be used as an operand.
index 7b29cd970d7d4447c852d0feaa39542afc77d0a6..e1832e0a0af347614978ad0db3a66db2a330d707 100644 (file)
@@ -33,8 +33,8 @@ pub fn as_local_rvalue<M>(&mut self, block: BasicBlock, expr: M)
                              -> BlockAnd<Rvalue<'tcx>>
         where M: Mirror<'tcx, Output = Expr<'tcx>>
     {
-        let topmost_scope = self.topmost_scope(); // FIXME(#6393)
-        self.as_rvalue(block, Some(topmost_scope), expr)
+        let local_scope = self.local_scope();
+        self.as_rvalue(block, local_scope, expr)
     }
 
     /// Compile `expr`, yielding an rvalue.
@@ -51,7 +51,7 @@ fn expr_as_rvalue(&mut self,
                       scope: Option<CodeExtent>,
                       expr: Expr<'tcx>)
                       -> BlockAnd<Rvalue<'tcx>> {
-        debug!("expr_as_rvalue(block={:?}, expr={:?})", block, expr);
+        debug!("expr_as_rvalue(block={:?}, scope={:?}, expr={:?})", block, scope, expr);
 
         let this = self;
         let expr_span = expr.span;
index a334923546fb2df76a8c4ccb73cd242bf11ae6ab..ab27a1a9c24bc2a92c5bfea8e22d56348cd37b77 100644 (file)
@@ -35,7 +35,8 @@ fn expr_as_temp(&mut self,
                     temp_lifetime: Option<CodeExtent>,
                     expr: Expr<'tcx>)
                     -> BlockAnd<Lvalue<'tcx>> {
-        debug!("expr_as_temp(block={:?}, expr={:?})", block, expr);
+        debug!("expr_as_temp(block={:?}, temp_lifetime={:?}, expr={:?})",
+               block, temp_lifetime, expr);
         let this = self;
 
         if let ExprKind::Scope { extent, value } = expr.kind {
index fb173e2487bff0c5091fb68566f4a5975f16b9f3..407b08d2831497b3456a2fdf0a7f9795c2f9d348 100644 (file)
@@ -172,7 +172,7 @@ fn create_constructor_shim<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
 {
     let span = tcx.hir.span(ctor_id);
     if let hir::VariantData::Tuple(ref fields, ctor_id) = *v {
-        let pe = tcx.parameter_environment(tcx.hir.local_def_id(ctor_id));
+        let pe = tcx.param_env(tcx.hir.local_def_id(ctor_id));
         tcx.infer_ctxt(pe, Reveal::UserFacing).enter(|infcx| {
             let (mut mir, src) =
                 shim::build_adt_ctor(&infcx, ctor_id, fields, span);
@@ -392,9 +392,9 @@ fn construct_fn<'a, 'gcx, 'tcx, A>(hir: Cx<'a, 'gcx, 'tcx>,
     mir
 }
 
-pub fn construct_const<'a, 'gcx, 'tcx>(hir: Cx<'a, 'gcx, 'tcx>,
-                                       body_id: hir::BodyId)
-                                       -> Mir<'tcx> {
+fn construct_const<'a, 'gcx, 'tcx>(hir: Cx<'a, 'gcx, 'tcx>,
+                                   body_id: hir::BodyId)
+                                   -> Mir<'tcx> {
     let tcx = hir.tcx();
     let ast_expr = &tcx.hir.body(body_id).value;
     let ty = hir.tables().expr_ty_adjusted(ast_expr);
@@ -415,7 +415,7 @@ pub fn construct_const<'a, 'gcx, 'tcx>(hir: Cx<'a, 'gcx, 'tcx>,
     builder.finish(vec![], ty)
 }
 
-pub fn construct_error<'a, 'gcx, 'tcx>(hir: Cx<'a, 'gcx, 'tcx>,
+fn construct_error<'a, 'gcx, 'tcx>(hir: Cx<'a, 'gcx, 'tcx>,
                                        body_id: hir::BodyId)
                                        -> Mir<'tcx> {
     let span = hir.tcx().hir.span(hir.tcx().hir.body_owner(body_id));
index ae47f4c42442041fe47241444d4c796fb5a91c39..a99e7b4be5768b81c9a5c06851b3dc20ed28c104 100644 (file)
@@ -93,6 +93,7 @@
 use rustc::ty::subst::{Kind, Subst};
 use rustc::ty::{Ty, TyCtxt};
 use rustc::mir::*;
+use rustc::mir::transform::MirSource;
 use syntax_pos::Span;
 use rustc_data_structures::indexed_vec::Idx;
 use rustc_data_structures::fx::FxHashMap;
@@ -428,6 +429,41 @@ pub fn topmost_scope(&self) -> CodeExtent {
         self.scopes.last().expect("topmost_scope: no scopes present").extent
     }
 
+    /// Returns the scope that we should use as the lifetime of an
+    /// operand. Basically, an operand must live until it is consumed.
+    /// This is similar to, but not quite the same as, the temporary
+    /// scope (which can be larger or smaller).
+    ///
+    /// Consider:
+    ///
+    ///     let x = foo(bar(X, Y));
+    ///
+    /// We wish to pop the storage for X and Y after `bar()` is
+    /// called, not after the whole `let` is completed.
+    ///
+    /// As another example, if the second argument diverges:
+    ///
+    ///     foo(Box::new(2), panic!())
+    ///
+    /// We would allocate the box but then free it on the unwinding
+    /// path; we would also emit a free on the 'success' path from
+    /// panic, but that will turn out to be removed as dead-code.
+    ///
+    /// When building statics/constants, returns `None` since
+    /// intermediate values do not have to be dropped in that case.
+    pub fn local_scope(&self) -> Option<CodeExtent> {
+        match self.hir.src {
+            MirSource::Const(_) |
+            MirSource::Static(..) =>
+                // No need to free storage in this context.
+                None,
+            MirSource::Fn(_) =>
+                Some(self.topmost_scope()),
+            MirSource::Promoted(..) =>
+                bug!(),
+        }
+    }
+
     // Scheduling drops
     // ================
     /// Indicates that `lvalue` should be dropped on exit from
index 9ffce18fe150e0c8b52ac54df9164910d5631345..581a403fb6dee848861860711fca541722b9fa5b 100644 (file)
@@ -36,8 +36,14 @@ pub struct Cx<'a, 'gcx: 'a + 'tcx, 'tcx: 'a> {
     tcx: TyCtxt<'a, 'gcx, 'tcx>,
     infcx: &'a InferCtxt<'a, 'gcx, 'tcx>,
     pub region_maps: Rc<RegionMaps>,
+
+    /// This is `Constness::Const` if we are compiling a `static`,
+    /// `const`, or the body of a `const fn`.
     constness: hir::Constness,
 
+    /// What are we compiling?
+    pub src: MirSource,
+
     /// True if this constant/function needs overflow checks.
     check_overflow: bool,
 }
@@ -74,7 +80,7 @@ pub fn new(infcx: &'a InferCtxt<'a, 'gcx, 'tcx>, src: MirSource) -> Cx<'a, 'gcx,
         // Constants and const fn's always need overflow checks.
         check_overflow |= constness == hir::Constness::Const;
 
-        Cx { tcx, infcx, region_maps, constness, check_overflow }
+        Cx { tcx, infcx, region_maps, constness, src, check_overflow }
     }
 }
 
@@ -168,7 +174,7 @@ pub fn needs_drop(&mut self, ty: Ty<'tcx>) -> bool {
                   type with inference types/regions",
                  ty);
         });
-        ty.needs_drop(self.tcx.global_tcx(), &self.infcx.parameter_environment)
+        ty.needs_drop(self.tcx.global_tcx(), self.infcx.param_env)
     }
 
     pub fn tcx(&self) -> TyCtxt<'a, 'gcx, 'tcx> {
index 6f4480bf6dd16d525bdb54dc8ba02a9f66b2ffa7..428685d7f5058cf1dbdaeabb0251eb9096352e3d 100644 (file)
@@ -40,8 +40,6 @@ fn make_shim<'a, 'tcx>(tcx: ty::TyCtxt<'a, 'tcx, 'tcx>,
                        -> &'tcx Mir<'tcx>
 {
     debug!("make_shim({:?})", instance);
-    let did = instance.def_id();
-    let param_env = tcx.parameter_environment(did);
 
     let mut result = match instance {
         ty::InstanceDef::Item(..) =>
@@ -98,7 +96,7 @@ fn make_shim<'a, 'tcx>(tcx: ty::TyCtxt<'a, 'tcx, 'tcx>,
             )
         }
         ty::InstanceDef::DropGlue(def_id, ty) => {
-            build_drop_shim(tcx, &param_env, def_id, ty)
+            build_drop_shim(tcx, def_id, ty)
         }
         ty::InstanceDef::Intrinsic(_) => {
             bug!("creating shims from intrinsics ({:?}) is unsupported", instance)
@@ -144,7 +142,6 @@ fn local_decls_for_sig<'tcx>(sig: &ty::FnSig<'tcx>, span: Span)
 }
 
 fn build_drop_shim<'a, 'tcx>(tcx: ty::TyCtxt<'a, 'tcx, 'tcx>,
-                             param_env: &ty::ParameterEnvironment<'tcx>,
                              def_id: DefId,
                              ty: Option<Ty<'tcx>>)
                              -> Mir<'tcx>
@@ -189,10 +186,12 @@ fn build_drop_shim<'a, 'tcx>(tcx: ty::TyCtxt<'a, 'tcx, 'tcx>,
 
     if let Some(..) = ty {
         let patch = {
+            let param_env = tcx.param_env(def_id);
             let mut elaborator = DropShimElaborator {
                 mir: &mir,
                 patch: MirPatch::new(&mir),
-                tcx, param_env
+                tcx,
+                param_env
             };
             let dropee = Lvalue::Local(Local::new(1+0)).deref();
             let resume_block = elaborator.patch.resume_block();
@@ -218,7 +217,7 @@ pub struct DropShimElaborator<'a, 'tcx: 'a> {
     mir: &'a Mir<'tcx>,
     patch: MirPatch<'tcx>,
     tcx: ty::TyCtxt<'a, 'tcx, 'tcx>,
-    param_env: &'a ty::ParameterEnvironment<'tcx>,
+    param_env: ty::ParamEnv<'tcx>,
 }
 
 impl<'a, 'tcx> fmt::Debug for DropShimElaborator<'a, 'tcx> {
@@ -233,7 +232,7 @@ impl<'a, 'tcx> DropElaborator<'a, 'tcx> for DropShimElaborator<'a, 'tcx> {
     fn patch(&mut self) -> &mut MirPatch<'tcx> { &mut self.patch }
     fn mir(&self) -> &'a Mir<'tcx> { self.mir }
     fn tcx(&self) -> ty::TyCtxt<'a, 'tcx, 'tcx> { self.tcx }
-    fn param_env(&self) -> &'a ty::ParameterEnvironment<'tcx> { self.param_env }
+    fn param_env(&self) -> ty::ParamEnv<'tcx> { self.param_env }
 
     fn drop_style(&self, _path: Self::Path, mode: DropFlagMode) -> DropStyle {
         if let DropFlagMode::Shallow = mode {
index e6d62dc6460726365dc560edb3492f74964f5f44..edb2f44d18e35423afe37ec1bebed8a9bca2f5d8 100644 (file)
@@ -220,7 +220,7 @@ fn should_inline(&self,
         // FIXME: Give a bonus to functions with only a single caller
 
         let def_id = tcx.hir.local_def_id(self.source.item_id());
-        let param_env = tcx.parameter_environment(def_id);
+        let param_env = tcx.param_env(def_id);
 
         let mut first_block = true;
         let mut cost = 0;
@@ -253,7 +253,7 @@ fn should_inline(&self,
                     // a regular goto.
                     let ty = location.ty(&callee_mir, tcx).subst(tcx, callsite.substs);
                     let ty = ty.to_ty(tcx);
-                    if ty.needs_drop(tcx, &param_env) {
+                    if ty.needs_drop(tcx, param_env) {
                         cost += CALL_PENALTY;
                         if let Some(unwind) = unwind {
                             work_list.push(unwind);
@@ -545,7 +545,7 @@ fn make_call_args(&self, args: Vec<Operand<'tcx>>,
     }
 }
 
-fn type_size_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, param_env: ty::ParameterEnvironment<'tcx>,
+fn type_size_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, param_env: ty::ParamEnv<'tcx>,
                           ty: Ty<'tcx>) -> Option<u64> {
     tcx.infer_ctxt(param_env, traits::Reveal::All).enter(|infcx| {
         ty.layout(&infcx).ok().map(|layout| {
index 72edf68f4034c47121332cf54b57d7647115ed56..4e84cbe6fecb130bfd268a39cdfab4c0edc345d2 100644 (file)
@@ -78,7 +78,7 @@ impl<'a, 'tcx> Qualif {
     /// Remove flags which are impossible for the given type.
     fn restrict(&mut self, ty: Ty<'tcx>,
                 tcx: TyCtxt<'a, 'tcx, 'tcx>,
-                param_env: &ty::ParameterEnvironment<'tcx>) {
+                param_env: ty::ParamEnv<'tcx>) {
         if ty.is_freeze(tcx, param_env, DUMMY_SP) {
             *self = *self - Qualif::MUTABLE_INTERIOR;
         }
@@ -128,7 +128,7 @@ struct Qualifier<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
     mir: &'a Mir<'tcx>,
     rpo: ReversePostorder<'a, 'tcx>,
     tcx: TyCtxt<'a, 'gcx, 'tcx>,
-    param_env: ty::ParameterEnvironment<'tcx>,
+    param_env: ty::ParamEnv<'tcx>,
     temp_qualif: IndexVec<Local, Option<Qualif>>,
     return_qualif: Option<Qualif>,
     qualif: Qualif,
@@ -139,7 +139,7 @@ struct Qualifier<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
 
 impl<'a, 'tcx> Qualifier<'a, 'tcx, 'tcx> {
     fn new(tcx: TyCtxt<'a, 'tcx, 'tcx>,
-           param_env: ty::ParameterEnvironment<'tcx>,
+           param_env: ty::ParamEnv<'tcx>,
            def_id: DefId,
            mir: &'a Mir<'tcx>,
            mode: Mode)
@@ -193,7 +193,7 @@ fn add(&mut self, qualif: Qualif) {
     /// Add the given type's qualification to self.qualif.
     fn add_type(&mut self, ty: Ty<'tcx>) {
         self.add(Qualif::MUTABLE_INTERIOR | Qualif::NEEDS_DROP);
-        self.qualif.restrict(ty, self.tcx, &self.param_env);
+        self.qualif.restrict(ty, self.tcx, self.param_env);
     }
 
     /// Within the provided closure, self.qualif will start
@@ -544,7 +544,7 @@ fn visit_lvalue(&mut self,
                                            static, use a constant instead");
                             }
                             let ty = lvalue.ty(this.mir, this.tcx).to_ty(this.tcx);
-                            this.qualif.restrict(ty, this.tcx, &this.param_env);
+                            this.qualif.restrict(ty, this.tcx, this.param_env);
                         }
 
                         ProjectionElem::ConstantIndex {..} |
@@ -937,7 +937,7 @@ fn mir_const_qualif<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
         return Qualif::NOT_CONST.bits();
     }
 
-    let param_env = tcx.parameter_environment(def_id);
+    let param_env = tcx.param_env(def_id);
 
     let mut qualifier = Qualifier::new(tcx, param_env, def_id, mir, Mode::Const);
     qualifier.qualify_const().bits()
@@ -965,7 +965,7 @@ fn run_pass<'a, 'tcx>(&self,
             MirSource::Const(_) |
             MirSource::Promoted(..) => return
         };
-        let param_env = tcx.parameter_environment(def_id);
+        let param_env = tcx.param_env(def_id);
 
         if mode == Mode::Fn || mode == Mode::ConstFn {
             // This is ugly because Qualifier holds onto mir,
index 82c0d2c1b01c6ab3f52f688538c4e87b9d7476f1..6d9603ea459d40941bc1225945f8d55ace1b1eef 100644 (file)
@@ -751,7 +751,7 @@ fn run_pass<'a, 'tcx>(&self,
             // broken MIR, so try not to report duplicate errors.
             return;
         }
-        let param_env = tcx.parameter_environment(def_id);
+        let param_env = tcx.param_env(def_id);
         tcx.infer_ctxt(param_env, Reveal::UserFacing).enter(|infcx| {
             let mut checker = TypeChecker::new(&infcx, item_id);
             {
index 9d7c7ec63cfc57afbc32eccfa5dfb5cee46185c2..585840ce1e509f17df1558be01671169b234710d 100644 (file)
@@ -56,7 +56,7 @@ pub trait DropElaborator<'a, 'tcx: 'a> : fmt::Debug {
     fn patch(&mut self) -> &mut MirPatch<'tcx>;
     fn mir(&self) -> &'a Mir<'tcx>;
     fn tcx(&self) -> ty::TyCtxt<'a, 'tcx, 'tcx>;
-    fn param_env(&self) -> &'a ty::ParameterEnvironment<'tcx>;
+    fn param_env(&self) -> ty::ParamEnv<'tcx>;
 
     fn drop_style(&self, path: Self::Path, mode: DropFlagMode) -> DropStyle;
     fn get_drop_flag(&mut self, path: Self::Path) -> Option<Operand<'tcx>>;
index a0998b1bd1bfb3fd7cd3a54da70b140d3987da0a..25845c5768e8c8629a12efee4bccc4d9894ef8c0 100644 (file)
@@ -58,7 +58,7 @@ struct CheckCrateVisitor<'a, 'tcx: 'a> {
     in_fn: bool,
     promotable: bool,
     mut_rvalue_borrows: NodeSet,
-    param_env: ty::ParameterEnvironment<'tcx>,
+    param_env: ty::ParamEnv<'tcx>,
     tables: &'a ty::TypeckTables<'tcx>,
 }
 
@@ -85,11 +85,11 @@ fn check_const_eval(&self, expr: &'gcx hir::Expr) {
 
     // Adds the worst effect out of all the values of one type.
     fn add_type(&mut self, ty: Ty<'gcx>) {
-        if !ty.is_freeze(self.tcx, &self.param_env, DUMMY_SP) {
+        if !ty.is_freeze(self.tcx, self.param_env, DUMMY_SP) {
             self.promotable = false;
         }
 
-        if ty.needs_drop(self.tcx, &self.param_env) {
+        if ty.needs_drop(self.tcx, self.param_env) {
             self.promotable = false;
         }
     }
@@ -139,7 +139,7 @@ fn visit_nested_body(&mut self, body_id: hir::BodyId) {
         }
 
         let outer_penv = self.tcx.infer_ctxt(body_id, Reveal::UserFacing).enter(|infcx| {
-            let param_env = infcx.parameter_environment.clone();
+            let param_env = infcx.param_env.clone();
             let outer_penv = mem::replace(&mut self.param_env, param_env);
             let region_maps = &self.tcx.region_maps(item_def_id);;
             euv::ExprUseVisitor::new(self, region_maps, &infcx).consume_body(body);
@@ -466,7 +466,7 @@ pub fn check_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
         in_fn: false,
         promotable: false,
         mut_rvalue_borrows: NodeSet(),
-        param_env: tcx.empty_parameter_environment(),
+        param_env: ty::ParamEnv::empty(),
     }.as_deep_visitor());
     tcx.sess.abort_if_errors();
 }
index c2f2c63790a4c64d04ec9e9ca93ffb175364fc24..0dece586c930dabfd39226e4ec8e817161049536 100644 (file)
@@ -79,7 +79,6 @@ pub fn extend(&mut self, stats: Stats) {
 pub struct SharedCrateContext<'a, 'tcx: 'a> {
     exported_symbols: NodeSet,
     tcx: TyCtxt<'a, 'tcx, 'tcx>,
-    empty_param_env: ty::ParameterEnvironment<'tcx>,
     check_overflow: bool,
 
     use_dll_storage_attrs: bool,
@@ -315,7 +314,6 @@ pub fn new(tcx: TyCtxt<'b, 'tcx, 'tcx>,
 
         SharedCrateContext {
             exported_symbols: exported_symbols,
-            empty_param_env: tcx.empty_parameter_environment(),
             tcx: tcx,
             check_overflow: check_overflow,
             use_dll_storage_attrs: use_dll_storage_attrs,
@@ -323,15 +321,15 @@ pub fn new(tcx: TyCtxt<'b, 'tcx, 'tcx>,
     }
 
     pub fn type_needs_drop(&self, ty: Ty<'tcx>) -> bool {
-        ty.needs_drop(self.tcx, &self.empty_param_env)
+        ty.needs_drop(self.tcx, ty::ParamEnv::empty())
     }
 
     pub fn type_is_sized(&self, ty: Ty<'tcx>) -> bool {
-        ty.is_sized(self.tcx, &self.empty_param_env, DUMMY_SP)
+        ty.is_sized(self.tcx, ty::ParamEnv::empty(), DUMMY_SP)
     }
 
     pub fn type_is_freeze(&self, ty: Ty<'tcx>) -> bool {
-        ty.is_freeze(self.tcx, &self.empty_param_env, DUMMY_SP)
+        ty.is_freeze(self.tcx, ty::ParamEnv::empty(), DUMMY_SP)
     }
 
     pub fn exported_symbols<'a>(&'a self) -> &'a NodeSet {
index d9f77e8f04f1ccbfa595b19195f286a8a942b34a..767cf8f48cfeabfc3989661bebb1ad150e7ed358 100644 (file)
@@ -165,10 +165,6 @@ fn compare_predicate_entailment<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
     // Finally we register each of these predicates as an obligation in
     // a fresh FulfillmentCtxt, and invoke select_all_or_error.
 
-    // Create a parameter environment that represents the implementation's
-    // method.
-    let impl_param_env = tcx.parameter_environment(impl_m.def_id);
-
     // Create mapping from impl to skolemized.
     let impl_to_skol_substs = Substs::identity_for_item(tcx, impl_m.def_id);
 
@@ -216,19 +212,18 @@ fn compare_predicate_entailment<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
     // The key step here is to update the caller_bounds's predicates to be
     // the new hybrid bounds we computed.
     let normalize_cause = traits::ObligationCause::misc(impl_m_span, impl_m_node_id);
-    let trait_param_env = impl_param_env.with_caller_bounds(
-        tcx.intern_predicates(&hybrid_preds.predicates));
-    let trait_param_env = traits::normalize_param_env_or_error(tcx,
-                                                               impl_m.def_id,
-                                                               trait_param_env,
-                                                               normalize_cause.clone());
-
-    tcx.infer_ctxt(trait_param_env, Reveal::UserFacing).enter(|infcx| {
+    let param_env = ty::ParamEnv::new(tcx.intern_predicates(&hybrid_preds.predicates));
+    let param_env = traits::normalize_param_env_or_error(tcx,
+                                                         impl_m.def_id,
+                                                         param_env,
+                                                         normalize_cause.clone());
+
+    tcx.infer_ctxt(param_env, Reveal::UserFacing).enter(|infcx| {
         let inh = Inherited::new(infcx, impl_m.def_id);
         let infcx = &inh.infcx;
 
         debug!("compare_impl_method: caller_bounds={:?}",
-               infcx.parameter_environment.caller_bounds);
+               infcx.param_env.caller_bounds);
 
         let mut selcx = traits::SelectionContext::new(&infcx);
 
@@ -350,7 +345,7 @@ fn compare_predicate_entailment<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
             let region_maps = RegionMaps::new();
             let mut free_regions = FreeRegionMap::new();
             free_regions.relate_free_regions_from_predicates(
-                &infcx.parameter_environment.caller_bounds);
+                &infcx.param_env.caller_bounds);
             infcx.resolve_regions_and_report_errors(impl_m.def_id, &region_maps, &free_regions);
         } else {
             let fcx = FnCtxt::new(&inh, impl_m_node_id);
index e029332559635663b46b12b696e9a466aa25dea2..3ed0da05dc2c2f800e8916017a22e047de4e2069 100644 (file)
@@ -79,7 +79,7 @@ fn ensure_drop_params_and_item_params_correspond<'a, 'tcx>(
 
     // check that the impl type can be made to match the trait type.
 
-    let impl_param_env = tcx.parameter_environment(self_type_did);
+    let impl_param_env = tcx.param_env(self_type_did);
     tcx.infer_ctxt(impl_param_env, Reveal::UserFacing).enter(|ref infcx| {
         let tcx = infcx.tcx;
         let mut fulfillment_cx = traits::FulfillmentContext::new();
index c1cf5192877c0d45246e5b003c4d63c1a5a20d9a..9ad72b2a137ea2ea10112bfb7ddb61ed1a0b9f23 100644 (file)
@@ -566,7 +566,7 @@ fn assemble_inherent_candidates_from_param(&mut self,
                                                param_ty: ty::ParamTy) {
         // FIXME -- Do we want to commit to this behavior for param bounds?
 
-        let bounds: Vec<_> = self.parameter_environment
+        let bounds: Vec<_> = self.param_env
             .caller_bounds
             .iter()
             .filter_map(|predicate| {
@@ -893,7 +893,7 @@ fn assemble_where_clause_candidates(&mut self,
         debug!("assemble_where_clause_candidates(trait_def_id={:?})",
                trait_def_id);
 
-        let caller_predicates = self.parameter_environment.caller_bounds.to_vec();
+        let caller_predicates = self.param_env.caller_bounds.to_vec();
         for poly_bound in traits::elaborate_predicates(self.tcx, caller_predicates)
             .filter_map(|p| p.to_opt_poly_trait_ref())
             .filter(|b| b.def_id() == trait_def_id) {
index d304d79bc52c8342b8ce1ad65cf1226f2cfb277a..24a88140cf041014af2370a1c5345beb4404f29d 100644 (file)
@@ -539,7 +539,7 @@ impl<'a, 'gcx, 'tcx> Inherited<'a, 'gcx, 'tcx> {
     pub fn build(tcx: TyCtxt<'a, 'gcx, 'gcx>, def_id: DefId)
                  -> InheritedBuilder<'a, 'gcx, 'tcx> {
         let tables = ty::TypeckTables::empty();
-        let param_env = tcx.parameter_environment(def_id);
+        let param_env = tcx.param_env(def_id);
         InheritedBuilder {
             infcx: tcx.infer_ctxt((tables, param_env), Reveal::UserFacing),
             def_id,
@@ -1561,7 +1561,7 @@ fn get_type_parameter_bounds(&self, _: Span, def_id: DefId)
         let index = generics.type_param_to_index[&def_id.index];
         ty::GenericPredicates {
             parent: None,
-            predicates: self.parameter_environment.caller_bounds.iter().filter(|predicate| {
+            predicates: self.param_env.caller_bounds.iter().filter(|predicate| {
                 match **predicate {
                     ty::Predicate::Trait(ref data) => {
                         data.0.self_ty().is_param(index)
index 754bd288bfaa70c995624c1358dbc3ffcd7e284f..b29bf01ba1996d472aba27ff1226c376583f2645 100644 (file)
@@ -138,7 +138,7 @@ pub fn regionck_item(&self,
         let subject = self.tcx.hir.local_def_id(item_id);
         let mut rcx = RegionCtxt::new(self, RepeatingScope(item_id), item_id, Subject(subject));
         rcx.free_region_map.relate_free_regions_from_predicates(
-            &self.parameter_environment.caller_bounds);
+            &self.param_env.caller_bounds);
         rcx.relate_free_regions(wf_tys, item_id, span);
         rcx.visit_region_obligations(item_id);
         rcx.resolve_regions_and_report_errors();
@@ -158,7 +158,7 @@ pub fn regionck_fn(&self,
         }
 
         rcx.free_region_map.relate_free_regions_from_predicates(
-            &self.parameter_environment.caller_bounds);
+            &self.param_env.caller_bounds);
 
         rcx.resolve_regions_and_report_errors();
 
@@ -1682,7 +1682,7 @@ fn recursive_type_bound(&self, span: Span, ty: Ty<'tcx>) -> VerifyBound<'tcx> {
     fn declared_generic_bounds_from_env(&self, generic: GenericKind<'tcx>)
                                         -> Vec<ty::Region<'tcx>>
     {
-        let param_env = &self.parameter_environment;
+        let param_env = &self.param_env;
 
         // To start, collect bounds from user:
         let mut param_bounds = self.tcx.required_region_bounds(generic.to_ty(self.tcx),
index 556bd618c78cbb22e49b90b503f1daad2577d4a6..ff5599fb1bdbf46c24a1dd0c8474360787035b79 100644 (file)
@@ -105,7 +105,7 @@ fn visit_implementation_of_copy<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
            self_type);
 
     let span = tcx.hir.span(impl_node_id);
-    let param_env = tcx.parameter_environment(impl_did);
+    let param_env = tcx.param_env(impl_did);
     assert!(!self_type.has_escaping_regions());
 
     debug!("visit_implementation_of_copy: self_type={:?} (free)",
@@ -199,7 +199,7 @@ pub fn coerce_unsized_info<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
            target);
 
     let span = tcx.hir.span(impl_node_id);
-    let param_env = tcx.parameter_environment(impl_did);
+    let param_env = tcx.param_env(impl_did);
     assert!(!source.has_escaping_regions());
 
     let err_info = CoerceUnsizedInfo { custom_kind: None };
@@ -387,7 +387,7 @@ pub fn coerce_unsized_info<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
         // Finally, resolve all regions.
         let region_maps = RegionMaps::new();
         let mut free_regions = FreeRegionMap::new();
-        free_regions.relate_free_regions_from_predicates(&infcx.parameter_environment
+        free_regions.relate_free_regions_from_predicates(&infcx.param_env
             .caller_bounds);
         infcx.resolve_regions_and_report_errors(impl_did, &region_maps, &free_regions);
 
index 99ee1cff7fd22ab9c2883eb49ac6346931c71c89..6f2c73b892567f343f174113bc6ee49b29d7029a 100644 (file)
@@ -76,7 +76,6 @@
 #![feature(box_patterns)]
 #![feature(box_syntax)]
 #![feature(conservative_impl_trait)]
-#![feature(loop_break_value)]
 #![feature(never_type)]
 #![feature(quote)]
 #![feature(rustc_diagnostic_macros)]
@@ -84,6 +83,7 @@
 #![cfg_attr(stage0, unstable(feature = "rustc_private", issue = "27812"))]
 #![cfg_attr(stage0, feature(rustc_private))]
 #![cfg_attr(stage0, feature(staged_api))]
+#![cfg_attr(stage0, feature(loop_break_value))]
 
 #[macro_use] extern crate log;
 #[macro_use] extern crate syntax;
index 9dea0e3d83088451b551acc35da723395105e5e4..141efe471af5fe1cdae32198ed4ea7add4d767e7 100644 (file)
 ///
 /// The returned value is `None` if the definition could not be inlined,
 /// and `Some` of a vector of items if it was successfully expanded.
-pub fn try_inline(cx: &DocContext, def: Def, into: Option<ast::Name>)
+pub fn try_inline(cx: &DocContext, def: Def, name: ast::Name)
                   -> Option<Vec<clean::Item>> {
     if def == Def::Err { return None }
     let did = def.def_id();
     if did.is_local() { return None }
-    try_inline_def(cx, def).map(|vec| {
-        vec.into_iter().map(|mut item| {
-            match into {
-                Some(into) if item.name.is_some() => {
-                    item.name = Some(into.clean(cx));
-                }
-                _ => {}
-            }
-            item
-        }).collect()
-    })
-}
-
-fn try_inline_def(cx: &DocContext, def: Def) -> Option<Vec<clean::Item>> {
-    let tcx = cx.tcx;
     let mut ret = Vec::new();
     let inner = match def {
         Def::Trait(did) => {
@@ -112,16 +97,15 @@ fn try_inline_def(cx: &DocContext, def: Def) -> Option<Vec<clean::Item>> {
         }
         _ => return None,
     };
-    let did = def.def_id();
     cx.renderinfo.borrow_mut().inlined.insert(did);
     ret.push(clean::Item {
-        source: tcx.def_span(did).clean(cx),
-        name: Some(tcx.item_name(did).to_string()),
+        source: cx.tcx.def_span(did).clean(cx),
+        name: Some(name.clean(cx)),
         attrs: load_attrs(cx, did),
         inner: inner,
         visibility: Some(clean::Public),
-        stability: tcx.lookup_stability(did).clean(cx),
-        deprecation: tcx.lookup_deprecation(did).clean(cx),
+        stability: cx.tcx.lookup_stability(did).clean(cx),
+        deprecation: cx.tcx.lookup_deprecation(did).clean(cx),
         def_id: did,
     });
     Some(ret)
@@ -463,7 +447,7 @@ fn fill_in(cx: &DocContext, did: DefId, items: &mut Vec<clean::Item>) {
             let def_id = item.def.def_id();
             if cx.tcx.sess.cstore.visibility(def_id) == ty::Visibility::Public {
                 if !visited.insert(def_id) { continue }
-                if let Some(i) = try_inline_def(cx, item.def) {
+                if let Some(i) = try_inline(cx, item.def, item.name) {
                     items.extend(i)
                 }
             }
index 61f941e57b2d8c6a61481e6ba7c819d0ded0604d..48d387f812d2548df1868fe197a082531d4ccdd4 100644 (file)
@@ -2618,7 +2618,7 @@ fn clean(&self, cx: &DocContext) -> Vec<Item> {
         } else {
             let name = self.name;
             if !denied {
-                if let Some(items) = inline::try_inline(cx, path.def, Some(name)) {
+                if let Some(items) = inline::try_inline(cx, path.def, name) {
                     return items;
                 }
             }
index f40475a41422bb9dc726480c3db4fbc9ea5459f4..1167c39dba8eef63c9589777b6a0928b4de61029 100644 (file)
 use slice;
 use str::{self, Utf8Error};
 
-/// A type representing an owned C-compatible string
+/// A type representing an owned C-compatible string.
 ///
 /// This type serves the primary purpose of being able to safely generate a
 /// C-compatible string from a Rust byte slice or vector. An instance of this
 /// type is a static guarantee that the underlying bytes contain no interior 0
 /// bytes and the final byte is 0.
 ///
-/// A `CString` is created from either a byte slice or a byte vector.  A `u8`
-/// slice can be obtained with the `as_bytes` method.  Slices produced from a
+/// A `CString` is created from either a byte slice or a byte vector. A [`u8`]
+/// slice can be obtained with the `as_bytes` method. Slices produced from a
 /// `CString` do *not* contain the trailing nul terminator unless otherwise
 /// specified.
 ///
+/// [`u8`]: ../primitive.u8.html
+///
 /// # Examples
 ///
 /// ```no_run
@@ -81,12 +83,14 @@ pub struct CString {
 ///
 /// Note that this structure is **not** `repr(C)` and is not recommended to be
 /// placed in the signatures of FFI functions. Instead safe wrappers of FFI
-/// functions may leverage the unsafe `from_ptr` constructor to provide a safe
+/// functions may leverage the unsafe [`from_ptr`] constructor to provide a safe
 /// interface to other consumers.
 ///
+/// [`from_ptr`]: #method.from_ptr
+///
 /// # Examples
 ///
-/// Inspecting a foreign C string
+/// Inspecting a foreign C string:
 ///
 /// ```no_run
 /// use std::ffi::CStr;
@@ -100,7 +104,7 @@ pub struct CString {
 /// }
 /// ```
 ///
-/// Passing a Rust-originating C string
+/// Passing a Rust-originating C string:
 ///
 /// ```no_run
 /// use std::ffi::{CString, CStr};
@@ -116,7 +120,9 @@ pub struct CString {
 /// work(&s);
 /// ```
 ///
-/// Converting a foreign C string into a Rust `String`
+/// Converting a foreign C string into a Rust [`String`]:
+///
+/// [`String`]: ../string/struct.String.html
 ///
 /// ```no_run
 /// use std::ffi::CStr;
@@ -142,14 +148,18 @@ pub struct CStr {
     inner: [c_char]
 }
 
-/// An error returned from `CString::new` to indicate that a nul byte was found
+/// An error returned from [`CString::new`] to indicate that a nul byte was found
 /// in the vector provided.
+///
+/// [`CString::new`]: struct.CString.html#method.new
 #[derive(Clone, PartialEq, Eq, Debug)]
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct NulError(usize, Vec<u8>);
 
-/// An error returned from `CStr::from_bytes_with_nul` to indicate that a nul
+/// An error returned from [`CStr::from_bytes_with_nul`] to indicate that a nul
 /// byte was found too early in the slice provided or one wasn't found at all.
+///
+/// [`CStr::from_bytes_with_nul`]: struct.CStr.html#method.from_bytes_with_nul
 #[derive(Clone, PartialEq, Eq, Debug)]
 #[stable(feature = "cstr_from_bytes", since = "1.10.0")]
 pub struct FromBytesWithNulError {
@@ -175,8 +185,10 @@ fn not_nul_terminated() -> FromBytesWithNulError {
     }
 }
 
-/// An error returned from `CString::into_string` to indicate that a UTF-8 error
+/// An error returned from [`CString::into_string`] to indicate that a UTF-8 error
 /// was encountered during the conversion.
+///
+/// [`CString::into_string`]: struct.CString.html#method.into_string
 #[derive(Clone, PartialEq, Eq, Debug)]
 #[stable(feature = "cstring_into", since = "1.7.0")]
 pub struct IntoStringError {
@@ -224,10 +236,12 @@ fn _new(bytes: Vec<u8>) -> Result<CString, NulError> {
     /// Creates a C-compatible string from a byte vector without checking for
     /// interior 0 bytes.
     ///
-    /// This method is equivalent to `new` except that no runtime assertion
+    /// This method is equivalent to [`new`] except that no runtime assertion
     /// is made that `v` contains no 0 bytes, and it requires an actual
     /// byte vector, not anything that can be converted to one with Into.
     ///
+    /// [`new`]: #method.new
+    ///
     /// # Examples
     ///
     /// ```
@@ -252,9 +266,11 @@ pub unsafe fn from_vec_unchecked(mut v: Vec<u8>) -> CString {
     /// # Safety
     ///
     /// This should only ever be called with a pointer that was earlier
-    /// obtained by calling `into_raw` on a `CString`. Other usage (e.g. trying to take
+    /// obtained by calling [`into_raw`] on a `CString`. Other usage (e.g. trying to take
     /// ownership of a string that was allocated by foreign code) is likely to lead
     /// to undefined behavior or allocator corruption.
+    ///
+    /// [`into_raw`]: #method.into_raw
     #[stable(feature = "cstr_memory", since = "1.4.0")]
     pub unsafe fn from_raw(ptr: *mut c_char) -> CString {
         let len = libc::strlen(ptr) + 1; // Including the NUL byte
@@ -265,19 +281,23 @@ pub unsafe fn from_raw(ptr: *mut c_char) -> CString {
     /// Transfers ownership of the string to a C caller.
     ///
     /// The pointer must be returned to Rust and reconstituted using
-    /// `from_raw` to be properly deallocated. Specifically, one
+    /// [`from_raw`] to be properly deallocated. Specifically, one
     /// should *not* use the standard C `free` function to deallocate
     /// this string.
     ///
-    /// Failure to call `from_raw` will lead to a memory leak.
+    /// Failure to call [`from_raw`] will lead to a memory leak.
+    ///
+    /// [`from_raw`]: #method.from_raw
     #[stable(feature = "cstr_memory", since = "1.4.0")]
     pub fn into_raw(self) -> *mut c_char {
         Box::into_raw(self.into_inner()) as *mut c_char
     }
 
-    /// Converts the `CString` into a `String` if it contains valid Unicode data.
+    /// Converts the `CString` into a [`String`] if it contains valid Unicode data.
     ///
     /// On failure, ownership of the original `CString` is returned.
+    ///
+    /// [`String`]: ../string/struct.String.html
     #[stable(feature = "cstring_into", since = "1.7.0")]
     pub fn into_string(self) -> Result<String, IntoStringError> {
         String::from_utf8(self.into_bytes())
@@ -299,8 +319,10 @@ pub fn into_bytes(self) -> Vec<u8> {
         vec
     }
 
-    /// Equivalent to the `into_bytes` function except that the returned vector
+    /// Equivalent to the [`into_bytes`] function except that the returned vector
     /// includes the trailing nul byte.
+    ///
+    /// [`into_bytes`]: #method.into_bytes
     #[stable(feature = "cstring_into", since = "1.7.0")]
     pub fn into_bytes_with_nul(self) -> Vec<u8> {
         self.into_inner().into_vec()
@@ -315,26 +337,34 @@ pub fn as_bytes(&self) -> &[u8] {
         &self.inner[..self.inner.len() - 1]
     }
 
-    /// Equivalent to the `as_bytes` function except that the returned slice
+    /// Equivalent to the [`as_bytes`] function except that the returned slice
     /// includes the trailing nul byte.
+    ///
+    /// [`as_bytes`]: #method.as_bytes
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn as_bytes_with_nul(&self) -> &[u8] {
         &self.inner
     }
 
-    /// Extracts a `CStr` slice containing the entire string.
+    /// Extracts a [`CStr`] slice containing the entire string.
+    ///
+    /// [`CStr`]: struct.CStr.html
     #[unstable(feature = "as_c_str", issue = "40380")]
     pub fn as_c_str(&self) -> &CStr {
         &*self
     }
 
-    /// Converts this `CString` into a boxed `CStr`.
+    /// Converts this `CString` into a boxed [`CStr`].
+    ///
+    /// [`CStr`]: struct.CStr.html
     #[unstable(feature = "into_boxed_c_str", issue = "40380")]
     pub fn into_boxed_c_str(self) -> Box<CStr> {
         unsafe { mem::transmute(self.into_inner()) }
     }
 
-    // Bypass "move out of struct which implements `Drop` trait" restriction.
+    // Bypass "move out of struct which implements [`Drop`] trait" restriction.
+    ///
+    /// [`Drop`]: ../ops/trait.Drop.html
     fn into_inner(self) -> Box<[u8]> {
         unsafe {
             let result = ptr::read(&self.inner);
@@ -443,7 +473,9 @@ fn default() -> Box<CStr> {
 
 impl NulError {
     /// Returns the position of the nul byte in the slice that was provided to
-    /// `CString::new`.
+    /// [`CString::new`].
+    ///
+    /// [`CString::new`]: struct.CString.html#method.new
     ///
     /// # Examples
     ///
@@ -518,8 +550,10 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
 }
 
 impl IntoStringError {
-    /// Consumes this error, returning original `CString` which generated the
+    /// Consumes this error, returning original [`CString`] which generated the
     /// error.
+    ///
+    /// [`CString`]: struct.CString.html
     #[stable(feature = "cstring_into", since = "1.7.0")]
     pub fn into_cstring(self) -> CString {
         self.inner
@@ -557,9 +591,9 @@ impl CStr {
     /// allows inspection and interoperation of non-owned C strings. This method
     /// is unsafe for a number of reasons:
     ///
-    /// * There is no guarantee to the validity of `ptr`
+    /// * There is no guarantee to the validity of `ptr`.
     /// * The returned lifetime is not guaranteed to be the actual lifetime of
-    ///   `ptr`
+    ///   `ptr`.
     /// * There is no guarantee that the memory pointed to by `ptr` contains a
     ///   valid nul terminator byte at the end of the string.
     ///
@@ -703,26 +737,30 @@ pub fn to_bytes(&self) -> &[u8] {
 
     /// Converts this C string to a byte slice containing the trailing 0 byte.
     ///
-    /// This function is the equivalent of `to_bytes` except that it will retain
+    /// This function is the equivalent of [`to_bytes`] except that it will retain
     /// the trailing nul instead of chopping it off.
     ///
     /// > **Note**: This method is currently implemented as a 0-cost cast, but
     /// > it is planned to alter its definition in the future to perform the
     /// > length calculation whenever this method is called.
+    ///
+    /// [`to_bytes`]: #method.to_bytes
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn to_bytes_with_nul(&self) -> &[u8] {
         unsafe { mem::transmute(&self.inner) }
     }
 
-    /// Yields a `&str` slice if the `CStr` contains valid UTF-8.
+    /// Yields a [`&str`] slice if the `CStr` contains valid UTF-8.
     ///
     /// This function will calculate the length of this string and check for
-    /// UTF-8 validity, and then return the `&str` if it's valid.
+    /// UTF-8 validity, and then return the [`&str`] if it's valid.
     ///
     /// > **Note**: This method is currently implemented to check for validity
     /// > after a 0-cost cast, but it is planned to alter its definition in the
     /// > future to perform the length calculation in addition to the UTF-8
     /// > check whenever this method is called.
+    ///
+    /// [`&str`]: ../primitive.str.html
     #[stable(feature = "cstr_to_str", since = "1.4.0")]
     pub fn to_str(&self) -> Result<&str, str::Utf8Error> {
         // NB: When CStr is changed to perform the length check in .to_bytes()
@@ -732,23 +770,29 @@ pub fn to_str(&self) -> Result<&str, str::Utf8Error> {
         str::from_utf8(self.to_bytes())
     }
 
-    /// Converts a `CStr` into a `Cow<str>`.
+    /// Converts a `CStr` into a [`Cow`]`<`[`str`]`>`.
     ///
     /// This function will calculate the length of this string (which normally
     /// requires a linear amount of work to be done) and then return the
-    /// resulting slice as a `Cow<str>`, replacing any invalid UTF-8 sequences
+    /// resulting slice as a [`Cow`]`<`[`str`]`>`, replacing any invalid UTF-8 sequences
     /// with `U+FFFD REPLACEMENT CHARACTER`.
     ///
     /// > **Note**: This method is currently implemented to check for validity
     /// > after a 0-cost cast, but it is planned to alter its definition in the
     /// > future to perform the length calculation in addition to the UTF-8
     /// > check whenever this method is called.
+    ///
+    /// [`Cow`]: ../borrow/enum.Cow.html
+    /// [`str`]: ../primitive.str.html
     #[stable(feature = "cstr_to_str", since = "1.4.0")]
     pub fn to_string_lossy(&self) -> Cow<str> {
         String::from_utf8_lossy(self.to_bytes())
     }
 
-    /// Converts a `Box<CStr>` into a `CString` without copying or allocating.
+    /// Converts a [`Box`]`<CStr>` into a [`CString`] without copying or allocating.
+    ///
+    /// [`Box`]: ../boxed/struct.Box.html
+    /// [`CString`]: struct.CString.html
     #[unstable(feature = "into_boxed_c_str", issue = "40380")]
     pub fn into_c_string(self: Box<CStr>) -> CString {
         unsafe { mem::transmute(self) }
index acff7faf8a7d0a853bf3d09e903f360db7c8f721..06fd838ea06d966b047f8e1a257d1acd253433cd 100644 (file)
@@ -35,6 +35,8 @@ fn lang_start(main: fn(), argc: isize, argv: *const *const u8) -> isize {
     use sys_common;
     use sys_common::thread_info;
     use thread::Thread;
+    #[cfg(not(feature = "backtrace"))]
+    use mem;
 
     sys::init();
 
@@ -53,9 +55,12 @@ fn lang_start(main: fn(), argc: isize, argv: *const *const u8) -> isize {
         sys::args::init(argc, argv);
 
         // Let's run some code!
+        #[cfg(feature = "backtrace")]
         let res = panic::catch_unwind(|| {
             ::sys_common::backtrace::__rust_begin_short_backtrace(main)
         });
+        #[cfg(not(feature = "backtrace"))]
+        let res = panic::catch_unwind(mem::transmute::<_, fn()>(main));
         sys_common::cleanup();
         res.is_err()
     };
index 8d80f942ff75cb9f50c29919c75d7beaf6a21466..296773d20f6140542cfdcfe8e7b25e4af1ee402a 100644 (file)
@@ -1,29 +1,12 @@
-/* Copyright (c) 2010-2011 Dmitry Vyukov. All rights reserved.
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *    1. Redistributions of source code must retain the above copyright notice,
- *       this list of conditions and the following disclaimer.
- *
- *    2. Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in the
- *       documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY DMITRY VYUKOV "AS IS" AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
- * SHALL DMITRY VYUKOV OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
- * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * The views and conclusions contained in the software and documentation are
- * those of the authors and should not be interpreted as representing official
- * policies, either expressed or implied, of Dmitry Vyukov.
- */
+// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
 
 //! A mostly lock-free multi-producer, single consumer queue.
 //!
index 5858e4b6ddb1f2ab35312aaa4a5406baa84ca29c..1148bc66fbabbaa0d0e998f6af203e1f84277588 100644 (file)
@@ -1,31 +1,12 @@
-/* Copyright (c) 2010-2011 Dmitry Vyukov. All rights reserved.
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *    1. Redistributions of source code must retain the above copyright notice,
- *       this list of conditions and the following disclaimer.
- *
- *    2. Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in the
- *       documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY DMITRY VYUKOV "AS IS" AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
- * SHALL DMITRY VYUKOV OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
- * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * The views and conclusions contained in the software and documentation are
- * those of the authors and should not be interpreted as representing official
- * policies, either expressed or implied, of Dmitry Vyukov.
- */
-
-// http://www.1024cores.net/home/lock-free-algorithms/queues/unbounded-spsc-queue
+// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
 
 //! A single-producer single-consumer concurrent queue
 //!
@@ -33,6 +14,8 @@
 //! concurrently between two threads. This data structure is safe to use and
 //! enforces the semantics that there is one pusher and one popper.
 
+// http://www.1024cores.net/home/lock-free-algorithms/queues/unbounded-spsc-queue
+
 use alloc::boxed::Box;
 use core::ptr;
 use core::cell::UnsafeCell;
index abdd9ace795f42dea62490944ec7d32c60493fd5..cacd84e21025f5dfaef88eeceec7593311411a17 100644 (file)
@@ -64,3 +64,8 @@ pub unsafe fn set(key: Key, value: *mut u8) {
 pub unsafe fn destroy(key: Key) {
     keys().remove(&key);
 }
+
+#[inline]
+pub fn requires_synchronized_create() -> bool {
+    false
+}
index 154406a1d8bd78ca29965e9f54f49f4af51fc896..d0e3b00d75fac43fdf2ad5f869e0f1add11be067 100644 (file)
@@ -359,9 +359,12 @@ pub fn spawn<F, T>(self, f: F) -> io::Result<JoinHandle<T>> where
             }
             unsafe {
                 thread_info::set(imp::guard::current(), their_thread);
+                #[cfg(feature = "backtrace")]
                 let try_result = panic::catch_unwind(panic::AssertUnwindSafe(|| {
                     ::sys_common::backtrace::__rust_begin_short_backtrace(f)
                 }));
+                #[cfg(not(feature = "backtrace"))]
+                let try_result = panic::catch_unwind(panic::AssertUnwindSafe(f));
                 *their_packet.get() = Some(try_result);
             }
         };
@@ -394,6 +397,26 @@ pub fn spawn<F, T>(self, f: F) -> io::Result<JoinHandle<T>> where
 /// want to specify the stack size or the name of the thread, use this API
 /// instead.
 ///
+/// As you can see in the signature of `spawn` there are two constraints on
+/// both the closure given to `spawn` and its return value, let's explain them:
+///
+/// - The `'static` constraint means that the closure and its return value
+///   must have a lifetime of the whole program execution. The reason for this
+///   is that threads can `detach` and outlive the lifetime they have been
+///   created in.
+///   Indeed if the thread, and by extension its return value, can outlive their
+///   caller, we need to make sure that they will be valid afterwards, and since
+///   we *can't* know when it will return we need to have them valid as long as
+///   possible, that is until the end of the program, hence the `'static`
+///   lifetime.
+/// - The [`Send`] constraint is because the closure will need to be passed
+///   *by value* from the thread where it is spawned to the new thread. Its
+///   return value will need to be passed from the new thread to the thread
+///   where it is `join`ed.
+///   As a reminder, the [`Send`] marker trait, expresses that it is safe to be
+///   passed from thread to thread. [`Sync`] expresses that it is safe to have a
+///   reference be passed from thread to thread.
+///
 /// # Panics
 ///
 /// Panics if the OS fails to create a thread; use [`Builder::spawn`]
@@ -460,6 +483,8 @@ pub fn spawn<F, T>(self, f: F) -> io::Result<JoinHandle<T>> where
 /// [`panic`]: ../../std/macro.panic.html
 /// [`Builder::spawn`]: ../../std/thread/struct.Builder.html#method.spawn
 /// [`Builder`]: ../../std/thread/struct.Builder.html
+/// [`Send`]: ../../std/marker/trait.Send.html
+/// [`Sync`]: ../../std/marker/trait.Sync.html
 #[stable(feature = "rust1", since = "1.0.0")]
 pub fn spawn<F, T>(f: F) -> JoinHandle<T> where
     F: FnOnce() -> T, F: Send + 'static, T: Send + 'static
index 45f891d8dc56db911f325fd6ff90b4034066e834..8e63e219c42c19924914ce01bf1661dc9cfb68aa 100644 (file)
@@ -320,7 +320,7 @@ pub fn meta(&self) -> Option<MetaItem> {
     pub fn parse<'a, T, F>(&self, sess: &'a ParseSess, mut f: F) -> PResult<'a, T>
         where F: FnMut(&mut Parser<'a>) -> PResult<'a, T>,
     {
-        let mut parser = Parser::new(sess, self.tokens.clone(), None, false);
+        let mut parser = Parser::new(sess, self.tokens.clone(), None, false, false);
         let result = f(&mut parser)?;
         if parser.token != token::Eof {
             parser.unexpected()?;
index bf66aa0f00bed42409ffbdc7ffe8cc3341d2a787..0b6a2eb536a20d7769721ee16a07f4de716ebefd 100644 (file)
@@ -418,9 +418,13 @@ fn inner_parse_loop(sess: &ParseSess,
     Success(())
 }
 
-pub fn parse(sess: &ParseSess, tts: TokenStream, ms: &[TokenTree], directory: Option<Directory>)
+pub fn parse(sess: &ParseSess,
+             tts: TokenStream,
+             ms: &[TokenTree],
+             directory: Option<Directory>,
+             recurse_into_modules: bool)
              -> NamedParseResult {
-    let mut parser = Parser::new(sess, tts, directory, true);
+    let mut parser = Parser::new(sess, tts, directory, recurse_into_modules, true);
     let mut cur_eis = SmallVector::one(initial_matcher_pos(ms.to_owned(), parser.span.lo));
     let mut next_eis = Vec::new(); // or proceed normally
 
index a208f530602a5f0b05677e27c261e29971871e78..73494d47fee9b9a59dee95d448e95e43de1e55ca 100644 (file)
@@ -121,7 +121,7 @@ fn generic_extension<'cx>(cx: &'cx mut ExtCtxt,
                     path: cx.current_expansion.module.directory.clone(),
                     ownership: cx.current_expansion.directory_ownership,
                 };
-                let mut p = Parser::new(cx.parse_sess(), tts, Some(directory), false);
+                let mut p = Parser::new(cx.parse_sess(), tts, Some(directory), true, false);
                 p.root_module_name = cx.current_expansion.module.mod_path.last()
                     .map(|id| id.name.as_str().to_string());
 
@@ -192,7 +192,7 @@ pub fn compile(sess: &ParseSess, features: &RefCell<Features>, def: &ast::Item)
         ast::ItemKind::MacroDef(ref body) => body.clone().into(),
         _ => unreachable!(),
     };
-    let argument_map = match parse(sess, body, &argument_gram, None) {
+    let argument_map = match parse(sess, body, &argument_gram, None, true) {
         Success(m) => m,
         Failure(sp, tok) => {
             let s = parse_failure_msg(tok);
index bebb26afb540f10f8a069fa4cab94031acf1c820..e1b7d4681ad160c38c613af52e931c48b0a5ff49 100644 (file)
@@ -297,9 +297,6 @@ pub fn new() -> Features {
 
     (active, use_extern_macros, "1.15.0", Some(35896)),
 
-    // Allows `break {expr}` with a value inside `loop`s.
-    (active, loop_break_value, "1.14.0", Some(37339)),
-
     // Allows #[target_feature(...)]
     (active, target_feature, "1.15.0", None),
 
@@ -423,6 +420,8 @@ pub fn new() -> Features {
     (accepted, pub_restricted, "1.18.0", Some(32409)),
     // The #![windows_subsystem] attribute
     (accepted, windows_subsystem, "1.18.0", Some(37499)),
+    // Allows `break {expr}` with a value inside `loop`s.
+    (accepted, loop_break_value, "1.19.0", Some(37339)),
 );
 // If you change this, please modify src/doc/unstable-book as well. You must
 // move that documentation into the relevant place in the other docs, and
@@ -1301,10 +1300,6 @@ fn visit_expr(&mut self, e: &'a ast::Expr) {
                     }
                 }
             }
-            ast::ExprKind::Break(_, Some(_)) => {
-                gate_feature_post!(&self, loop_break_value, e.span,
-                                   "`break` with a value is experimental");
-            }
             ast::ExprKind::Lit(ref lit) => {
                 if let ast::LitKind::Int(_, ref ty) = lit.node {
                     match *ty {
index 4df23da3c9ce3464bf1cb760352e5bd7df68b144..83a164bdb9693c66b67cd46300331d0839f703a4 100644 (file)
@@ -238,7 +238,7 @@ pub fn check_for_substitution<'a>(reader: &StringReader<'a>,
         match ASCII_ARRAY.iter().find(|&&(c, _)| c == ascii_char) {
             Some(&(ascii_char, ascii_name)) => {
                 let msg =
-                    format!("unicode character '{}' ({}) looks much like '{}' ({}), but it's not",
+                    format!("unicode character '{}' ({}) looks like '{}' ({}), but it's not",
                             ch, u_name, ascii_char, ascii_name);
                 err.span_help(span, &msg);
             },
index 1eff819d755493f33f713b6281100591bab78413..3a68a6ba7646c98de89a8cd8354b4db1fab175ef 100644 (file)
@@ -149,7 +149,9 @@ pub fn parse_stream_from_source_str(name: String, source: String, sess: &ParseSe
 // Create a new parser from a source string
 pub fn new_parser_from_source_str(sess: &ParseSess, name: String, source: String)
                                       -> Parser {
-    filemap_to_parser(sess, sess.codemap().new_filemap(name, source))
+    let mut parser = filemap_to_parser(sess, sess.codemap().new_filemap(name, source));
+    parser.recurse_into_file_modules = false;
+    parser
 }
 
 /// Create a new parser, handling errors as appropriate
@@ -218,7 +220,7 @@ pub fn filemap_to_stream(sess: &ParseSess, filemap: Rc<FileMap>) -> TokenStream
 
 /// Given stream and the `ParseSess`, produce a parser
 pub fn stream_to_parser(sess: &ParseSess, stream: TokenStream) -> Parser {
-    Parser::new(sess, stream, None, false)
+    Parser::new(sess, stream, None, true, false)
 }
 
 /// Parse a string representing a character literal into its final form.
@@ -1032,4 +1034,23 @@ fn ttdelim_span() {
             Err(_) => panic!("could not get snippet"),
         }
     }
+
+    // This tests that when parsing a string (rather than a file) we don't try
+    // and read in a file for a module declaration and just parse a stub.
+    // See `recurse_into_file_modules` in the parser.
+    #[test]
+    fn out_of_line_mod() {
+        let sess = ParseSess::new(FilePathMapping::empty());
+        let item = parse_item_from_source_str(
+            "foo".to_owned(),
+            "mod foo { struct S; mod this_does_not_exist; }".to_owned(),
+            &sess,
+        ).unwrap().unwrap();
+
+        if let ast::ItemKind::Mod(ref m) = item.node {
+            assert!(m.items.len() == 2);
+        } else {
+            panic!();
+        }
+    }
 }
index 4741f896d3cc0c8c6ce38501dd2e1cb1a7dcfe0e..c28f678cb5197a84f62426c4bdfc5f8fdfb3d485 100644 (file)
@@ -179,6 +179,8 @@ pub struct Parser<'a> {
     pub obsolete_set: HashSet<ObsoleteSyntax>,
     /// Used to determine the path to externally loaded source files
     pub directory: Directory,
+    /// Whether to parse sub-modules in other files.
+    pub recurse_into_file_modules: bool,
     /// Name of the root module this parser originated from. If `None`, then the
     /// name is not known. This does not change while the parser is descending
     /// into modules, and sub-parsers have new values for this name.
@@ -190,6 +192,7 @@ pub struct Parser<'a> {
     pub cfg_mods: bool,
 }
 
+
 struct TokenCursor {
     frame: TokenCursorFrame,
     stack: Vec<TokenCursorFrame>,
@@ -439,6 +442,7 @@ impl<'a> Parser<'a> {
     pub fn new(sess: &'a ParseSess,
                tokens: TokenStream,
                directory: Option<Directory>,
+               recurse_into_file_modules: bool,
                desugar_doc_comments: bool)
                -> Self {
         let mut parser = Parser {
@@ -450,6 +454,7 @@ pub fn new(sess: &'a ParseSess,
             prev_token_kind: PrevTokenKind::Other,
             restrictions: Restrictions::empty(),
             obsolete_set: HashSet::new(),
+            recurse_into_file_modules: recurse_into_file_modules,
             directory: Directory { path: PathBuf::new(), ownership: DirectoryOwnership::Owned },
             root_module_name: None,
             expected_tokens: Vec::new(),
@@ -467,12 +472,14 @@ pub fn new(sess: &'a ParseSess,
         let tok = parser.next_tok();
         parser.token = tok.tok;
         parser.span = tok.sp;
+
         if let Some(directory) = directory {
             parser.directory = directory;
         } else if parser.span != syntax_pos::DUMMY_SP {
             parser.directory.path = PathBuf::from(sess.codemap().span_to_filename(parser.span));
             parser.directory.path.pop();
         }
+
         parser.process_potential_macro_variable();
         parser
     }
@@ -3921,6 +3928,7 @@ fn parse_stmt_without_recovery(&mut self,
                 mem::replace(&mut self.directory.ownership, DirectoryOwnership::UnownedViaBlock);
             let item = self.parse_item_(attrs.clone(), false, true)?;
             self.directory.ownership = old_directory_ownership;
+
             match item {
                 Some(i) => Stmt {
                     id: ast::DUMMY_NODE_ID,
@@ -5254,7 +5262,7 @@ fn parse_item_mod(&mut self, outer_attrs: &[Attribute]) -> PResult<'a, ItemInfo>
         let id = self.parse_ident()?;
         if self.check(&token::Semi) {
             self.bump();
-            if in_cfg {
+            if in_cfg && self.recurse_into_file_modules {
                 // This mod is in an external file. Let's go get it!
                 let ModulePathSuccess { path, directory_ownership, warn } =
                     self.submod_path(id, &outer_attrs, id_span)?;
@@ -5281,10 +5289,12 @@ fn parse_item_mod(&mut self, outer_attrs: &[Attribute]) -> PResult<'a, ItemInfo>
         } else {
             let old_directory = self.directory.clone();
             self.push_directory(id, &outer_attrs);
+
             self.expect(&token::OpenDelim(token::Brace))?;
             let mod_inner_lo = self.span;
             let attrs = self.parse_inner_attributes()?;
             let module = self.parse_mod_items(&token::CloseDelim(token::Brace), mod_inner_lo)?;
+
             self.directory = old_directory;
             Ok((id, ItemKind::Mod(module), Some(attrs)))
         }
@@ -5347,7 +5357,8 @@ pub fn default_submod_path(id: ast::Ident, dir_path: &Path, codemap: &CodeMap) -
     fn submod_path(&mut self,
                    id: ast::Ident,
                    outer_attrs: &[ast::Attribute],
-                   id_sp: Span) -> PResult<'a, ModulePathSuccess> {
+                   id_sp: Span)
+                   -> PResult<'a, ModulePathSuccess> {
         if let Some(path) = Parser::submod_path_from_attr(outer_attrs, &self.directory.path) {
             return Ok(ModulePathSuccess {
                 directory_ownership: match path.file_name().and_then(|s| s.to_str()) {
index 9c1371a31fec7a9287f9f874c5d59defe042056e..339e7c0b628adcf5a9c9298cd93423c138ae20a5 100644 (file)
@@ -109,7 +109,7 @@ pub fn parse(cx: &base::ExtCtxt, mtch: &[quoted::TokenTree], tts: TokenStream)
             path: cx.current_expansion.module.directory.clone(),
             ownership: cx.current_expansion.directory_ownership,
         };
-        macro_parser::parse(cx.parse_sess(), tts, mtch, Some(directory))
+        macro_parser::parse(cx.parse_sess(), tts, mtch, Some(directory), true)
     }
 
     /// Check if this TokenTree is equal to the other, regardless of span information.
index 211c0e6f890313130583ac8d7796ddd6a6403a2d..816d35295542785cc0c5ac9fb8c8c75299c2ca88 100644 (file)
@@ -25,7 +25,6 @@ fn is_send<T: Send>() { }
 fn main() {
     is_send::<Foo>();
     //~^ ERROR the trait bound `*const u8: std::marker::Send` is not satisfied in `Foo`
-    //~| NOTE within `Foo`, the trait `std::marker::Send` is not implemented for `*const u8`
     //~| NOTE: `*const u8` cannot be sent between threads safely
     //~| NOTE: required because it appears within the type `Baz`
     //~| NOTE: required because it appears within the type `Bar`
index e31fea1e45863205e40132d17162e04a9fbe9e85..8b34936419db587c2bf844fa54cb23069ccf38b2 100644 (file)
@@ -20,7 +20,6 @@ fn some_func<T: Foo>(foo: T) {
 
 fn f(p: Path) { }
 //~^ ERROR the trait bound `[u8]: std::marker::Sized` is not satisfied in `std::path::Path`
-//~| NOTE within `std::path::Path`, the trait `std::marker::Sized` is not implemented for `[u8]`
 //~| NOTE `[u8]` does not have a constant size known at compile-time
 //~| NOTE required because it appears within the type `std::path::Path`
 //~| NOTE all local variables must have a statically known size
index 23cff4ac6ad6c219b55eae24f8c8d515c4d30523..4b212814ded2985249dcb8b004a70b1c2f462aa9 100644 (file)
 
 const CONST_0: Debug+Sync = *(&0 as &(Debug+Sync));
 //~^ ERROR `std::fmt::Debug + std::marker::Sync + 'static: std::marker::Sized` is not satisfied
-//~| NOTE the trait `std::marker::Sized` is not implemented for `std::fmt::Debug + std::marker::Syn
 //~| NOTE does not have a constant size known at compile-time
 //~| NOTE constant expressions must have a statically known size
 
 const CONST_FOO: str = *"foo";
 //~^ ERROR `str: std::marker::Sized` is not satisfied
-//~| NOTE the trait `std::marker::Sized` is not implemented for `str`
 //~| NOTE does not have a constant size known at compile-time
 //~| NOTE constant expressions must have a statically known size
 
 static STATIC_1: Debug+Sync = *(&1 as &(Debug+Sync));
 //~^ ERROR `std::fmt::Debug + std::marker::Sync + 'static: std::marker::Sized` is not satisfied
-//~| NOTE the trait `std::marker::Sized` is not implemented for `std::fmt::Debug + std::marker::Syn
 //~| NOTE does not have a constant size known at compile-time
 //~| NOTE constant expressions must have a statically known size
 
 static STATIC_BAR: str = *"bar";
 //~^ ERROR `str: std::marker::Sized` is not satisfied
-//~| NOTE the trait `std::marker::Sized` is not implemented for `str`
 //~| NOTE does not have a constant size known at compile-time
 //~| NOTE constant expressions must have a statically known size
 
diff --git a/src/test/compile-fail/feature-gate-loop-break-value.rs b/src/test/compile-fail/feature-gate-loop-break-value.rs
deleted file mode 100644 (file)
index 1632c40..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-// Copyright 2016 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() {
-    loop {
-        break 123; //~ ERROR `break` with a value is experimental
-    }
-}
index 13e53cab17226d385107b551928608cb95c56a1a..8a5033e76478ba90e0347ff01578f9d25889a381 100644 (file)
@@ -26,7 +26,6 @@ fn send<T: Send>(_: T) {}
 fn main() {
     send(before());
     //~^ ERROR the trait bound `std::rc::Rc<std::cell::Cell<i32>>: std::marker::Send` is not satisfied
-    //~| NOTE the trait `std::marker::Send` is not implemented for `std::rc::Rc<std::cell::Cell<i32>>`
     //~| NOTE `std::rc::Rc<std::cell::Cell<i32>>` cannot be sent between threads safely
     //~| NOTE required because it appears within the type `[closure
     //~| NOTE required because it appears within the type `impl std::ops::Fn<(i32,)>`
@@ -34,7 +33,6 @@ fn main() {
 
     send(after());
     //~^ ERROR the trait bound `std::rc::Rc<std::cell::Cell<i32>>: std::marker::Send` is not satisfied
-    //~| NOTE the trait `std::marker::Send` is not implemented for `std::rc::Rc<std::cell::Cell<i32>>`
     //~| NOTE `std::rc::Rc<std::cell::Cell<i32>>` cannot be sent between threads safely
     //~| NOTE required because it appears within the type `[closure
     //~| NOTE required because it appears within the type `impl std::ops::Fn<(i32,)>`
diff --git a/src/test/compile-fail/isssue-38821.rs b/src/test/compile-fail/isssue-38821.rs
new file mode 100644 (file)
index 0000000..63de780
--- /dev/null
@@ -0,0 +1,43 @@
+// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+pub struct Nullable<T: NotNull>(T);
+
+pub trait NotNull {}
+
+pub trait IntoNullable {
+    type Nullable;
+}
+
+impl<T: NotNull> IntoNullable for T {
+    type Nullable = Nullable<T>;
+}
+
+impl<T: NotNull> IntoNullable for Nullable<T> {
+    type Nullable = Nullable<T>;
+}
+
+pub trait Expression {
+    type SqlType;
+}
+
+pub trait Column: Expression {}
+
+#[derive(Debug, Copy, Clone)]
+//~^ ERROR the trait bound `<Col as Expression>::SqlType: NotNull` is not satisfied
+pub enum ColumnInsertValue<Col, Expr> where
+    Col: Column,
+    Expr: Expression<SqlType=<Col::SqlType as IntoNullable>::Nullable>,
+{
+    Expression(Col, Expr),
+    Default(Col),
+}
+
+fn main() {}
index a414321899203d17b0f16642a9e8fc0e67170d18..938f7fba2a0324320b3616e4b68e8acc66ec5ce9 100644 (file)
@@ -8,7 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(loop_break_value)]
 #![feature(never_type)]
 
 fn main() {
index 0ad9f21e0983f491bc079f65dfec4e4e76656f5f..0df8c41ffe1a8e52ae7fa2f710305af478c78348 100644 (file)
@@ -42,17 +42,14 @@ fn index(&self, _index: Bar<usize>) -> &i32 {
 fn main() {
     Index::index(&[] as &[i32], 2u32);
     //~^ ERROR E0277
-    //~| NOTE the trait `Index<u32>` is not implemented for `[i32]`
     //~| NOTE trait message
     //~| NOTE required by
     Index::index(&[] as &[i32], Foo(2u32));
     //~^ ERROR E0277
-    //~| NOTE the trait `Index<Foo<u32>>` is not implemented for `[i32]`
     //~| NOTE on impl for Foo
     //~| NOTE required by
     Index::index(&[] as &[i32], Bar(2u32));
     //~^ ERROR E0277
-    //~| NOTE the trait `Index<Bar<u32>>` is not implemented for `[i32]`
     //~| NOTE on impl for Bar
     //~| NOTE required by
 }
index a7c599330a070e70051a8b9b7771bcefb7c26b12..79021cd03ccc13e6fa12f35d6f1ab23c28338252 100644 (file)
@@ -31,7 +31,6 @@ fn index(&self, index: usize) -> &i32 {
 fn main() {
     Index::<u32>::index(&[1, 2, 3] as &[i32], 2u32);
     //~^ ERROR E0277
-    //~| NOTE the trait `Index<u32>` is not implemented for `[i32]`
     //~| NOTE a usize is required
     //~| NOTE required by
 }
index 0f4b0919b6500842c7566ceefa0f099fb0a05bf5..a8daef356a5ccb809565bac96259e955ece9d11a 100644 (file)
@@ -35,9 +35,8 @@ pub fn main() {
     //~^ ERROR
     //~^^ NOTE a collection of type `std::option::Option<std::vec::Vec<u8>>` cannot be built from an iterator over elements of type `&u8`
     //~^^^ NOTE required by `collect`
-    //~| NOTE the trait `MyFromIterator<&u8>` is not implemented for `std::option::Option<std::vec::Vec<u8>>`
+
     let x: String = foobar(); //~ ERROR
     //~^ NOTE test error `std::string::String` with `u8` `_` `u32`
     //~^^ NOTE required by `foobar`
-    //~| NOTE the trait `Foo<u8, _, u32>` is not implemented for `std::string::String`
 }
index 1a9ed2dd6e4dcd957c4350c44b1af6ed61bec546..5d30c2e982ef719e30a0894788cf32af3fa8bf4c 100644 (file)
@@ -20,10 +20,8 @@ fn main() {
     let x = &[1, 2, 3] as &[i32];
     x[1i32]; //~ ERROR E0277
              //~| NOTE slice indices are of type `usize` or ranges of `usize`
-             //~| NOTE trait `std::slice::SliceIndex<[i32]>` is not implemented for `i32`
              //~| NOTE required because of the requirements on the impl of `std::ops::Index<i32>`
     x[..1i32]; //~ ERROR E0277
                //~| NOTE slice indices are of type `usize` or ranges of `usize`
-               //~| NOTE trait `std::slice::SliceIndex<[i32]>` is not implemented for `std::ops::RangeTo<i32>`
                //~| NOTE requirements on the impl of `std::ops::Index<std::ops::RangeTo<i32>>`
 }
diff --git a/src/test/compile-fail/partialeq_help.rs b/src/test/compile-fail/partialeq_help.rs
new file mode 100644 (file)
index 0000000..52c2447
--- /dev/null
@@ -0,0 +1,20 @@
+// Copyright 2017 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 foo<T: PartialEq>(a: &T, b: T) {
+    a == b; //~ ERROR E0277
+            //~| NOTE can't compare `&T` with `T`
+            //~| HELP the trait `std::cmp::PartialEq<T>` is not implemented for `&T`
+            //~| HELP consider adding a `where &T: std::cmp::PartialEq<T>` bound
+}
+
+fn main() {
+    foo(&1, 1);
+}
index 7530d8890b98c9397f45e10bb23fab948959ecf7..2c38d8d2e28ba2e3e1f6355a79df3e80b8883d2d 100644 (file)
@@ -16,51 +16,53 @@ fn check<T: Iterator, U: ?Sized>() {
     // suggest a where-clause, if needed
     mem::size_of::<U>();
     //~^ ERROR `U: std::marker::Sized` is not satisfied
-    //~| NOTE the trait `std::marker::Sized` is not implemented for `U`
     //~| HELP consider adding a `where U: std::marker::Sized` bound
     //~| NOTE required by `std::mem::size_of`
+    //~| NOTE `U` does not have a constant size known at compile-time
+    //~| HELP the trait `std::marker::Sized` is not implemented for `U`
 
     mem::size_of::<Misc<U>>();
     //~^ ERROR `U: std::marker::Sized` is not satisfied
-    //~| NOTE the trait `std::marker::Sized` is not implemented for `U`
     //~| HELP consider adding a `where U: std::marker::Sized` bound
     //~| NOTE required because it appears within the type `Misc<U>`
     //~| NOTE required by `std::mem::size_of`
+    //~| NOTE `U` does not have a constant size known at compile-time
+    //~| HELP within `Misc<U>`, the trait `std::marker::Sized` is not implemented for `U`
 
     // ... even if T occurs as a type parameter
 
     <u64 as From<T>>::from;
     //~^ ERROR `u64: std::convert::From<T>` is not satisfied
-    //~| NOTE the trait `std::convert::From<T>` is not implemented for `u64`
     //~| HELP consider adding a `where u64: std::convert::From<T>` bound
     //~| NOTE required by `std::convert::From::from`
+    //~| NOTE the trait `std::convert::From<T>` is not implemented for `u64`
 
     <u64 as From<<T as Iterator>::Item>>::from;
     //~^ ERROR `u64: std::convert::From<<T as std::iter::Iterator>::Item>` is not satisfied
-    //~| NOTE the trait `std::convert::From<<T as std::iter::Iterator>::Item>` is not implemented
     //~| HELP consider adding a `where u64:
     //~| NOTE required by `std::convert::From::from`
+    //~| NOTE the trait `std::convert::From<<T as std::iter::Iterator>::Item>` is not implemented
 
     // ... but not if there are inference variables
 
     <Misc<_> as From<T>>::from;
     //~^ ERROR `Misc<_>: std::convert::From<T>` is not satisfied
-    //~| NOTE the trait `std::convert::From<T>` is not implemented for `Misc<_>`
     //~| NOTE required by `std::convert::From::from`
+    //~| NOTE the trait `std::convert::From<T>` is not implemented for `Misc<_>`
 
     // ... and also not if the error is not related to the type
 
     mem::size_of::<[T]>();
     //~^ ERROR `[T]: std::marker::Sized` is not satisfied
-    //~| NOTE the trait `std::marker::Sized` is not implemented for `[T]`
     //~| NOTE `[T]` does not have a constant size
     //~| NOTE required by `std::mem::size_of`
+    //~| HELP the trait `std::marker::Sized` is not implemented for `[T]`
 
     mem::size_of::<[&U]>();
     //~^ ERROR `[&U]: std::marker::Sized` is not satisfied
-    //~| NOTE the trait `std::marker::Sized` is not implemented for `[&U]`
     //~| NOTE `[&U]` does not have a constant size
     //~| NOTE required by `std::mem::size_of`
+    //~| HELP the trait `std::marker::Sized` is not implemented for `[&U]`
 }
 
 fn main() {
diff --git a/src/test/mir-opt/storage_live_dead_in_statics.rs b/src/test/mir-opt/storage_live_dead_in_statics.rs
new file mode 100644 (file)
index 0000000..9fb725a
--- /dev/null
@@ -0,0 +1,100 @@
+// Copyright 2017 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.
+
+// Check that when we compile the static `XXX` into MIR, we do not
+// generate `StorageStart` or `StorageEnd` statements.
+
+// ignore-tidy-linelength
+
+static XXX: &'static Foo = &Foo {
+    tup: "hi",
+    data: &[
+        (0, 1), (0, 2), (0, 3),
+        (0, 1), (0, 2), (0, 3),
+        (0, 1), (0, 2), (0, 3),
+        (0, 1), (0, 2), (0, 3),
+        (0, 1), (0, 2), (0, 3),
+        (0, 1), (0, 2), (0, 3),
+        (0, 1), (0, 2), (0, 3),
+        (0, 1), (0, 2), (0, 3),
+        (0, 1), (0, 2), (0, 3),
+        (0, 1), (0, 2), (0, 3),
+        (0, 1), (0, 2), (0, 3),
+        (0, 1), (0, 2), (0, 3),
+        (0, 1), (0, 2), (0, 3),
+        (0, 1), (0, 2), (0, 3),
+    ]
+};
+
+#[derive(Debug)]
+struct Foo {
+    tup: &'static str,
+    data: &'static [(u32, u32)]
+}
+
+fn main() {
+    println!("{:?}", XXX);
+}
+
+// END RUST SOURCE
+// START rustc.node4.mir_map.0.mir
+//    bb0: {
+//        _7 = (const 0u32, const 1u32);   // scope 0 at src/test/mir-opt/basic_assignment.rs:29:9: 29:15
+//        _8 = (const 0u32, const 2u32);   // scope 0 at src/test/mir-opt/basic_assignment.rs:29:17: 29:23
+//        _9 = (const 0u32, const 3u32);   // scope 0 at src/test/mir-opt/basic_assignment.rs:29:25: 29:31
+//        _10 = (const 0u32, const 1u32);  // scope 0 at src/test/mir-opt/basic_assignment.rs:30:9: 30:15
+//        _11 = (const 0u32, const 2u32);  // scope 0 at src/test/mir-opt/basic_assignment.rs:30:17: 30:23
+//        _12 = (const 0u32, const 3u32);  // scope 0 at src/test/mir-opt/basic_assignment.rs:30:25: 30:31
+//        _13 = (const 0u32, const 1u32);  // scope 0 at src/test/mir-opt/basic_assignment.rs:31:9: 31:15
+//        _14 = (const 0u32, const 2u32);  // scope 0 at src/test/mir-opt/basic_assignment.rs:31:17: 31:23
+//        _15 = (const 0u32, const 3u32);  // scope 0 at src/test/mir-opt/basic_assignment.rs:31:25: 31:31
+//        _16 = (const 0u32, const 1u32);  // scope 0 at src/test/mir-opt/basic_assignment.rs:32:9: 32:15
+//        _17 = (const 0u32, const 2u32);  // scope 0 at src/test/mir-opt/basic_assignment.rs:32:17: 32:23
+//        _18 = (const 0u32, const 3u32);  // scope 0 at src/test/mir-opt/basic_assignment.rs:32:25: 32:31
+//        _19 = (const 0u32, const 1u32);  // scope 0 at src/test/mir-opt/basic_assignment.rs:33:9: 33:15
+//        _20 = (const 0u32, const 2u32);  // scope 0 at src/test/mir-opt/basic_assignment.rs:33:17: 33:23
+//        _21 = (const 0u32, const 3u32);  // scope 0 at src/test/mir-opt/basic_assignment.rs:33:25: 33:31
+//        _22 = (const 0u32, const 1u32);  // scope 0 at src/test/mir-opt/basic_assignment.rs:34:9: 34:15
+//        _23 = (const 0u32, const 2u32);  // scope 0 at src/test/mir-opt/basic_assignment.rs:34:17: 34:23
+//        _24 = (const 0u32, const 3u32);  // scope 0 at src/test/mir-opt/basic_assignment.rs:34:25: 34:31
+//        _25 = (const 0u32, const 1u32);  // scope 0 at src/test/mir-opt/basic_assignment.rs:35:9: 35:15
+//        _26 = (const 0u32, const 2u32);  // scope 0 at src/test/mir-opt/basic_assignment.rs:35:17: 35:23
+//        _27 = (const 0u32, const 3u32);  // scope 0 at src/test/mir-opt/basic_assignment.rs:35:25: 35:31
+//        _28 = (const 0u32, const 1u32);  // scope 0 at src/test/mir-opt/basic_assignment.rs:36:9: 36:15
+//        _29 = (const 0u32, const 2u32);  // scope 0 at src/test/mir-opt/basic_assignment.rs:36:17: 36:23
+//        _30 = (const 0u32, const 3u32);  // scope 0 at src/test/mir-opt/basic_assignment.rs:36:25: 36:31
+//        _31 = (const 0u32, const 1u32);  // scope 0 at src/test/mir-opt/basic_assignment.rs:37:9: 37:15
+//        _32 = (const 0u32, const 2u32);  // scope 0 at src/test/mir-opt/basic_assignment.rs:37:17: 37:23
+//        _33 = (const 0u32, const 3u32);  // scope 0 at src/test/mir-opt/basic_assignment.rs:37:25: 37:31
+//        _34 = (const 0u32, const 1u32);  // scope 0 at src/test/mir-opt/basic_assignment.rs:38:9: 38:15
+//        _35 = (const 0u32, const 2u32);  // scope 0 at src/test/mir-opt/basic_assignment.rs:38:17: 38:23
+//        _36 = (const 0u32, const 3u32);  // scope 0 at src/test/mir-opt/basic_assignment.rs:38:25: 38:31
+//        _37 = (const 0u32, const 1u32);  // scope 0 at src/test/mir-opt/basic_assignment.rs:39:9: 39:15
+//        _38 = (const 0u32, const 2u32);  // scope 0 at src/test/mir-opt/basic_assignment.rs:39:17: 39:23
+//        _39 = (const 0u32, const 3u32);  // scope 0 at src/test/mir-opt/basic_assignment.rs:39:25: 39:31
+//        _40 = (const 0u32, const 1u32);  // scope 0 at src/test/mir-opt/basic_assignment.rs:40:9: 40:15
+//        _41 = (const 0u32, const 2u32);  // scope 0 at src/test/mir-opt/basic_assignment.rs:40:17: 40:23
+//        _42 = (const 0u32, const 3u32);  // scope 0 at src/test/mir-opt/basic_assignment.rs:40:25: 40:31
+//        _43 = (const 0u32, const 1u32);  // scope 0 at src/test/mir-opt/basic_assignment.rs:41:9: 41:15
+//        _44 = (const 0u32, const 2u32);  // scope 0 at src/test/mir-opt/basic_assignment.rs:41:17: 41:23
+//        _45 = (const 0u32, const 3u32);  // scope 0 at src/test/mir-opt/basic_assignment.rs:41:25: 41:31
+//        _46 = (const 0u32, const 1u32);  // scope 0 at src/test/mir-opt/basic_assignment.rs:42:9: 42:15
+//        _47 = (const 0u32, const 2u32);  // scope 0 at src/test/mir-opt/basic_assignment.rs:42:17: 42:23
+//        _48 = (const 0u32, const 3u32);  // scope 0 at src/test/mir-opt/basic_assignment.rs:42:25: 42:31
+//        _6 = [_7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48]; // scope 0 at src/test/mir-opt/basic_assignment.rs:28:12: 43:6
+//        _5 = &_6;                        // scope 0 at src/test/mir-opt/basic_assignment.rs:28:11: 43:6
+//        _4 = &(*_5);                     // scope 0 at src/test/mir-opt/basic_assignment.rs:28:11: 43:6
+//        _3 = _4 as &'static [(u32, u32)] (Unsize); // scope 0 at src/test/mir-opt/basic_assignment.rs:28:11: 43:6
+//        _2 = Foo { tup: const "hi", data: _3 }; // scope 0 at src/test/mir-opt/basic_assignment.rs:26:29: 44:2
+//        _1 = &_2;                        // scope 0 at src/test/mir-opt/basic_assignment.rs:26:28: 44:2
+//        _0 = &(*_1);                     // scope 0 at src/test/mir-opt/basic_assignment.rs:26:28: 44:2
+//        return;                          // scope 0 at src/test/mir-opt/basic_assignment.rs:26:1: 44:3
+//    }
+// END rustc.node4.mir_map.0.mir
index adfaf62b5d3cc04aa203f3ee2810725f63d45450..1bdeb121a55d5ed555246cdf69d2d4a1448dc694 100644 (file)
@@ -9,10 +9,9 @@
 // except according to those terms.
 
 // compile-flags: -Z parse-only
-// ignore-tidy-linelength
 
 fn main() {
     let y = 0;
     //~^ ERROR unknown start of token: \u{37e}
-    //~^^ HELP unicode character ';' (Greek Question Mark) looks much like ';' (Semicolon), but it's not
+    //~^^ HELP unicode character ';' (Greek Question Mark) looks like ';' (Semicolon), but it's not
 }
index 023f2218b87ae7e7afaf853e5d953b53363da95e..b41e8e9226b326e43f87d5eacf0d83f2d27064c0 100644 (file)
@@ -20,6 +20,8 @@
 trait Sized {}
 #[lang = "copy"]
 trait Copy {}
+#[lang = "freeze"]
+trait Freeze {}
 
 #[cfg(target_has_atomic = "8")]
 pub unsafe fn atomic_u8(x: *mut u8) {
index 656e90d2d52d7e0f57cf3f1d1add2791df92bd7a..723a98bcdfa0d85a894e7aea8d20739afdc0aff0 100644 (file)
@@ -15,7 +15,6 @@
 // like to revisit these and potentially change them. --nmatsakis
 
 #![feature(never_type)]
-#![feature(loop_break_value)]
 
 trait BadDefault {
     fn default() -> Self;
index 4906a8e71d7a4fad61a4d5b57bbedb7e4d5f7500..1d5c83bc20d9554c3244eaa3d7513d1982d7f255 100644 (file)
@@ -8,7 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(loop_break_value)]
 #![feature(never_type)]
 
 #[allow(unused)]
index cfa9f6e36e9bcb37fce6b735ed61b6e3d925ff08..372d4a8b732acfb44151cd560e3d489653ffd179 100644 (file)
@@ -82,7 +82,7 @@ pub fn main() {
     short.next();
     assert_eq!(long.size_hint(), (255, Some(255)));
     assert_eq!(short.size_hint(), (0, Some(0)));
-    assert_eq!(short, RangeInclusive::Empty { at: 42 });
+    assert_eq!(short, 1...0);
 
     assert_eq!(long.len(), 255);
     assert_eq!(short.len(), 0);
@@ -97,28 +97,28 @@ pub fn main() {
     for i in 3...251 {
         assert_eq!(long.next(), Some(i));
     }
-    assert_eq!(long, RangeInclusive::Empty { at: 251 });
+    assert_eq!(long, 1...0);
 
     // check underflow
     let mut narrow = 1...0;
     assert_eq!(narrow.next_back(), None);
-    assert_eq!(narrow, RangeInclusive::Empty { at: 0 });
+    assert_eq!(narrow, 1...0);
     let mut zero = 0u8...0;
     assert_eq!(zero.next_back(), Some(0));
     assert_eq!(zero.next_back(), None);
-    assert_eq!(zero, RangeInclusive::Empty { at: 0 });
+    assert_eq!(zero, 1...0);
     let mut high = 255u8...255;
     assert_eq!(high.next_back(), Some(255));
     assert_eq!(high.next_back(), None);
-    assert_eq!(high, RangeInclusive::Empty { at: 255 });
+    assert_eq!(high, 1...0);
 
     // what happens if you have a nonsense range?
     let mut nonsense = 10...5;
     assert_eq!(nonsense.next(), None);
-    assert_eq!(nonsense, RangeInclusive::Empty { at: 10 });
+    assert_eq!(nonsense, 10...5);
 
     // output
     assert_eq!(format!("{:?}", 0...10), "0...10");
     assert_eq!(format!("{:?}", ...10), "...10");
-    assert_eq!(format!("{:?}", long), "[empty range @ 251]");
+    assert_eq!(format!("{:?}", long), "1...0");
 }
diff --git a/src/test/rustdoc/inline_cross/auxiliary/renamed-via-module.rs b/src/test/rustdoc/inline_cross/auxiliary/renamed-via-module.rs
new file mode 100644 (file)
index 0000000..9f7a259
--- /dev/null
@@ -0,0 +1,19 @@
+// Copyright 2017 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.
+
+#![crate_name = "foo"]
+
+pub mod iter {
+    mod range {
+        pub struct StepBy;
+    }
+    pub use self::range::StepBy as DeprecatedStepBy;
+    pub struct StepBy;
+}
diff --git a/src/test/rustdoc/inline_cross/renamed-via-module.rs b/src/test/rustdoc/inline_cross/renamed-via-module.rs
new file mode 100644 (file)
index 0000000..a4e0154
--- /dev/null
@@ -0,0 +1,34 @@
+// Copyright 2017 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.
+
+// aux-build:renamed-via-module.rs
+// build-aux-docs
+// ignore-cross-compile
+
+#![crate_name = "bar"]
+
+extern crate foo;
+
+// @has foo/iter/index.html
+// @has - '//a/[@href="struct.DeprecatedStepBy.html"]' "DeprecatedStepBy"
+// @has - '//a/[@href="struct.StepBy.html"]' "StepBy"
+// @has foo/iter/struct.DeprecatedStepBy.html
+// @has - '//h1' "Struct foo::iter::DeprecatedStepBy"
+// @has foo/iter/struct.StepBy.html
+// @has - '//h1' "Struct foo::iter::StepBy"
+
+// @has bar/iter/index.html
+// @has - '//a/[@href="struct.DeprecatedStepBy.html"]' "DeprecatedStepBy"
+// @has - '//a/[@href="struct.StepBy.html"]' "StepBy"
+// @has bar/iter/struct.DeprecatedStepBy.html
+// @has - '//h1' "Struct bar::iter::DeprecatedStepBy"
+// @has bar/iter/struct.StepBy.html
+// @has - '//h1' "Struct bar::iter::StepBy"
+pub use foo::iter;
index 6083a82b1b6de29eb926114b8b6a37a58b31884c..a30d4cbd64c22e84e4362a5230c496d944c63568 100644 (file)
@@ -6,5 +6,5 @@ error[E0507]: cannot move out of captured outer variable in an `Fn` closure
 15 |     Box::new(|| x) //~ ERROR cannot move out of captured outer variable
    |                 ^ cannot move out of captured outer variable in an `Fn` closure
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index dbfcb2e0c2f95fbef0c71d52e7ed596c37c334eb..a13971d32de084bc50f950fcd466c44074828eb8 100644 (file)
@@ -7,5 +7,5 @@ error[E0507]: cannot move out of captured outer variable in an `Fn` closure
 21 |         y.into_iter();
    |         ^ cannot move out of captured outer variable in an `Fn` closure
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index 0aafe3f17b3d0f6310b30d10baedc9eb00d19cef..0cb264ff35e4eb0ffd5b491e6611a19b2c38d92d 100644 (file)
@@ -46,5 +46,5 @@ error[E0004]: non-exhaustive patterns: `Some(B)`, `Some(C)`, `Some(D)` and 2 mor
 49 |     match Some(A) {
    |           ^^^^^^^ patterns `Some(B)`, `Some(C)`, `Some(D)` and 2 more not covered
 
-error: aborting due to 8 previous errors
+error: aborting due to previous error(s)
 
index 87255dfe7747673b7be9b215df55da55c16fb64c..cddc7df85ae3e763d8336c0705a015323cb4010d 100644 (file)
@@ -22,5 +22,5 @@ error: expected token: `,`
    |
    = note: this error originates in a macro outside of the current crate
 
-error: aborting due to 3 previous errors
+error: aborting due to previous error(s)
 
index 7f1ab929c6fc2b32fcbd4e0a18cd4341d08da5e8..1c32ce44109ed2002e047b0bc9414d61a27ef45d 100644 (file)
@@ -6,5 +6,5 @@ error[E0592]: duplicate definitions with name `f`
 15 | impl C { fn f() {} }
    |          --------- other definition for `f`
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index b33dee6b4a472ed04086888a61d93accf8f11e91..84e6e336b9343dfcad1ff05d48f97dade5f97f01 100644 (file)
@@ -4,5 +4,5 @@ error[E0321]: cross-crate traits with a default impl, like `std::marker::Send`,
 17 |     unsafe impl Send for &'static Foo { }
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index 7bb69caa1024af4c060687c83e5bc9ba41a59a5e..059215157ec52ba715e106d6bfecc11c8e6feceb 100644 (file)
@@ -7,5 +7,5 @@ error: cannot borrow immutable local variable `x` as mutable
 100 |     let y = &mut x;
     |                  ^ cannot borrow mutably
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index 4947cbedd200e45ec424e508881480505c313b57..dcc21672c56323b3c4d6f95505bf9a396463a9a8 100644 (file)
@@ -8,5 +8,5 @@ error[E0499]: cannot borrow `x` as mutable more than once at a time
 101 | }
     | - first borrow ends here
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index d65b34f3f4164cf8dd7b912d4c777155240b9813..5e611d42a1491236eadd99dfc2f5c75e1edd3640 100644 (file)
@@ -6,5 +6,5 @@ error: cannot apply unary operator `!` to type `&'static str`
    |
    = note: this error originates in a macro outside of the current crate
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index a73575a8d57f1ae65783eec6492c758db02c3c5c..e2e0537226a92cff78795cff18bb17bb17c22eef 100644 (file)
@@ -7,5 +7,5 @@ error[E0499]: cannot borrow `v` as mutable more than once at a time
    |     |      second mutable borrow occurs here
    |     first mutable borrow occurs here
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index de8a24cf33f44c12f0e70d3dbf57e99101a67e09..0af8c06cfdae71c0bbaa57991bbde19c68450313 100644 (file)
@@ -25,5 +25,5 @@ error[E0592]: duplicate definitions with name `baz`
 43 |     fn baz(&self) {}
    |     ---------------- other definition for `baz`
 
-error: aborting due to 3 previous errors
+error: aborting due to previous error(s)
 
index d32b18d670308c4379da0ed8060db3694a1f1bdd..9778015766ce55489807c5376526b84e30a1a04c 100644 (file)
@@ -7,5 +7,5 @@ error[E0509]: cannot move out of type `S`, which implements the `Drop` trait
    |         |    hint: to prevent move, use `ref _s` or `ref mut _s`
    |         cannot move out of here
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index 657deca4e6d491afc2398aa5e4c4da6bda8df00a..a3b76159b463fa9d3de9db2a82740d40d286e192 100644 (file)
@@ -4,5 +4,5 @@ error[E0425]: cannot find value `bar` in this scope
 14 | \tbar;
    | \t^^^ not found in this scope
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index eef8793511529fab5d904d6b766ce8b8a263d96b..a6e3cf8b869f06b587906907e2102018ba1918df 100644 (file)
@@ -4,5 +4,5 @@ error: invalid ABI: expected one of [cdecl, stdcall, fastcall, vectorcall, aapcs
 11 | extern "路濫狼á́́" fn foo() {}
    |        ^^^^^^^^
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index 8f08ff34637707851e48ec63c00a0745e980aa6a..28a99e58eca89d954f8aedb62625a15eb96ea9ac 100644 (file)
@@ -15,5 +15,5 @@ help: consider removing this semicolon:
 14 |     x + 1;
    |          ^
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index 2a707c6eb8b103b428de32c4fb5f2c64f848b38a..63c48ffe26b28478f36a2149c9dc29b26c5e3411 100644 (file)
@@ -11,5 +11,5 @@ error[E0276]: impl has stricter requirements than trait
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #37166 <https://github.com/rust-lang/rust/issues/37166>
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index af974d501839b35cb76d8ac7c746c244e25d4b6a..7adcc66d75c892b2eee2c83344b9ddc2eef7e855 100644 (file)
@@ -10,5 +10,5 @@ error[E0276]: impl has stricter requirements than trait
 22 | |     }
    | |_____^ impl has extra requirement `'a: 'b`
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index e657813221a1265e9854a8728e4055a91be39df2..a29a292ac655656eaa3f1559ff9e0f3d0fbf9adb 100644 (file)
@@ -7,5 +7,5 @@ error[E0276]: impl has stricter requirements than trait
 22 |     fn foo() where 'a: 'b { }
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^ impl has extra requirement `'a: 'b`
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index 9e822bd8b0790097ff4832bd78edadf41677b8e9..04de54cd05de215017b8fcf7d49680cab1eb33b9 100644 (file)
@@ -11,5 +11,5 @@ error[E0276]: impl has stricter requirements than trait
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #37166 <https://github.com/rust-lang/rust/issues/37166>
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index 4620248e2efeae50747b5af688ea1fabb96e008f..b5e9c89f2f591293daaac81bc912b65b7a01fea8 100644 (file)
@@ -10,5 +10,5 @@ error[E0053]: method `b` has an incompatible type for trait
    = note: expected type `fn(&E, F) -> F`
               found type `fn(&E, G) -> G`
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index 7112a00c7b7900fd7f305fbc1b79f71a044d21e4..c4a4921289b3b56100d0da4946316f603b470af2 100644 (file)
@@ -7,5 +7,5 @@ error[E0276]: impl has stricter requirements than trait
 25 |     fn b<F: Sync, G>(&self, _x: F) -> F { panic!() } //~ ERROR E0276
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl has extra requirement `F: std::marker::Sync`
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index f221ebe3302c019dadf23280d4904b519a7955a6..6374b83e7946a10402671a5cec8b74832a48d3a0 100644 (file)
@@ -61,5 +61,5 @@ error[E0276]: impl has stricter requirements than trait
 76 |     fn method<G: Getter<usize>>(&self) {}
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl has extra requirement `G: Getter<usize>`
 
-error: aborting due to 7 previous errors
+error: aborting due to previous error(s)
 
index 622e144c53a040447103654b7fb552c79d68c5b0..7ff2d93d820dbde51ca05bac13433999749ee20b 100644 (file)
@@ -10,5 +10,5 @@ error[E0276]: impl has stricter requirements than trait
 26 | |     }
    | |_____^ impl has extra requirement `U: Iterator<B>`
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index 84db85ac092dbfbf3d199d7d489ca97983da83db..3642a702a82955838cafc8b01e27df0e3cf247d1 100644 (file)
@@ -6,5 +6,5 @@ error: invalid reference to argument `0` (no arguments given)
    |
    = note: this error originates in a macro outside of the current crate
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index 15e7131cfd3be41a75621b24e212971643909267..bcf00df98323bd96a98b2f463bdc9c16698975ad 100644 (file)
@@ -22,5 +22,5 @@ error[E0178]: expected a path on the left-hand side of `+`, not `fn() -> Foo`
 17 |     z: fn() -> Foo + 'a,
    |        ^^^^^^^^^^^^^^^^ perhaps you forgot parentheses?
 
-error: aborting due to 4 previous errors
+error: aborting due to previous error(s)
 
index 9010de081da46b602e3db93efa77d54165c9f1c6..73b8e06183b25cf07732cffaae678c30989ff805 100644 (file)
@@ -8,5 +8,5 @@ error[E0277]: the trait bound `Bar: Foo<usize>` is not satisfied
              <Bar as Foo<i32>>
              <Bar as Foo<u8>>
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index e9591a64784d5ad6dff8f3a96648d5a7b16194ce..e1e4e14b215c08617a251ae4253cc5c6b2270c29 100644 (file)
@@ -11,5 +11,5 @@ error[E0277]: the trait bound `Bar: Foo<usize>` is not satisfied
              <Bar as Foo<u8>>
            and 2 others
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index 60fa06d314ff7bcf7da74a8c2f8a7fa53f1750d7..1bd8d5128337ac96d6fff5420232e759482a701f 100644 (file)
@@ -15,5 +15,5 @@ error: cannot borrow immutable argument `self` as mutable
 23 |         (&mut self).bar();
    |               ^^^^ cannot borrow mutably
 
-error: aborting due to 2 previous errors
+error: aborting due to previous error(s)
 
index 8011298c80cdded1bf74963020c99171972c61ea..606d6b2b259861455ce179b65e710d9ef7714cb4 100644 (file)
@@ -7,5 +7,5 @@ error: cannot borrow immutable argument `self` as mutable
    |                       try removing `&mut` here
    |                       cannot reborrow mutably
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index d658912835b9c438ae889474b8ceccb589b0ad09..c32fb56f61be0b042878d24d3e67cf2c9f590b1a 100644 (file)
@@ -7,5 +7,5 @@ error: cannot borrow immutable local variable `key` as mutable
    |              try removing `&mut` here
    |              cannot reborrow mutably
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index bea3d1291433db20d39470c6b61ecb951edad56d..09a9b796c6a461824ad6b443fcbc3bcdcf67f4dd 100644 (file)
@@ -22,5 +22,5 @@ error: cannot assign to immutable field `s.x`
 30 |     s.x += 1;
    |     ^^^^^^^^ cannot mutably borrow immutable field
 
-error: aborting due to 3 previous errors
+error: aborting due to previous error(s)
 
index c124747c801d87dcb595a4436541dd0dec905e7e..ea628f10e0fd615571442c423842dc1586c66bd3 100644 (file)
@@ -4,5 +4,5 @@ error: no field `baz` on type `Foo`
 17 |     f.baz;
    |       ^^^ did you mean `bar`?
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index 4e02f8bd0cfb2d1a81087215074cd7ebfdbc7ff5..a9090e3911b07e65464a53c4c9715a45c77fffb1 100644 (file)
@@ -4,5 +4,5 @@ error: no field `zz` on type `Foo`
 17 |     f.zz;
    |       ^^ unknown field
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index b1a8231fdb6cfd613ed8d206733d147307992b7b..acbeaafdf798d66fbc48d4fda09c51a8d6dd1c8b 100644 (file)
@@ -7,5 +7,5 @@ error: cannot borrow immutable local variable `x` as mutable
    |                       try removing `&mut` here
    |                       cannot reborrow mutably
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index 325f55e686c622e12ec5772512392b0a1e70f460..10f5972e36946554f4f304dbcc2cfc9a1ac38982 100644 (file)
@@ -10,5 +10,5 @@ error[E0432]: unresolved import `Foo1`
 13 | use Foo1;
    |     ^^^^ no `Foo1` in the root
 
-error: aborting due to 2 previous errors
+error: aborting due to previous error(s)
 
index e9f2b1dad806d52429b48060b5a1136315856584..85eecd037dd7badbe71bfbe844e7a2b8923a39cb 100644 (file)
@@ -6,5 +6,5 @@ error[E0389]: cannot borrow data mutably in a `&` reference
 27 |         self.s.push('x');
    |         ^^^^^^ assignment into an immutable reference
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index 855feaf7d2d5e6931e58b0081234dfb866e4a70a..83d46e3fc47271409a4e3c2dbf43dc9fdf9f7e72 100644 (file)
@@ -7,5 +7,5 @@ error: cannot borrow immutable borrowed content `*self.s` as mutable
 17 |         self.s.push('x');
    |         ^^^^^^ cannot borrow as mutable
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index d970d078df8d96c395d088d5a32b442df964ee88..ca6f376ffd301c9682b0740b6d2767e63d4b98a2 100644 (file)
@@ -7,5 +7,5 @@ error: cannot borrow immutable borrowed content `*self.s` as mutable
 17 |         self.s.push('x');
    |         ^^^^^^ cannot borrow as mutable
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index 9a8853f4fbbdb15dfe2bfa8330db4c5b4d4e8344..6fa152c970bdfe2227ff41634a4818cb52170ae3 100644 (file)
@@ -6,5 +6,5 @@ error[E0389]: cannot borrow data mutably in a `&` reference
 16 |     f.s.push('x');
    |     ^^^ assignment into an immutable reference
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index 2e98bc65e9e9f0c268e3badf0b5e61bdc11f914a..9ae240bf420a5bfc176bcba5ef36e3a284d878ea 100644 (file)
@@ -96,5 +96,5 @@ error: cannot assign to immutable borrowed content `*x.0`
 58 |     *x.0 = 1;
    |     ^^^^^^^^ cannot borrow as mutable
 
-error: aborting due to 12 previous errors
+error: aborting due to previous error(s)
 
index 4ea4adfcfe0fc68260f9dc047f487db7cc6eea17..6a0e94bf13803d3cd74e02c22a2ace99d1f6384a 100644 (file)
@@ -39,5 +39,5 @@ error[E0277]: the trait bound `bool: Foo<i32>` is not satisfied
            and 2 others
    = note: required by `Foo::bar`
 
-error: aborting due to 3 previous errors
+error: aborting due to previous error(s)
 
index 8e8773eba3e222feb5c31bbe4f2029a69ef5df5d..b1dab01d81ff2637d5b8bdeba494846ba52f6c56 100644 (file)
@@ -64,5 +64,5 @@ error[E0038]: the trait `X` cannot be made into an object
    |
    = note: method `xxx` has no receiver
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index 1a0c74dc01a09d4eb96735e0253f8215220ed082..daee8df7ed89b219618a15b1321cc2b82837713d 100644 (file)
@@ -30,5 +30,5 @@ error: chained comparison operators require parentheses
    |
    = help: use `::<...>` instead of `<...>` if you meant to specify type arguments
 
-error: aborting due to 4 previous errors
+error: aborting due to previous error(s)
 
index 8e77ebd9b6da3c1920166533f804014793c63703..5718471527d88459b31e6948d0cb45b76d55093c 100644 (file)
@@ -4,5 +4,5 @@ error: cannot borrow immutable borrowed content `*buf` as mutable
 13 |     buf.iter_mut();
    |     ^^^ cannot borrow as mutable
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index 2abbbf65ba9b507254cef20ec002e58cf760aea5..4f210bb0b11b2d7ca60a359eb2c83961dee8a07b 100644 (file)
@@ -6,5 +6,5 @@ error: `~` can not be used as a unary operator
    |
    = help: use `!` instead of `~` if you meant to perform bitwise negation
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index d157c5de6c7f57f98fd213b5da51db9a6015e9be..32f9d90ec2d8d5ea39bbeb72f69536e3dcbcae2e 100644 (file)
@@ -17,5 +17,5 @@ error[E0275]: overflow evaluating the requirement `K: std::marker::Send`
    = note: required because it appears within the type `A`
    = note: required by `is_send`
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index 57b28d037362239f237591faf6eb9dd7d7aa6456..ba8d3815181ac84c282682f0f290826d1fe13663 100644 (file)
@@ -19,5 +19,5 @@ error[E0308]: mismatched types
    = note: expected type `&Bottom`
               found type `&Top`
 
-error: aborting due to 3 previous errors
+error: aborting due to previous error(s)
 
index c4858b63c2d930e4a3af534edf1961a4e17386f8..50e296a1bc53758b491bd1f753e670f9ddcf1a43 100644 (file)
@@ -18,5 +18,5 @@ error[E0038]: the trait `std::marker::Copy` cannot be made into an object
    |
    = note: the trait cannot require that `Self : Sized`
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index 2a4ba22ecc46711cf4cb6f1e06ba5f81eb900c95..b69b4f9f32117957a7f5861a2ed0e3889aa5bf79 100644 (file)
@@ -42,5 +42,5 @@ error: `c` does not live long enough
    |
    = note: values in a scope are dropped in the opposite order they are created
 
-error: aborting due to 4 previous errors
+error: aborting due to previous error(s)
 
index 2c788e952edbfd455b29645f875bdded8cf4eedd..e1bfb4d8c1e181a4feb734c89e70252c9ad0f0c1 100644 (file)
@@ -20,5 +20,5 @@ error[E0569]: requires an `unsafe impl` declaration due to `#[may_dangle]` attri
 43 | | }
    | |_^
 
-error: aborting due to 2 previous errors
+error: aborting due to previous error(s)
 
index cfcf988f31f7b1295ea73bac6d32b2eb44c554cb..ddd213dd9ad7088feaefa06af61e1cae46c0da27 100644 (file)
@@ -42,5 +42,5 @@ error: `c` does not live long enough
    |
    = note: values in a scope are dropped in the opposite order they are created
 
-error: aborting due to 4 previous errors
+error: aborting due to previous error(s)
 
index cd420756b444c81f207a8785b121e04637cf9dd1..d9d00919b6dcac704d56ef4928822d86f5127e82 100644 (file)
@@ -42,5 +42,5 @@ error: `c` does not live long enough
    |
    = note: values in a scope are dropped in the opposite order they are created
 
-error: aborting due to 4 previous errors
+error: aborting due to previous error(s)
 
index 58b392f0b8d658fc1df9896a3568b05b9338bf23..2466d2b43b6fcd648f325d5f44b146a2177cfaa4 100644 (file)
@@ -16,5 +16,5 @@ error: invalid format string: unmatched `}` found
    = note: if you intended to print `}`, you can escape it using `}}`
    = note: this error originates in a macro outside of the current crate
 
-error: aborting due to 2 previous errors
+error: aborting due to previous error(s)
 
index 322ab64ebd4eac2424b1e0eceefe84a5f0075ae9..91c89e55c54a824d205081ab9c8c44d8557beb5c 100644 (file)
@@ -8,5 +8,5 @@ error[E0382]: use of moved value: `debug_dump_dict`
    |
    = help: closure was moved because it only implements `FnOnce`
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index bd024d6766eda590a809243fed7daa8407a51714..a08e77a2151e210c98916a99200a1848e2b9a60e 100644 (file)
@@ -11,9 +11,9 @@ error[E0277]: the trait bound `u32: std::ops::Add<impl Foo>` is not satisfied
   --> $DIR/equality.rs:34:9
    |
 34 |         n + sum_to(n - 1)
-   |         ^^^^^^^^^^^^^^^^^ the trait `std::ops::Add<impl Foo>` is not implemented for `u32`
+   |         ^^^^^^^^^^^^^^^^^ no implementation for `u32 + impl Foo`
    |
-   = note: no implementation for `u32 + impl Foo`
+   = help: the trait `std::ops::Add<impl Foo>` is not implemented for `u32`
 
 error[E0308]: mismatched types
   --> $DIR/equality.rs:53:18
@@ -51,5 +51,5 @@ error[E0308]: mismatched types
    = note: expected type `impl Foo` (i32)
               found type `impl Foo` (u32)
 
-error: aborting due to 6 previous errors
+error: aborting due to previous error(s)
 
index 3e9b21cdb740fc072a1779e128acb49be55d7df2..a444d5f5a40308bbae8a182f8392b831e1db5b5c 100644 (file)
@@ -10,5 +10,5 @@ note: maybe move this module `$DIR/auxiliary/foo/bar.rs` to its own directory vi
 11 | pub mod baz;
    |         ^^^
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index b51b683a1ac3a5de798a8e3feaea1d315159574d..62223c553e377a7e9f91cd6adea6c238fb9d82a2 100644 (file)
@@ -8,5 +8,5 @@ error: reached the type-length limit while instantiating `<T as Foo><(&(&(&(&(&(
    |
    = note: consider adding a `#![type_length_limit="2097152"]` attribute to your crate
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index de110ac12b70398a3fc7f8d6ca7f051f71ff73b1..80f608c1d371040075d466165e1a1b6e75419f88 100644 (file)
@@ -7,5 +7,5 @@ error[E0507]: cannot move out of indexed content
    |             help: consider using a reference instead `&f.v[0]`
    |             cannot move out of indexed content
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index 0060b683bba43637789a732186b8de60b21e75f5..d35800ac1e766f67d9dfca9ad611d5ac56b8ec77 100644 (file)
@@ -7,5 +7,5 @@ error[E0507]: cannot move out of indexed content
    |          |  ...and here (use `ref b` or `ref mut b`)
    |          hint: to prevent move, use `ref a` or `ref mut a`
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index 4d33a99f6a38c47b37981666bd7d45df1edce3bf..a0177e79ac467b4445e94011d51f6d4bb7ba40ba 100644 (file)
@@ -8,5 +8,5 @@ error: no method named `f` found for type `{integer}` in the current scope
 note: candidate #1 is defined in the trait `issue_41652_b::Tr`
    = help: to disambiguate the method call, write `issue_41652_b::Tr::f(3)` instead
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index f325d10b548735ca04af219b6f7a044777fd9786..0ab24b0b3e6c417bb035f4df923ad9865b523c85 100644 (file)
@@ -19,5 +19,5 @@ note: ...but the borrowed content is only valid for the anonymous lifetime #1 de
 13 | | }
    | |_^
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index fccc44caac81a5f7e25b11cdb0ca893266387bd7..d005eeb40451ad8f9855665c8f10368510bc031d 100644 (file)
@@ -6,5 +6,5 @@ error[E0106]: missing lifetime specifier
    |
    = help: this function's return type contains a borrowed value, but the signature does not say whether it is borrowed from `x` or `y`
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index df484a14927c737ce514e9ab27e550585b7a6330..7d0947b364e03ff2318b3aaa4421f460d6667a09 100644 (file)
@@ -21,5 +21,5 @@ note: ...does not necessarily outlive the lifetime 'a as defined on the function
 17 | | }
    | |_^
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index 6764c58f4bb59aeb1b9b345eab5f840ba0032c48..6380a885f4467ddaf2a783ccb7716c454782fb4e 100644 (file)
@@ -21,5 +21,5 @@ note: ...does not necessarily outlive the anonymous lifetime #2 defined on the f
 17 | | }
    | |_^
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index 7356fc11862f6e104d004cd642852161b18e5e1b..b28a3c0c1351da9662f025cbb0f832a961146a13 100644 (file)
@@ -31,5 +31,5 @@ note: ...so that expression is assignable (expected Ref<'b, _>, found Ref<'_, _>
 17 |     x.push(z);
    |            ^
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index 38b0acf9339e0e89595a6c0ee889abca1f2c221e..dd716bac513d2eab4fceba362c4f54de6983295a 100644 (file)
@@ -33,5 +33,5 @@ note: ...so that expression is assignable (expected &mut std::vec::Vec<Ref<'_, i
 16 |     let a: &mut Vec<Ref<i32>> = x;
    |                                 ^
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index 035e516e8628e9b933157645e651ef281f272c01..141f5a7c4528b1e55ec504aae50ab10bac9f3f41 100644 (file)
@@ -33,5 +33,5 @@ note: ...so that expression is assignable (expected &mut std::vec::Vec<Ref<'_, i
 16 |     let a: &mut Vec<Ref<i32>> = x;
    |                                 ^
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index d85483f43c9e02dfb57a38b5551da5e8d475237a..768057301d1263dfc79fc1ef70b09786203a5723 100644 (file)
@@ -10,5 +10,5 @@ error: borrowed value does not live long enough
    |
    = note: consider using a `let` binding to increase its lifetime
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index 23fac66cc6c98f60ba85966bc8c10f565bd4ee3e..d441702374b74dc42a3b8796a93ea26daf05f801 100644 (file)
@@ -6,5 +6,5 @@ error: variable `_InappropriateCamelCasing` should have a snake case name such a
    |
    = note: `-D non-snake-case` implied by `-D bad-style`
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index 0babd7f6fe47a06dbaccf37ad6790a8b15d2bb45..9d4d0b12b187071d0311e4ed3e81faeb3f13ded1 100644 (file)
@@ -6,5 +6,5 @@ error: variable `_InappropriateCamelCasing` should have a snake case name such a
    |
    = note: `-F non-snake-case` implied by `-F bad-style`
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index 9c0f4866af6902e43ff1eac30e998fcb0d0543d8..dec44c317e4b2f4c1eafb54251d74d4b443e685e 100644 (file)
@@ -63,5 +63,5 @@ note: lint level defined here
 28 |         #![warn(bad_style)]
    |                 ^^^^^^^^^
 
-error: aborting due to 3 previous errors
+error: aborting due to previous error(s)
 
index 790f796fae07f787a64fba8266b46ede5ed7bb65..b52d540fd75119dc5d24c87f7ca06f9888f5a4ab 100644 (file)
@@ -8,7 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(loop_break_value)]
 #![allow(unused_variables)]
 
 use std::ptr;
index 0d99abd3907d81b40a67e8959a1d9edf747db9f5..7a4a9c3f012bf9d082a30af769b45f3614a861cc 100644 (file)
@@ -1,8 +1,8 @@
 error[E0571]: `break` with value from a `for` loop
-  --> $DIR/loop-break-value-no-repeat.rs:23:9
+  --> $DIR/loop-break-value-no-repeat.rs:22:9
    |
-23 |         break 22
+22 |         break 22
    |         ^^^^^^^^ can only break with a value inside `loop`
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index bffb33f468fc886c7c10433111713bb242add472..b8337c81834b89e6efcf9ae2857838405f526216 100644 (file)
@@ -4,5 +4,5 @@ error: expected a literal
 12 |     println!(3 + 4);
    |              ^^^^^
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index 0283052a89f53d19a128cd8cb4836f7dbae769c2..a964b92712ddb00711621b6f2eb3c0ef8e9861e3 100644 (file)
@@ -48,5 +48,5 @@ error: named argument never used
    = help: `$NAME` should be written as `{NAME}`
    = note: shell formatting not supported; see the documentation for `std::fmt`
 
-error: aborting due to 4 previous errors
+error: aborting due to previous error(s)
 
index 48f9bac906ecf56a0108f03059234f9f346e47a8..304d4459e4975dda4306e604f88961676e2b80bc 100644 (file)
@@ -52,5 +52,5 @@ error: attempted tuple index `0` on type `{integer}`, but the type was not a tup
 56 |     let _ = fake_anon_field_expr!();
    |             ----------------------- in this macro invocation
 
-error: aborting due to 6 previous errors
+error: aborting due to previous error(s)
 
index 8b69d112d4d42b8390db27b5a03056557656aa02..7835b85eafc0e8821889ec8abb9f7222a50de6ee 100644 (file)
@@ -16,5 +16,5 @@ error[E0425]: cannot find value `fake` in this scope
 28 |     call_nested_expr_sum!();
    |     ------------------------ in this macro invocation
 
-error: aborting due to 2 previous errors
+error: aborting due to previous error(s)
 
index f21253bb67fb0c10e46458e63aa3997d639283cf..4177240d97696d2693bff7b8824de62c0bca7425 100644 (file)
@@ -7,5 +7,5 @@ error: invalid reference to argument `0` (no arguments given)
 28 |     myprintln!("{}");
    |     ----------------- in this macro invocation
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index d9871b8970c5cf22b1cd32b70b5b34bbc8f4c32d..2ba2069677e3d9f1cb41225fb6995acbe84e5f88 100644 (file)
@@ -22,5 +22,5 @@ error[E0053]: method `bar` has an incompatible type for trait
    = note: expected type `fn(&Bar)`
               found type `fn(&mut Bar)`
 
-error: aborting due to 2 previous errors
+error: aborting due to previous error(s)
 
index 28a649d4c91a471acb22e8c8e1220fe5ecd71da2..fab48e9a740a29ed4de52b1010d09368dde86432 100644 (file)
@@ -20,5 +20,5 @@ error[E0281]: type mismatch: `[closure@$DIR/E0281.rs:14:9: 14:24]` implements th
    |
    = note: required by `foo`
 
-error: aborting due to 2 previous errors
+error: aborting due to previous error(s)
 
index 45a42b1c271f8678920ca841580d814aa62f6498..a5f63aca13e2170128675f077be1d1e3a3d588d0 100644 (file)
@@ -15,5 +15,5 @@ error[E0308]: mismatched types
    = note: expected type `&{integer}`
               found type `{integer}`
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index 36bdec8d43afef1b9ca5fba171743cca1963002b..78b5dcda1d9d24be75b73276e29c1cdc7a77b8ab 100644 (file)
@@ -64,5 +64,5 @@ error[E0308]: mismatched types
    = note: expected type `X<X<_, std::string::String>, _>`
               found type `X<X<_, {integer}>, _>`
 
-error: aborting due to 6 previous errors
+error: aborting due to previous error(s)
 
index a0f7ff6587097bedc2ed08f3bc2e22af36f918ce..d97c78137089ec721e9ee55db27a960e5077f963 100644 (file)
@@ -2,57 +2,57 @@ error[E0277]: the trait bound `{integer}: std::ops::Add<std::option::Option<{int
   --> $DIR/binops.rs:12:5
    |
 12 |     1 + Some(1);
-   |     ^^^^^^^^^^^ the trait `std::ops::Add<std::option::Option<{integer}>>` is not implemented for `{integer}`
+   |     ^^^^^^^^^^^ no implementation for `{integer} + std::option::Option<{integer}>`
    |
-   = note: no implementation for `{integer} + std::option::Option<{integer}>`
+   = help: the trait `std::ops::Add<std::option::Option<{integer}>>` is not implemented for `{integer}`
 
 error[E0277]: the trait bound `usize: std::ops::Sub<std::option::Option<{integer}>>` is not satisfied
   --> $DIR/binops.rs:13:5
    |
 13 |     2 as usize - Some(1);
-   |     ^^^^^^^^^^^^^^^^^^^^ the trait `std::ops::Sub<std::option::Option<{integer}>>` is not implemented for `usize`
+   |     ^^^^^^^^^^^^^^^^^^^^ no implementation for `usize - std::option::Option<{integer}>`
    |
-   = note: no implementation for `usize - std::option::Option<{integer}>`
+   = help: the trait `std::ops::Sub<std::option::Option<{integer}>>` is not implemented for `usize`
 
 error[E0277]: the trait bound `{integer}: std::ops::Mul<()>` is not satisfied
   --> $DIR/binops.rs:14:5
    |
 14 |     3 * ();
-   |     ^^^^^^ the trait `std::ops::Mul<()>` is not implemented for `{integer}`
+   |     ^^^^^^ no implementation for `{integer} * ()`
    |
-   = note: no implementation for `{integer} * ()`
+   = help: the trait `std::ops::Mul<()>` is not implemented for `{integer}`
 
 error[E0277]: the trait bound `{integer}: std::ops::Div<&str>` is not satisfied
   --> $DIR/binops.rs:15:5
    |
 15 |     4 / "";
-   |     ^^^^^^ the trait `std::ops::Div<&str>` is not implemented for `{integer}`
+   |     ^^^^^^ no implementation for `{integer} / &str`
    |
-   = note: no implementation for `{integer} / &str`
+   = help: the trait `std::ops::Div<&str>` is not implemented for `{integer}`
 
 error[E0277]: the trait bound `{integer}: std::cmp::PartialEq<std::string::String>` is not satisfied
   --> $DIR/binops.rs:16:5
    |
 16 |     5 < String::new();
-   |     ^^^^^^^^^^^^^^^^^ the trait `std::cmp::PartialEq<std::string::String>` is not implemented for `{integer}`
+   |     ^^^^^^^^^^^^^^^^^ can't compare `{integer}` with `std::string::String`
    |
-   = note: can't compare `{integer}` with `std::string::String`
+   = help: the trait `std::cmp::PartialEq<std::string::String>` is not implemented for `{integer}`
 
 error[E0277]: the trait bound `{integer}: std::cmp::PartialOrd<std::string::String>` is not satisfied
   --> $DIR/binops.rs:16:5
    |
 16 |     5 < String::new();
-   |     ^^^^^^^^^^^^^^^^^ the trait `std::cmp::PartialOrd<std::string::String>` is not implemented for `{integer}`
+   |     ^^^^^^^^^^^^^^^^^ can't compare `{integer}` with `std::string::String`
    |
-   = note: can't compare `{integer}` with `std::string::String`
+   = help: the trait `std::cmp::PartialOrd<std::string::String>` is not implemented for `{integer}`
 
 error[E0277]: the trait bound `{integer}: std::cmp::PartialEq<std::result::Result<{integer}, _>>` is not satisfied
   --> $DIR/binops.rs:17:5
    |
 17 |     6 == Ok(1);
-   |     ^^^^^^^^^^ the trait `std::cmp::PartialEq<std::result::Result<{integer}, _>>` is not implemented for `{integer}`
+   |     ^^^^^^^^^^ can't compare `{integer}` with `std::result::Result<{integer}, _>`
    |
-   = note: can't compare `{integer}` with `std::result::Result<{integer}, _>`
+   = help: the trait `std::cmp::PartialEq<std::result::Result<{integer}, _>>` is not implemented for `{integer}`
 
-error: aborting due to 7 previous errors
+error: aborting due to previous error(s)
 
index 7fd10f3cb689176f9c23ac53a4c5ee3fee518352..8d31dd7500a34f81dcb6fb58dc562a8188fd9089 100644 (file)
@@ -210,18 +210,18 @@ error[E0277]: the trait bound `[u8]: std::marker::Sized` is not satisfied
   --> $DIR/cast-rfc0401.rs:63:13
    |
 63 |     let _ = fat_v as *const Foo;
-   |             ^^^^^ the trait `std::marker::Sized` is not implemented for `[u8]`
+   |             ^^^^^ `[u8]` does not have a constant size known at compile-time
    |
-   = note: `[u8]` does not have a constant size known at compile-time
+   = help: the trait `std::marker::Sized` is not implemented for `[u8]`
    = note: required for the cast to the object type `Foo`
 
 error[E0277]: the trait bound `str: std::marker::Sized` is not satisfied
   --> $DIR/cast-rfc0401.rs:72:13
    |
 72 |     let _ = a as *const Foo;
-   |             ^ the trait `std::marker::Sized` is not implemented for `str`
+   |             ^ `str` does not have a constant size known at compile-time
    |
-   = note: `str` does not have a constant size known at compile-time
+   = help: the trait `std::marker::Sized` is not implemented for `str`
    = note: required for the cast to the object type `Foo`
 
 error: casting `&{float}` as `f32` is invalid
@@ -236,5 +236,5 @@ help: did you mean `*s`?
 81 |     vec![0.0].iter().map(|s| s as f32).collect::<Vec<f32>>();
    |                              ^
 
-error: aborting due to 34 previous errors
+error: aborting due to previous error(s)
 
index c1b880b6162734e5a720e3452086e4a222831800..cd16e5d70b68b6eb423b26e31ae15d6a116308b3 100644 (file)
@@ -55,5 +55,5 @@ error[E0593]: closure takes 1 argument but 2 arguments are required
    |               |
    |               expected closure that takes 2 arguments
 
-error: aborting due to 7 previous errors
+error: aborting due to previous error(s)
 
index 5b3eb5931896aee60c50c0e36b8efa0c97379607..2c9c918168d0299989fe7b508f10199863f19799 100644 (file)
@@ -20,5 +20,5 @@ error[E0281]: type mismatch: `[closure@$DIR/closure-mismatch.rs:18:9: 18:15]` im
    = note: required because of the requirements on the impl of `Foo` for `[closure@$DIR/closure-mismatch.rs:18:9: 18:15]`
    = note: required by `baz`
 
-error: aborting due to 2 previous errors
+error: aborting due to previous error(s)
 
index f7b7635e41aecfec70ad91f99b95fac6a0d944f2..5f67a66eb325fa7e287cf2537d32f24478fcc813 100644 (file)
@@ -10,5 +10,5 @@ error[E0379]: trait fns cannot be declared const
 21 |     const fn f() -> u32 { 22 }
    |     ^^^^^ trait fns cannot be const
 
-error: aborting due to 2 previous errors
+error: aborting due to previous error(s)
 
index 120fb87cdc89820ea2264348dea853e069c8d105..2030ad6c13b56af2ea42f0c0292875a523665914 100644 (file)
@@ -14,5 +14,5 @@ error[E0281]: type mismatch: `fn(&isize) {takes_imm}` implements the trait `for<
    |
    = note: required by `apply`
 
-error: aborting due to 2 previous errors
+error: aborting due to previous error(s)
 
index 4067507c9644568ae3767e92b9aa5b2b1152dcf2..cbce4f810c5312469d168dd7e31798c42ead8e28 100644 (file)
@@ -7,5 +7,5 @@ error[E0308]: mismatched types
    = note: expected type `()`
               found type `*mut Trait`
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index 5d07ee1648a3ecfffe90986405e78bec9e8abfb5..dc3764a376cde4d8443f780a649f194146a1a445 100644 (file)
@@ -16,5 +16,5 @@ error: non-scalar cast: `{integer}` as `()`
 38 |     cast!(2);
    |     --------- in this macro invocation
 
-error: aborting due to 2 previous errors
+error: aborting due to previous error(s)
 
index 46d690c5f037b97ee2235cc51364c663ae642b4a..463d9fdf1717b3cac825bc248ad496976f37cf58 100644 (file)
@@ -7,5 +7,5 @@ error[E0308]: mismatched types
    = note: expected type `bool` (type parameter)
               found type `bool` (bool)
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index 78e0f7e619b12791e7f52b917eb205959da36f9f..d72ab326ce644168cdf3a5cb885ce86b034bbf80 100644 (file)
@@ -26,5 +26,5 @@ error[E0281]: type mismatch: `[closure@$DIR/issue-36053-2.rs:17:39: 17:53]` impl
    |                                requires `for<'r> std::ops::FnOnce<(&'r &str,)>`
    |                                expected &str, found str
 
-error: aborting due to 3 previous errors
+error: aborting due to previous error(s)
 
index 9efee4cc5593cb2ed8c9056c6ff3b985be3d7298..76ffa6e50e133d2e58cad02b4802bf75db98b40e 100644 (file)
@@ -32,5 +32,5 @@ error[E0529]: expected an array or slice, found `u32`
 34 | fn ugh(&[bar]: &u32) {
    |         ^^^^^ pattern cannot match with input type `u32`
 
-error: aborting due to 4 previous errors
+error: aborting due to previous error(s)
 
index c8941fbf950734c021621508ef1ef3129a95af14..b4e688e025e52b23ef87cc54223b8a86f3261375 100644 (file)
@@ -9,5 +9,5 @@ error[E0308]: mismatched types
    = note: expected type `u32`
               found type `()`
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index 2bd786c20fef0285d8050e44ab0eec7f1c1969d7..c7a52fea3bc8c3e0219e69ac0927424fcc6269d4 100644 (file)
@@ -7,5 +7,5 @@ error: no method named `unwrap` found for type `std::result::Result<(), Foo>` in
    = note: the method `unwrap` exists but the following trait bounds were not satisfied:
            `Foo : std::fmt::Debug`
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index cd05684f15d55d71c2157558b6380c8de90f615b..7c644e3a72dcd637e079bb6074c6d3e0c4934d75 100644 (file)
@@ -19,5 +19,5 @@ error[E0057]: this function takes 1 parameter but 2 parameters were supplied
 45 |     let ans = s("burma", "shave");
    |                 ^^^^^^^^^^^^^^^^ expected 1 parameter
 
-error: aborting due to 3 previous errors
+error: aborting due to previous error(s)
 
index ccc9fb56772f5b4e1c6b67b5be3d7bf509caed8e..9e7f79df35aee136652f733d095930b292dc876f 100644 (file)
@@ -7,5 +7,5 @@ error[E0308]: mismatched types
    = note: expected type `std::boxed::Box<Foo + std::marker::Send + 'static>`
               found type `std::boxed::Box<Foo + 'static>`
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index 349432f64bbc20cf4af4839fe604639f2c6f7124..8741589f8464ed8b9a629ebc8975ff2bb9dcc450 100644 (file)
@@ -22,5 +22,5 @@ error[E0053]: method `bar` has an incompatible type for trait
    = note: expected type `fn(&mut Bar, &mut Bar)`
               found type `fn(&mut Bar, &Bar)`
 
-error: aborting due to 2 previous errors
+error: aborting due to previous error(s)
 
index e100520e561f579a25819bdf2d45476275506f40..c5bfb6e45e77e468aabcd6086ed53dc4e5ef9e7b 100644 (file)
@@ -26,5 +26,5 @@ error[E0281]: type mismatch: `[closure@$DIR/unboxed-closures-vtable-mismatch.rs:
    |
    = note: required by `call_it`
 
-error: aborting due to 2 previous errors
+error: aborting due to previous error(s)
 
index fc90c8a2b20bebc39cc4029febe377213a1c61da..878544937905d0907f6a10af8510a54e4ea10c32 100644 (file)
@@ -4,5 +4,5 @@ error[E0004]: non-exhaustive patterns: `C(QA)` not covered
 21 |     match proto {
    |           ^^^^^ pattern `C(QA)` not covered
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index 503ce5618d486db165587ec6ccd283399e0ac5f2..26748d18ffa954ac004fa583d92c45abebce771f 100644 (file)
@@ -11,5 +11,5 @@ error[E0046]: not all trait items implemented, missing: `CONSTANT`, `Type`, `met
    = note: `Type` from trait: `type Type;`
    = note: `method` from trait: `fn(&Self, std::string::String) -> <Self as m1::X>::Type`
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index a16ae5538bf92d2038afae65670a6d6d909c7b1a..ce38178bf87bbfcb962ad807b93761e656f73ca2 100644 (file)
@@ -4,5 +4,5 @@ error[E0282]: type annotations needed
 14 |     foo();
    |     ^^^ cannot infer type for `X`
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index 470e8331247851848b2cecf66b5c87c66d1fd863..94fc8f15c2b9e23346ecd1e71f0d2652051ba2ba 100644 (file)
@@ -4,5 +4,5 @@ error: unmatched visibility `pub`
 13 | pub(crate) () fn foo() {}
    |          ^
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index b8b4c80778d968d05f5296d9a8acb2459e8974dd..eebb2428ba3a5f023d5c2fba73465eefedb7838d 100644 (file)
@@ -4,5 +4,5 @@ error: expected identifier, found `(`
 16 |     pub(crate) () foo: usize,
    |                ^
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index ebfccc4d720451f0e168d5c606792cdb64c68d45..865b1d409e131bfa2e86ed0df3b3a25994047f7b 100644 (file)
@@ -4,5 +4,5 @@ error: expected identifier, found `.`
 13 | pub (.) fn afn() {}
    |      ^
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index ae283f1fb636a151fb913cc8134a623ffff96f9b..34cc80fcc752796e9f480fbe276d64af615b95df 100644 (file)
@@ -48,5 +48,5 @@ error: visibilities can only be restricted to ancestor modules
 33 |         pub (in x) non_parent_invalid: usize,
    |                 ^
 
-error: aborting due to 5 previous errors
+error: aborting due to previous error(s)
 
index 1a2cc252051bfb9dffc07e18fdf0b86b2ff0ed71..cbcbf88d86e7f6c39a3ba88843aee6d4df80ec8a 100644 (file)
@@ -10,5 +10,5 @@ note: lint level defined here
 13 | #![deny(unreachable_code)]
    |         ^^^^^^^^^^^^^^^^
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index bf4e4dc4711cbcfbd6ef39069ae3536ac956a924..20640c0a897b44c562c8658e7bc9847fa34098c5 100644 (file)
@@ -11,5 +11,5 @@ note: lint level defined here
    |         ^^^^^^^^^^^^^^^^
    = note: this error originates in a macro outside of the current crate
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index f8dbdb5f8bb66aa9c6097c5a6d18cb6944e80920..c778aec08108e84c9afd5ec71ca43f3e3be67763 100644 (file)
@@ -16,5 +16,5 @@ error: unreachable expression
 25 |     let x: [usize; 2] = [22, return];
    |                         ^^^^^^^^^^^^
 
-error: aborting due to 2 previous errors
+error: aborting due to previous error(s)
 
index 807f6a1c1d5847eb383d2e1f6bcfcb24ee2f2ea2..9310c000192739124476794271e214c4587f98f9 100644 (file)
@@ -22,5 +22,5 @@ error: unreachable expression
 36 |     *{return; &mut i} = 22;
    |               ^^^^^^
 
-error: aborting due to 3 previous errors
+error: aborting due to previous error(s)
 
index 542ce1c3fd9cb5b49e7f41743d623128be4505bc..ea7b962e190d190c03a7a8237ee776f3e20529c3 100644 (file)
@@ -18,5 +18,5 @@ error: unreachable statement
    |
    = note: this error originates in a macro outside of the current crate
 
-error: aborting due to 2 previous errors
+error: aborting due to previous error(s)
 
index 78ba231cef9fcf2121f0173688ab3710823c13fa..ee89104df9e92413bdac699125cbffb35e9f30ac 100644 (file)
@@ -10,5 +10,5 @@ note: lint level defined here
 13 | #![deny(unreachable_code)]
    |         ^^^^^^^^^^^^^^^^
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index 5526827f59fc9965853df9bc66eb3674e29572ea..5e072ed1dc7abe766ec0e2ef41636a50eda5aba2 100644 (file)
@@ -16,5 +16,5 @@ error: unreachable expression
 28 |     bar(return);
    |     ^^^^^^^^^^^
 
-error: aborting due to 2 previous errors
+error: aborting due to previous error(s)
 
index a22300dcc1398f37c6c0dbee1b349266864a90a1..a8668dc7355c12f6d6ae17d8f06f8f9adf6acbaa 100644 (file)
@@ -10,5 +10,5 @@ note: lint level defined here
 14 | #![deny(unreachable_code)]
    |         ^^^^^^^^^^^^^^^^
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index 2cf17474f6e9dd2ab1ddd152addf393ab004971a..7f901511f7206f281972cdcd1be72ed9cf47926b 100644 (file)
@@ -11,5 +11,5 @@ note: lint level defined here
    |         ^^^^^^^^^^^^^^^^
    = note: this error originates in a macro outside of the current crate
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index 6e98e754c54db30d1078dd882e45d004bfaeec0a..4fb6392f405c218eb4858fe9b6e2ac139aac957c 100644 (file)
@@ -27,5 +27,5 @@ error: unreachable statement
    |
    = note: this error originates in a macro outside of the current crate
 
-error: aborting due to 3 previous errors
+error: aborting due to previous error(s)
 
index f5857a5b345eccbb27c0ee1159574737e9897002..387f7900f4948d86d53b3be53adbee9e24472f5a 100644 (file)
@@ -26,5 +26,5 @@ error: unreachable statement
    |
    = note: this error originates in a macro outside of the current crate
 
-error: aborting due to 3 previous errors
+error: aborting due to previous error(s)
 
index 177d4352a376ddb175125c1425e7e57891a8d659..68fd4973414151cf00e4c4985146e6cf108b552d 100644 (file)
@@ -16,5 +16,5 @@ error: unreachable expression
 31 |     Foo.bar(return);
    |     ^^^^^^^^^^^^^^^
 
-error: aborting due to 2 previous errors
+error: aborting due to previous error(s)
 
index 19afc5dd7b5ee192dc8307c046a6fabaa6d08100..01b2e1009ee0c5507e2cf6c0d41df7c8a877f003 100644 (file)
@@ -10,5 +10,5 @@ note: lint level defined here
 14 | #![deny(unreachable_code)]
    |         ^^^^^^^^^^^^^^^^
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index 3eb70a4dd7c848ecc53b7b50d5ce47035c876da5..ee958aa9089d8e3350705265f9339b47f153bf80 100644 (file)
@@ -10,5 +10,5 @@ note: lint level defined here
 14 | #![deny(unreachable_code)]
    |         ^^^^^^^^^^^^^^^^
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index 4b7ac6604132c165b255200be13f61c49b0ae77f..08866bf32b873abf1d4a0437318e12309183b4de 100644 (file)
@@ -28,5 +28,5 @@ error: unreachable expression
 40 |     let x = Foo { a: 22, b: return };
    |             ^^^^^^^^^^^^^^^^^^^^^^^^
 
-error: aborting due to 4 previous errors
+error: aborting due to previous error(s)
 
index 63f477fd0c373a9a8b37111b1657380e410b8733..780fb02f79037861879cc53c5441e81b1217acc5 100644 (file)
@@ -16,5 +16,5 @@ error: unreachable expression
 25 |     let x: (usize, usize) = (2, return);
    |                             ^^^^^^^^^^^
 
-error: aborting due to 2 previous errors
+error: aborting due to previous error(s)
 
index 6ed79974ccb77c1aea43d4eddfbecc92102215fd..1216ec2676eefe106e40ca1dec343bfa82e3e8da 100644 (file)
@@ -10,5 +10,5 @@ note: lint level defined here
 14 | #![deny(unreachable_code)]
    |         ^^^^^^^^^^^^^^^^
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index 11172652d84450bde5cfa592d09b015c78f99ad1..889e3e01c6daaedd42dcd630cdc4529be745367a 100644 (file)
@@ -4,5 +4,5 @@ error: cannot apply unary operator `!` to type `!`
 18 |     let x: ! = ! { return; 22 };
    |                ^^^^^^^^^^^^^^^^
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index 066cfc86c6462c534a35260d76975bd5c40b091a..3da057f4bbd364ec61a0667518c4ecd378802fc0 100644 (file)
@@ -27,5 +27,5 @@ error: unreachable statement
    |
    = note: this error originates in a macro outside of the current crate
 
-error: aborting due to 3 previous errors
+error: aborting due to previous error(s)
 
index 0c7b44af949b6315588759e19418a5ea30064d01..121a50d0eda172dd0e61a0283b61c9bb9b704880 100644 (file)
@@ -9,5 +9,5 @@ error[E0308]: mismatched types
    = note: lifetime parameter `'b` declared on fn `bar` appears only in the return type, but here is required to be higher-ranked, which means that `'b` must appear in both argument and return types
    = note: this error is the result of a recent bug fix; for more information, see issue #33685 <https://github.com/rust-lang/rust/issues/33685>
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index 17c5d5d15d40479415e0c5503c248ace94e25045..03e80046f679cb69140ee979474c762d8ba1b45a 100644 (file)
@@ -25,5 +25,5 @@ error[E0422]: cannot find struct, variant or union type `C` in module `namespace
 help: possible candidate is found in another module, you can import it into scope
    | use namespaced_enums::Foo::C;
 
-error: aborting due to 3 previous errors
+error: aborting due to previous error(s)
 
index 18eb2fabdacb541d351401a235a146ac198948b1..8aaad906ea28a477e8c7324b2815ed46e1469ade 100644 (file)
@@ -144,5 +144,5 @@ error[E0425]: cannot find value `bah` in this scope
 
 error: main function not found
 
-error: aborting due to 25 previous errors
+error: aborting due to previous error(s)
 
index 63d2ce109142c70116181304aad38511fcb51325..2fbf7d7185da3d3de70cdafcee7a45b43cc8a689 100644 (file)
@@ -9,5 +9,5 @@ help: possible better candidates are found in other modules, you can import them
    | use std::io::Result;
    | use std::thread::Result;
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index c0438abfe43b45cd5458eb302868063ff96c15df..69eeb178dffcca4abf6b12637628fba7e6bafdc0 100644 (file)
@@ -7,5 +7,5 @@ error[E0422]: cannot find struct, variant or union type `E` in this scope
 help: possible candidate is found in another module, you can import it into scope
    | use SomeEnum::E;
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index edc7196d8464570222f235bd0a0b9b3e10947f20..225e31010dabbfd4c0665d04df35e013fcc71b3d 100644 (file)
@@ -4,5 +4,5 @@ error[E0423]: expected function, found struct variant `Foo::Variant`
 16 |     let f = Foo::Variant(42);
    |             ^^^^^^^^^^^^ did you mean `Foo::Variant { /* fields */ }`?
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index 7b14d49af51dd8c79cddd54c83372dd9b8929395..25ee3a02146a70f5c614ae3dd6012440955b7962 100644 (file)
@@ -10,5 +10,5 @@ error[E0423]: expected value, found struct variant `issue_19452_aux::Homura::Mad
 22 |     let homura = issue_19452_aux::Homura::Madoka;
    |                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ did you mean `issue_19452_aux::Homura::Madoka { /* fields */ }`?
 
-error: aborting due to 2 previous errors
+error: aborting due to previous error(s)
 
index fda87de9b9c500bb2f3d151ec33aa14cc7d9ca59..2ca541c161badea97dea7256ca4c1c9a2759c63d 100644 (file)
@@ -11,5 +11,5 @@ note: the cycle begins when processing `<impl at $DIR/issue-23305.rs:15:1: 15:20
    | ^^^^^^^^^^^^^^^^^^^
    = note: ...which then again requires processing `<impl at $DIR/issue-23305.rs:15:1: 15:20>`, completing the cycle.
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index 039887d8da65fe169b5695d5b880f6d1a47f2724..559598dd38ae92cbb882a31d38b240e6babd38e6 100644 (file)
@@ -106,5 +106,5 @@ error[E0424]: expected value, found module `self`
 122 |     self += 1;
     |     ^^^^ `self` value is only available in methods with `self` parameter
 
-error: aborting due to 17 previous errors
+error: aborting due to previous error(s)
 
index 111710d515a92f28c3e4a479913e9fac3bd76c6b..14a2413feee23265c375b56bda9a2de934a9a09a 100644 (file)
@@ -4,5 +4,5 @@ error[E0411]: cannot find type `Self` in this scope
 11 | fn foo(_: Self) {
    |           ^^^^ `Self` is only available in traits and impls
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index 5dbecc4f0c5fa1ca937092b80d39cbb57de8282c..a950075715ac014417aa46f2d1d2cdb57b4b766d 100644 (file)
@@ -4,5 +4,5 @@ error[E0423]: expected value, found trait `Bar`
 20 |     let any: &Any = &Bar; //~ ERROR expected value, found trait `Bar`
    |                      ^^^ not a value
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index 2ef8c830eb2fe5173c8f774a0a1053f75d74a33c..4e1ef25f8033307f32eb48cf52d41fa3c71a8c34 100644 (file)
@@ -6,5 +6,5 @@ error[E0038]: the trait `issue_3907::Foo` cannot be made into an object
    |
    = note: method `bar` has no receiver
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index f6ee0b025bb2e9a78c688d761626b8e03a0b6490..134a4540a8d9e39538814de39db8c61625d6be00 100644 (file)
@@ -7,5 +7,5 @@ error[E0423]: expected value, found struct `Handle`
    |                 did you mean `handle`?
    |                 did you mean `Handle { /* fields */ }`?
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index 72b1578e0d020f055fe12c5d5019aaaa159e40cb..9bdd7ee4fd4b588eff1181c3324aec71b8dd8bf8 100644 (file)
@@ -2,10 +2,10 @@ error[E0277]: the trait bound `I + 'static: std::marker::Sized` is not satisfied
   --> $DIR/issue-5035-2.rs:14:8
    |
 14 | fn foo(_x: K) {} //~ ERROR: `I + 'static: std::marker::Sized` is not satisfied
-   |        ^^ the trait `std::marker::Sized` is not implemented for `I + 'static`
+   |        ^^ `I + 'static` does not have a constant size known at compile-time
    |
-   = note: `I + 'static` does not have a constant size known at compile-time
+   = help: the trait `std::marker::Sized` is not implemented for `I + 'static`
    = note: all local variables must have a statically known size
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index b50295752f2e0a1632558b7d6de3a25a17d4b57d..620958190caf8f739343e3a38ad13dd1d702da1a 100644 (file)
@@ -4,5 +4,5 @@ error[E0423]: expected function, found struct `Monster`
 17 |     let _m = Monster(); //~ ERROR expected function, found struct `Monster`
    |              ^^^^^^^ did you mean `Monster { /* fields */ }`?
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index 4dff2620319e4607dcee7cf5fe92c79bd922a8ab..d25c52eeab3ce9cb31b6464e31cbc464c74a970b 100644 (file)
@@ -46,5 +46,5 @@ error[E0425]: cannot find value `second` in module `m`
 32 |     let b: m::first = m::second; // Misspelled item in module.
    |                          ^^^^^^ did you mean `Second`?
 
-error: aborting due to 8 previous errors
+error: aborting due to previous error(s)
 
index 19940ff4586d2e3baf028f71ebecec7ba96804f9..b21b10c63b02b7567082762656e09e57253edae6 100644 (file)
@@ -65,5 +65,5 @@ error: tuple struct `Z` is private
 45 |     xcrate::m::n::Z; //~ ERROR tuple struct `Z` is private
    |     ^^^^^^^^^^^^^^^
 
-error: aborting due to 8 previous errors
+error: aborting due to previous error(s)
 
index 7975c168de7d4d39075ed8e349aeeec795b8f249..c346612a68bb62a04353ef3fb401cacfc5a61a20 100644 (file)
@@ -52,5 +52,5 @@ error[E0425]: cannot find value `method` in this scope
 52 |         method;
    |         ^^^^^^ did you mean `self.method(...)`?
 
-error: aborting due to 9 previous errors
+error: aborting due to previous error(s)
 
index ffb3f8484306f72b66f857cc1a634233deb6c1c2..92f13f705b079adf766dee79291467c6319f5986 100644 (file)
@@ -4,5 +4,5 @@ error[E0423]: expected function, found macro `assert`
 12 |     assert(true);
    |     ^^^^^^ did you mean `assert!(...)`?
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index e7df8140bc577bbb0d207cf85801c736c330d6a9..04c8087ace9ffa5e937fe36d8f6792971afc3621 100644 (file)
@@ -22,5 +22,5 @@ error[E0425]: cannot find function `method` in this scope
 38 |         method();
    |         ^^^^^^ did you mean `self.method(...)`?
 
-error: aborting due to 4 previous errors
+error: aborting due to previous error(s)
 
index f254ad3d87d86ec8cd7368416c917f88606f1fb3..24cef694737e05e8cc32825e0954ed7de2504d24 100644 (file)
@@ -74,5 +74,5 @@ error[E0423]: expected function, found module `a::b`
 
 error: main function not found
 
-error: aborting due to 10 previous errors
+error: aborting due to previous error(s)
 
index feb12612e660419a04b8db46ad4da603f9ead61d..7307f19c74de3ecb3347f92f37050a73c9014346 100644 (file)
@@ -16,5 +16,5 @@ error[E0425]: cannot find value `foo` in this scope
 14 |     if foo {
    |        ^^^ not found in this scope
 
-error: aborting due to 2 previous errors
+error: aborting due to previous error(s)
 
index 849787e383f107d2140ed9c97dcce388f2b9b140..d234c8538fe27a23d8128a70fbb317c7b31043d3 100644 (file)
@@ -40,5 +40,5 @@ error[E0308]: mismatched types
    = note: expected type `()`
               found type `std::result::Result<bool, std::io::Error>`
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index 226fa6469bc740f9403c0f8aa75050a68693574e..1dd263affd4c3c6f923cf9b58f705fc2abbe2b86 100644 (file)
@@ -52,5 +52,5 @@ error[E0425]: cannot find function `bar` in this scope
 14 |     foo(bar(;
    |         ^^^ not found in this scope
 
-error: aborting due to 7 previous errors
+error: aborting due to previous error(s)
 
index e2ef8f0e568fcf4f47ca1ed331d22eb9fa5b6dbe..2fc5979a6065ebc4b42be1f855c6789dfaed7e44 100644 (file)
@@ -28,5 +28,5 @@ error[E0532]: expected tuple struct/variant, found type alias `A`
    |         did you mean `S`?
    |         did you mean `A { /* fields */ }`?
 
-error: aborting due to 4 previous errors
+error: aborting due to previous error(s)
 
index 5fbaf66e014af073f45aef78a325c8347a7c1cef..ff6bcf2a53205ecb9f5c4b4a8fd153e77712088f 100644 (file)
@@ -7,5 +7,5 @@ error[E0425]: cannot find value `cx` in this scope
    |           did you mean `self.cx`?
    |           `self` value is only available in methods with `self` parameter
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index 729a515612463396cf588abc8c38f174ed0c092f..f722908ec108a07099a4db10567e1f27a8f89a96 100644 (file)
@@ -7,5 +7,5 @@ error[E0046]: not all trait items implemented, missing: `foo`
 18 | impl Foo for Bar {}
    | ^^^^^^^^^^^^^^^^^^^ missing `foo` in implementation
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index 0d6b0a552e4de981733df0af246a7dc0848b50cf..bc3a3908dcaefef6033c4a40114732dc37acda19 100644 (file)
@@ -10,5 +10,5 @@ error[E0057]: this function takes 1 parameter but 2 parameters were supplied
 15 |     let c = f(2, 3); //~ ERROR E0057
    |               ^^^^ expected 1 parameter
 
-error: aborting due to 2 previous errors
+error: aborting due to previous error(s)
 
index 1f6dd6b1d165f52c9eb3f5e257ccce7dcafd4718..14e6bcb73b02b69c62058b93fc3861924f24afd7 100644 (file)
@@ -9,5 +9,5 @@ error[E0072]: recursive type `ListNode` has infinite size
    |
    = help: insert indirection (e.g., a `Box`, `Rc`, or `&`) at some point to make `ListNode` representable
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index 4fe6afaca8ec658a4eae9fdba79b35dc37cacb29..fab2436922dda318fd5f2d16716b69ba17407645 100644 (file)
@@ -34,5 +34,5 @@ error[E0204]: the trait `Copy` may not be implemented for this type
 31 |     Bar(&'a mut bool),
    |         ------------- this field does not implement `Copy`
 
-error: aborting due to 4 previous errors
+error: aborting due to previous error(s)
 
index afcc9a240eb4e6c266a4decb0e110c8e2b80ad99..5f8b57294d548e6aa6fb38133abb7adbc0017ba4 100644 (file)
@@ -7,5 +7,5 @@ error[E0493]: constants are not allowed to have destructors
 27 | const F : Foo = Foo { a : 0 };
    |                 ^^^^^^^^^^^^^ constants cannot have destructors
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index 23070e1555b9b89f101cd7440fd30e9d06554978..64c0016085f07c1de13792dfe77ddd532828bbc4 100644 (file)
@@ -4,5 +4,5 @@ error[E0535]: invalid argument
 11 | #[inline(unknown)] //~ ERROR E0535
    |          ^^^^^^^
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index b2da0c6a296d8fc5119d4f68560f799f9947408d..8a4cf34e565f5016348dd7b7b33efa26b2b42c5b 100644 (file)
@@ -4,5 +4,5 @@ error[E0536]: expected 1 cfg-pattern
 11 | #[cfg(not())] //~ ERROR E0536
    |       ^^^
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index 29873943f444d8e65a7fc59f27af530744919307..1bd54a6a007ed94c2c18c128270da0be691bec71 100644 (file)
@@ -4,5 +4,5 @@ error[E0537]: invalid predicate `unknown`
 11 | #[cfg(unknown())] //~ ERROR E0537
    |       ^^^^^^^
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index edf1635a6b84fe7f1b0f187bf865cc4fccc9e787..7cd9f30f42c1743a8d9d824fc3ca392a578d9785 100644 (file)
@@ -82,5 +82,5 @@ error: cannot borrow immutable borrowed content `*x` as mutable
 143 |     *x.y_mut() = 3; //~ ERROR cannot borrow
     |      ^ cannot borrow as mutable
 
-error: aborting due to 10 previous errors
+error: aborting due to previous error(s)
 
index 2ec01168721798684e360cd3a54fca6aa53868dc..83c49409049d8610410377c2dc816c6f7153cfad 100644 (file)
@@ -30,5 +30,5 @@ error: cannot borrow immutable borrowed content `*x` as mutable
 63 |     **x = 3; //~ ERROR cannot borrow
    |      ^^ cannot borrow as mutable
 
-error: aborting due to 4 previous errors
+error: aborting due to previous error(s)
 
index 4ece8bc6af10fb06867356f608244c382ff823a5..bfb51ba48166287eb8e1550800aadebfeb3ef927 100644 (file)
@@ -47,5 +47,5 @@ error[E0507]: cannot move out of captured outer variable in an `FnMut` closure
 72 |         foo(f);
    |             ^ cannot move out of captured outer variable in an `FnMut` closure
 
-error: aborting due to 5 previous errors
+error: aborting due to previous error(s)
 
index 2349bfaf75e6f4fe37c3fde7703a554142b6ad4a..00fa6577545daf13fb1e711e70aa4214ff34c806 100644 (file)
@@ -7,5 +7,5 @@ error: cannot borrow immutable borrowed content `*x` as mutable
 27 |     x.h(); //~ ERROR cannot borrow
    |     ^ cannot borrow as mutable
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index 251a9e4aa57555730d0a988b08fd59cf839cd035..75866b7e45e31236bc6d84e393ffeb1b57007f00 100644 (file)
@@ -6,5 +6,5 @@ error: cannot borrow immutable borrowed content `*x` as mutable
 17 |         x.push(format!("this is broken"));
    |         ^ cannot borrow as mutable
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index 5bb656878b3f3b7d384a760621b84503453b8e6c..fd2a752c4721be2cc3e50b2a26c6edb2415c6ba3 100644 (file)
@@ -48,5 +48,5 @@ error: borrowed value does not live long enough
    |
    = note: consider using a `let` binding to increase its lifetime
 
-error: aborting due to 4 previous errors
+error: aborting due to previous error(s)
 
index 0abdbdc3a21b58f1560763529439ac66aeb5ca35..86316d8980d0ccf010e902e4a04b75dcc4d83cfd 100644 (file)
@@ -16,5 +16,5 @@ error: cannot borrow immutable `Box` content `*x` as mutable
 29 |     x.borrowed_mut(); //~ ERROR cannot borrow
    |     ^ cannot borrow as mutable
 
-error: aborting due to 2 previous errors
+error: aborting due to previous error(s)
 
index adbf39b3f7580f9d65b27ab52a2f1e18b93f32c5..38ce3d398baaf892505db2e982a6105e976464ae 100644 (file)
@@ -12,5 +12,5 @@ error: borrowed value does not live long enough
    |
    = note: consider using a `let` binding to increase its lifetime
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index 220b2f471da9ad7aef33e4d22a67ab811adbb778..47ede6f2eb1a8a718df6dc5b46835ce37adf7d46 100644 (file)
@@ -47,5 +47,5 @@ error[E0308]: mismatched types
    = note: expected type `_`
               found type `std::boxed::Box<_>`
 
-error: aborting due to 5 previous errors
+error: aborting due to previous error(s)
 
index 3253212c5b87ba389f519a689cc83de4256da09b..bf449518ce70c7c0c1ed9fa3ea86ddcbf19389c5 100644 (file)
@@ -8,5 +8,5 @@ error: `*a` does not live long enough
    |     |
    |     `*a` dropped here while still borrowed
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index e31c36e83dfca125be3a54c98553ddf525b033d7..f098448527905ee8f83ab99d0038a28160ba31a4 100644 (file)
@@ -9,5 +9,5 @@ error: `*m` does not live long enough
    |
    = note: values in a scope are dropped in the opposite order they are created
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index c89da0baef233925862e37f6ca69e28c99a0701e..ea5163cf924729a43d83b81af50f004603291090 100644 (file)
@@ -63,5 +63,5 @@ error: `b2` does not live long enough
     |
     = note: values in a scope are dropped in the opposite order they are created
 
-error: aborting due to 6 previous errors
+error: aborting due to previous error(s)
 
index 9eb2a2157717025f3cc7b88f22940b5c4e3b1c91..d5f22a2665049d802830d49e9b35cf6fc5c2f5d4 100644 (file)
@@ -19,5 +19,5 @@ error: `d1` does not live long enough
    |
    = note: values in a scope are dropped in the opposite order they are created
 
-error: aborting due to 2 previous errors
+error: aborting due to previous error(s)
 
index 98c1cbbba7b3fa160e5bcf8c0b1f75b9d91551b0..4ad98b429c53b4c3bbdc7067dcc16d1477dcab72 100644 (file)
@@ -19,5 +19,5 @@ error: `v` does not live long enough
    |
    = note: values in a scope are dropped in the opposite order they are created
 
-error: aborting due to 2 previous errors
+error: aborting due to previous error(s)
 
index 961ac81cf8280dea57688362c8c7762d30bea1d2..e38c49d6a5c36bed9cb88054305cb3733cfa4944 100644 (file)
@@ -63,5 +63,5 @@ error: `c2` does not live long enough
     |
     = note: values in a scope are dropped in the opposite order they are created
 
-error: aborting due to 6 previous errors
+error: aborting due to previous error(s)
 
index ae290b3b11aa79c5df19475fbd03aaab7ed839b1..ca7286f50275b7c3899c281718b8b03cb13ddf74 100644 (file)
@@ -85,5 +85,5 @@ error[E0046]: not all trait items implemented, missing: `fmt`
    |
    = note: `fmt` from trait: `fn(&Self, &mut std::fmt::Formatter<'_>) -> std::result::Result<(), std::fmt::Error>`
 
-error: aborting due to 7 previous errors
+error: aborting due to previous error(s)
 
index 6ad9c27b8b9101418959815e2a929c52f5ed2538..18cbf9332301924aeb42a3258177893472d74c59 100644 (file)
@@ -10,5 +10,5 @@ error: `x` does not live long enough
 23 | }
    | - borrowed value needs to live until here
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index 85f6c41c366413320ca85c8d37f1cba702a9f40f..d2534388f7255d3212331a80f72deb00bb67fcd5 100644 (file)
@@ -11,5 +11,5 @@ error: borrowed value does not live long enough
    |
    = note: consider using a `let` binding to increase its lifetime
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index 85a0002f2418081f2d43b4c12082fab811fcf94b..bf7c099187ee64aaaf96f9c3d13e861102ebe42e 100644 (file)
@@ -18,5 +18,5 @@ error: `y` does not live long enough
    |     |
    |     `y` dropped here while still borrowed
 
-error: aborting due to 2 previous errors
+error: aborting due to previous error(s)
 
index d9f4bacce35ae0650c9d88c39f58329dab187dcc..d6aed36c8f63f9258323bfb42396d433a7b67ae3 100644 (file)
@@ -12,5 +12,5 @@ error[E0046]: not all trait items implemented, missing: `Item`
    |
    = note: `Item` from trait: `type Item;`
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index 3127af157a62bbb8184673b6398e6f4993db4230..a1d3f5c11df34e91c2d7f34c0069b79209a9e568 100644 (file)
@@ -12,5 +12,5 @@ error[E0046]: not all trait items implemented, missing: `Output`
    |
    = note: `Output` from trait: `type Output;`
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index 71ab82d98b809abee614d08c740e37a5266d8ee6..771ea787304b3c29862b4b7c6dc0c0002b776089 100644 (file)
@@ -11,5 +11,5 @@ error[E0046]: not all trait items implemented, missing: `Target`
    |
    = note: `Target` from trait: `type Target;`
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index c4f2616f5945b1baa5680d1bc475fc3e8c282f5c..598f9f5130781552806f5301153d12ab512f6628 100644 (file)
@@ -32,5 +32,5 @@ note: lint level defined here
 16 | #![deny(warnings)]
    |         ^^^^^^^^
 
-error: aborting due to 3 previous errors
+error: aborting due to previous error(s)
 
index a622e7cfb7180972bd31b0688a4d90eba4f3ceef..8c2254483e03075c29ce2d0948cb7c1748205e0b 100644 (file)
@@ -9,5 +9,5 @@ error: `d1` does not live long enough
    |
    = note: values in a scope are dropped in the opposite order they are created
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index d06c8af62ee60938c17c56085acce300e9bc9ece..450bc123e60bc9ab0f86171a9416c22c7ff0b778 100644 (file)
@@ -28,5 +28,5 @@ error: `d1` does not live long enough
    |
    = note: values in a scope are dropped in the opposite order they are created
 
-error: aborting due to 3 previous errors
+error: aborting due to previous error(s)
 
index 160bfb63900454cc091e62e6356edb0ecde5971b..dfee66ae546cddee245e3dfce9ba3c78d2bf1cb9 100644 (file)
@@ -8,5 +8,5 @@ error: `d1` does not live long enough
    |
    = note: values in a scope are dropped in the opposite order they are created
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index 3c8ee07a1fdd88beae1b1a395bc2666bb2e9665b..17c05557297530d43f53a3e44896e61877ce4aa5 100644 (file)
@@ -19,5 +19,5 @@ error: `container` does not live long enough
    |
    = note: values in a scope are dropped in the opposite order they are created
 
-error: aborting due to 2 previous errors
+error: aborting due to previous error(s)
 
index f960844c818ff7a2b08c9de2661bdfc5e3713749..1f5c64986c7369f1aaf8f8e7e01667e3d5a51b25 100644 (file)
@@ -8,5 +8,5 @@ error: `ticking` does not live long enough
    |
    = note: values in a scope are dropped in the opposite order they are created
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index 117b109780b152de90c24f45dd97f8697ea3d84b..443595c6d2c764ae4c62a20c0a16dc56758c9375 100644 (file)
@@ -7,5 +7,5 @@ error[E0308]: mismatched method receiver
    = note: expected type `&Self`
               found type `&SomeType`
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index a7d3b84daba469b841d95c1361d678c9866b8a14..2a7e59f0422e64725e1c55d6e30646354f3e8659 100644 (file)
@@ -18,5 +18,5 @@ error: `x` does not live long enough
    |
    = note: values in a scope are dropped in the opposite order they are created
 
-error: aborting due to 2 previous errors
+error: aborting due to previous error(s)
 
index abbac245f89f66b191709212f42738ac9d8e2244..4065c4fb85713f3836cf1172c98672a3d1fd5971 100644 (file)
@@ -6,5 +6,5 @@ error[E0277]: the trait bound `u8: Tr` is not satisfied
    |
    = note: required by `Tr::C`
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index 2a874181c7ad9a03332c073bbde569fce15ebc76..38256ec944b9b9c5debf9ed7f4a9cd55f075381a 100644 (file)
@@ -8,5 +8,5 @@ error[E0308]: mismatched types
               found type `std::string::String`
    = note: this error originates in a macro outside of the current crate
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index 98183e2f082e9f55b33da1dd5443306de6041d29..48ed0b4ac89aa964e62debf10532383fa2873175 100644 (file)
@@ -45,5 +45,5 @@ error[E0061]: this function takes 2 parameters but 3 parameters were supplied
 19 |     bar(1, 2, 3);
    |         ^^^^^^^ expected 2 parameters
 
-error: aborting due to 3 previous errors
+error: aborting due to previous error(s)
 
index dc6190c2e76b0f28afee368623308f022d13cb96..5dc9bd8b79b19952cd313f6940e421135ea7eb7d 100644 (file)
@@ -14,5 +14,5 @@ error: The attribute `foo` is currently unknown to the compiler and may have mea
    |
    = help: add #![feature(custom_attribute)] to the crate attributes to enable
 
-error: aborting due to 2 previous errors
+error: aborting due to previous error(s)
 
index a335194580d4553a9d35256cb41fb99c7e64ad19..dbce171dd9b7e5c14f166385f91b43628445e2f3 100644 (file)
@@ -8,5 +8,5 @@ error: `a` does not live long enough
    |
    = note: values in a scope are dropped in the opposite order they are created
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index 7cf74eaab8db12c65c7ed2e1266edc152643919d..bd271641e7e3cca949f80c52bee1e71a435e3815 100644 (file)
@@ -55,5 +55,5 @@ note: candidate #2 is defined in the trait `F`
    |     ^^^^^^^^^^^^^^^
    = help: to disambiguate the method call, write `F::foo(a)` instead
 
-error: aborting due to 3 previous errors
+error: aborting due to previous error(s)
 
index cd3a41b037c7996e8fa529e8fc805b9bca3e4c61..f0b940cdf3fa9e150e1509ec9562f0dd10734b82 100644 (file)
@@ -15,5 +15,5 @@ error[E0369]: binary operation `+` cannot be applied to type `World`
    |
    = note: an implementation of `std::ops::Add` might be missing for `World`
 
-error: aborting due to 2 previous errors
+error: aborting due to previous error(s)
 
index 97d802f8398311fa3930f046e903224063e1d87e..0d0a07629c49a09309dacb4115d1e6cbafd73f15 100644 (file)
@@ -38,5 +38,5 @@ error[E0408]: variable `c` is not bound in all patterns
    |         |             pattern doesn't bind `c`
    |         pattern doesn't bind `c`
 
-error: aborting due to 4 previous errors
+error: aborting due to previous error(s)
 
index ad1c149d2e56f7546a7f86cbae68e4ee6a006a3d..160f65fd1b9af499e7d842f484e10439bfc06d5e 100644 (file)
@@ -10,5 +10,5 @@ error: `foo` does not live long enough
    |
    = note: this error originates in a macro outside of the current crate
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index 8b813220d789de781b21f5dc635f3aa882cb2003..c017e38680826d60fc7ddfb201a5b57dd9add551 100644 (file)
@@ -61,5 +61,5 @@ note: candidate #1 is defined in the trait `ManyImplTrait`
    = help: items from traits can only be used if the trait is implemented and in scope; the following trait defines an item `is_str`, perhaps you need to implement it:
    = help: candidate #1: `ManyImplTrait`
 
-error: aborting due to 3 previous errors
+error: aborting due to previous error(s)
 
index b5fbe99ec72e8ac9fd8824e0b8c5dfce6865e75d..06b7f922b684c538f95c8d127c8648ab6b8f13f7 100644 (file)
@@ -19,5 +19,5 @@ error: `foo.data` does not live long enough
    |
    = note: values in a scope are dropped in the opposite order they are created
 
-error: aborting due to 2 previous errors
+error: aborting due to previous error(s)
 
index debb8354568cc453c6d720faa0d65f6e30d6f306..d166af522478e693afb238c9021ceae83e0368b9 100644 (file)
@@ -20,5 +20,5 @@ error: `first_dropped` does not live long enough
    |
    = note: values in a scope are dropped in the opposite order they are created
 
-error: aborting due to 2 previous errors
+error: aborting due to previous error(s)
 
index 7d3ac3e9d0391ab6d69c82e4e562ba7c3da52bc2..6a02d7015733de3cad307dc50acb402728c2d886 100644 (file)
@@ -20,5 +20,5 @@ error: `first_dropped` does not live long enough
    |
    = note: values in a scope are dropped in the opposite order they are created
 
-error: aborting due to 2 previous errors
+error: aborting due to previous error(s)
 
index ae96cace91c476a4345f009462166878c09ea709..91a410e0f65894ca0c0fa1efd45bdd0ce3a82a3d 100644 (file)
@@ -20,5 +20,5 @@ error: `first_dropped` does not live long enough
    |
    = note: values in a scope are dropped in the opposite order they are created
 
-error: aborting due to 2 previous errors
+error: aborting due to previous error(s)
 
index f4998e08907a387f55b897ab80f5cc47e203d540..2f5e60a1b3c9d0fbf07bb0899f18db927e6b467c 100644 (file)
@@ -106,5 +106,5 @@ note: because it's nested under this `unsafe` fn
 44 | | }
    | |_^
 
-error: aborting due to 8 previous errors
+error: aborting due to previous error(s)
 
index b0f191e29d1be02da29d0039aedac4fa302514ca..6095a3b6be5cbd27ab75b128c648bf0b2f203519 100644 (file)
@@ -9,5 +9,5 @@ error: `short` does not live long enough
    |
    = note: values in a scope are dropped in the opposite order they are created
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index 2294e6476d61fe2dd6c157884821603176b21af3..f76c5b049c4b04c0a65f69885be2573e89c647d3 100644 (file)
@@ -7,5 +7,5 @@ error[E0308]: mismatched types
    = note: expected type `()`
               found type `[closure@$DIR/move-closure.rs:15:17: 15:27]`
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index a06cbd04deb4fb4a32bc030387426608e8a913fd..881c2f5df45a2ffaee2e15f8a26870904589379a 100644 (file)
@@ -12,5 +12,5 @@ error[E0072]: recursive type `ListNode` has infinite size
    |
    = help: insert indirection (e.g., a `Box`, `Rc`, or `&`) at some point to make `ListNode` representable
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index 843c1e811d578393ea375cc42338d38a773e7749..057f8fe6ee274f6e22b6682013bc04be2e3a2488 100644 (file)
@@ -7,9 +7,9 @@ error[E0277]: the trait bound `u32: std::ops::Add<()>` is not satisfied
 25 | |         bar(x,
 26 | |
 27 | |             y),
-   | |______________^ the trait `std::ops::Add<()>` is not implemented for `u32`
+   | |______________^ no implementation for `u32 + ()`
    |
-   = note: no implementation for `u32 + ()`
+   = help: the trait `std::ops::Add<()>` is not implemented for `u32`
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index 01364c0714407a029e76bd967554e341a2c11f8a..d5e6b62865586a7547e3e5da155759965a34160a 100644 (file)
@@ -22,5 +22,5 @@ error: cannot borrow immutable borrowed content `*a` as mutable
 25 |         a.push_str("foo");
    |         ^ cannot borrow as mutable
 
-error: aborting due to 3 previous errors
+error: aborting due to previous error(s)
 
index 0417eb075af85ab15a799543f41784b07eb82fbd..68dc87d0667e2d2bca63d17034be6b8a683e48be 100644 (file)
@@ -8,5 +8,5 @@ error: `b` does not live long enough
 20 | }
    | - borrowed value needs to live until here
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index c66361c8546b839046fb47b9fcf2556eeba2c395..835b08f890751a853a2407902bdba88e9e702d03 100644 (file)
@@ -15,5 +15,5 @@ error[E0124]: field `bar` is already declared
 17 |     pub(crate) bar: u8,
    |     ^^^^^^^^^^^^^^^^^^ field already declared
 
-error: aborting due to 2 previous errors
+error: aborting due to previous error(s)
 
index 9f11de77be7e73dd9789ed987ff3c2fc8c99a50d..4f638562bb8014a2e9045b8db0e2a6961ef3eb7f 100644 (file)
@@ -20,5 +20,5 @@ error: `b` does not live long enough
 21 | }
    | - borrowed value needs to live until here
 
-error: aborting due to 2 previous errors
+error: aborting due to previous error(s)
 
index b4d0b5a6a25d03557028beec40e27409ccb2b19e..72177754681f80ea3c516f000cd953ffa76db8a2 100644 (file)
@@ -27,5 +27,5 @@ error[E0072]: recursive type `Bar` has infinite size
    |
    = help: insert indirection (e.g., a `Box`, `Rc`, or `&`) at some point to make `Bar` representable
 
-error: aborting due to 2 previous errors
+error: aborting due to previous error(s)
 
index 9c369e03e33ab8fdeee92b50327180907be3fb02..6c5007a570535093109be8b70c2036aec8977e87 100644 (file)
@@ -9,5 +9,5 @@ error: `c` does not live long enough
 20 | }
    | - borrowed value needs to live until here
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index 205734c25e0e6cd4926fc870e852f62e7032dea0..d6a460d83ab0faa9f054c7b0295aac5485be6bbb 100644 (file)
@@ -9,5 +9,5 @@ error: borrowed value does not live long enough
 23 | }
    | - temporary value needs to live until here
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index ea652da7da46f57b6bd68e52bffc284ed9e426f9..099f6df27efc69fca1dbed8f6c945b35503aab43 100644 (file)
@@ -9,5 +9,5 @@ error: `tmp0` does not live long enough
    |     |
    |     `tmp0` dropped here while still borrowed
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index 09f2154905f38d7f536c43e7c5db0a500e232e0b..09178ce57e8be951b1d86a8197c3d885041536cd 100644 (file)
@@ -8,5 +8,5 @@ error: `x` does not live long enough
 23 | }
    | - borrowed value needs to live until here
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index 58f7849e443f5a52b8e07ac0f10b39adb826ef17..006060f342a38e5e934f7d2a0bfec398ffa5f31e 100644 (file)
@@ -37,5 +37,5 @@ error[E0506]: cannot assign to `x` because it is borrowed
 24 |         x += 1; //~ ERROR cannot assign
    |         ^^^^^^ assignment to borrowed `x` occurs here
 
-error: aborting due to 4 previous errors
+error: aborting due to previous error(s)
 
index 0e7b64ec2b36c08db9dca69805871f504a025146..d4dfef36e4afbb6af94fe6a3c549676f01eb1821 100644 (file)
@@ -10,5 +10,5 @@ error: `*x` does not live long enough
 30 | }
    | - borrowed value needs to live until here
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index 5897921476d3ffde2d44dbc33e856264923c1148..4a815a58b354da092bd13e4bc06b8483be40fb52 100644 (file)
@@ -24,5 +24,5 @@ error: `y` does not live long enough
 35 | }
    | - borrowed value needs to live until here
 
-error: aborting due to 2 previous errors
+error: aborting due to previous error(s)
 
index 08f85f17bf8adaa861f8e4d47e8cdf00e826f66a..815f88022675d21ebfcf20f3e6da685a1160c6e3 100644 (file)
@@ -32,5 +32,5 @@ error: `x` does not live long enough
 44 | }
    | - borrowed value needs to live until here
 
-error: aborting due to 3 previous errors
+error: aborting due to previous error(s)
 
index a86cf1e58846dbafb935fed38393a402f52f75d2..81f53c7f374eb691a80e7218eb31abe75ba9e069 100644 (file)
@@ -52,5 +52,5 @@ error[E0505]: cannot move out of `y` because it is borrowed
 49 |     drop(y); //~ ERROR cannot move out
    |          ^ move out of `y` occurs here
 
-error: aborting due to 6 previous errors
+error: aborting due to previous error(s)
 
index efe81fd00bf4789b2069fb255d68782041d53b98..ff6d30d670de1ffb4275770da329950b76dc8697 100644 (file)
@@ -9,5 +9,5 @@ error: borrowed value does not live long enough
 19 | }
    | - temporary value needs to live until here
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index 91e629c44b073572a8a9a8934fcb1b396e31cad4..b6353c0f6a205084c2b88ec2d12dfa1a0e2924fb 100644 (file)
@@ -4,5 +4,5 @@ error: cannot index a value of type `({integer},)`
 14 |     println!("☃{}", tup[0]);
    |                     ^^^^^^ help: to access tuple elements, use `tup.0`
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index dc37acaf3f98eb3a5b320bebfb3c4d65bc40dc13..afe069e7aa684cad3bc73dfdb92528c209d0210e 100644 (file)
@@ -4,5 +4,5 @@ error[E0220]: associated type `Trget` not found for `std::ops::Deref`
 16 | fn homura<T: Deref<Trget = i32>>(_: T) {}
    |                    ^^^^^^^^^^^ associated type `Trget` not found
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index dca0a93f897baaa42de4d950161856983dd49876..6556e5b4c001e7f92e86d2ec7b76bbdb1166f2f6 100644 (file)
@@ -10,5 +10,5 @@ error[E0425]: cannot find value `fob` in this scope
 18 |     println!("Hello {}", fob);
    |                          ^^^ did you mean `foo`?
 
-error: aborting due to 2 previous errors
+error: aborting due to previous error(s)
 
index 11031ee0ab263251655c69c2336430847e7173bf..fad46d5a7d05282242cf3179b58bb8586c1f10fa 100644 (file)
@@ -19,5 +19,5 @@ error: `c1` does not live long enough
     |
     = note: values in a scope are dropped in the opposite order they are created
 
-error: aborting due to 2 previous errors
+error: aborting due to previous error(s)
 
index 8cc12c32b9303f0eee2c17c2e4d19f16fe2e5990..c890d4740e6c2aad70316c2b8eca764534d197c4 100644 (file)
@@ -20,5 +20,5 @@ error: `y` does not live long enough
    |
    = note: values in a scope are dropped in the opposite order they are created
 
-error: aborting due to 2 previous errors
+error: aborting due to previous error(s)
 
index aeac3102fbf3a94bb989bb332c55b538b111a8bf..ff1bf47d44d058d198d1c64584c1fc95c138ebb0 100644 (file)
@@ -9,5 +9,5 @@ error: `pointer` does not live long enough
 33 | }
    | - borrowed value needs to live until here
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index f73dff4f73d0ee43ba06369bcfed4a5a6f3ca13a..89008828ac5efaf54178e88ed0bca1c847fac0f8 100644 (file)
@@ -6,5 +6,5 @@ error[E0477]: the type `std::borrow::Cow<'a, A>` does not fulfill the required l
    |
    = note: type must satisfy the static lifetime
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index 9e5e4adb180d5fdb1aef2b9177e42baf4f80db8f..0f2097dfb312c0bed8777ba96c79f33cc08d49c2 100644 (file)
@@ -6,5 +6,5 @@ error: no method named `closure` found for type `Obj<[closure@$DIR/issue-18343.r
    |
    = help: use `(o.closure)(...)` if you meant to call the function stored in the `closure` field
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index 56e1060bdb95ae2645cd4556e248a690ac1fa804..0191060e837bacef156ace72c52569c12aabc655 100644 (file)
@@ -86,5 +86,5 @@ error: no method named `f3` found for type `FuncContainer` in the current scope
     |
     = help: use `((*self.container).f3)(...)` if you meant to call the function stored in the `f3` field
 
-error: aborting due to 11 previous errors
+error: aborting due to previous error(s)
 
index 0d2a895bad16d31fea4529f0c6c1f52a4166df79..704b7a37e9553cf18b8acc35f46f48f96a0f8744 100644 (file)
@@ -6,5 +6,5 @@ error: no method named `example` found for type `Example` in the current scope
    |
    = help: use `(demo.example)(...)` if you meant to call the function stored in the `example` field
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index 70d64e3ffa3319d05ec92a62513988d303d8d6be..d827f89cf8d821b6b88684426847726521d76c8b 100644 (file)
@@ -22,5 +22,5 @@ error: no method named `c_fn_ptr` found for type `&D` in the current scope
    |
    = help: use `(s.c_fn_ptr)(...)` if you meant to call the function stored in the `c_fn_ptr` field
 
-error: aborting due to 3 previous errors
+error: aborting due to previous error(s)
 
index d07885915d2b7a1139bca563b7c986879ec62ab1..e3c88c1e7bbbd62e07e2397e6ed1a850e123e89b 100644 (file)
@@ -4,5 +4,5 @@ error: no method named `dog_age` found for type `animal::Dog` in the current sco
 26 |     let dog_age = dog.dog_age();
    |                       ^^^^^^^ private field, not a method
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index 8a121b145366250abbcd1d39a05c42ca1d4e63d5..47a1b53cc60e0d95a98f78a4e4d2cafdf02636dd 100644 (file)
@@ -7,5 +7,5 @@ error: unexpected token: `1.1`
    |     |           unexpected token
    |     help: try parenthesizing the first index `((1, (2, 3)).1).1`
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index 4d60be15ecaf0aae9a8801d4a1655831da71eb7a..15e4d4c72bc50d926ddae589d8c319e6601ea35f 100644 (file)
@@ -4,5 +4,5 @@ error: expected one of `!` or `::`, found `<eof>`
 15 | FAIL
    | ^^^^ expected one of `!` or `::` here
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index b0bae1248b9698442106d8a2654c8473da2c5ffc..faa30dca94581effc840dcc6ba1f3f9f90b4407e 100644 (file)
@@ -24,5 +24,5 @@ error: expected expression, found `)`
 
 error: main function not found
 
-error: aborting due to 4 previous errors
+error: aborting due to previous error(s)
 
index a6ad1206b14d06cfe19311025cef40c60d080f5a..96c2d764e7101f2e76760b84fdd69395ba0b762a 100644 (file)
@@ -14,5 +14,5 @@ error[E0412]: cannot find type `S` in this scope
 
 error: main function not found
 
-error: aborting due to 3 previous errors
+error: aborting due to previous error(s)
 
index f23d97586b843437002585034875cd2bca7dddd8..14a7186aab19c2ef249e21d37e062f0270251206 100644 (file)
@@ -28,5 +28,5 @@ note: caused by the macro expansion here; the usage of `ignored_pat!` is likely
 37 |         ignored_pat!() => (), //~ NOTE caused by the macro expansion here
    |         ^^^^^^^^^^^^^^
 
-error: aborting due to 3 previous errors
+error: aborting due to previous error(s)
 
index c765a434b8ac6e86ef1c6f5cffce28b847dea095..5fe0b3594f67cc1bd86a856de6972ec7928a51e8 100644 (file)
@@ -4,5 +4,5 @@ error: expected one of `!` or `::`, found `<eof>`
 19 | FAIL
    | ^^^^ expected one of `!` or `::` here
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index 8c52bb5a1d3a51d9401efe7d30800c019f4b8323..007480dc44ff22e7f508008de9ed4d676090620d 100644 (file)
@@ -6,5 +6,5 @@ error[E0282]: type annotations needed
    |         |
    |         consider giving `x` a type
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index 4788fad20889e4123904a479d13ed2ade197b7c7..4650df5411b5bc6abba5ec0a5e396d548db00f00 100644 (file)
@@ -8,5 +8,5 @@ error[E0282]: type annotations needed
    |
    = note: this error originates in a macro outside of the current crate
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index ccffadebe9ee2c177ed408509ae3789ede07e7f9..08b5ae4bbb6fa2e7377b3bdf1f289d89077684f0 100644 (file)
@@ -8,5 +8,5 @@ error[E0282]: type annotations needed
    |
    = note: this error originates in a macro outside of the current crate
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index 9568411885192a04f4002f0ca87a138159b22f1e..b3c736c3b685d3722e066c8bab8b7e5d296b0e93 100644 (file)
@@ -4,5 +4,5 @@ error[E0282]: type annotations needed
 14 |     [];
    |     ^^ cannot infer type for `[_; 0]`
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index 7a76799889b97385d114fe863b94ed0573acc925..bf03e52369feb8b4a50423ab0be4230d1c039e59 100644 (file)
@@ -10,5 +10,5 @@ error[E0282]: type annotations needed
 21 | | }
    | |_^ cannot infer type for `&'a T`
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index afbd15ca486bd1e66566ee1269341879986d5e45..200864dfbf77aa0467d3f6e75b25c066a51ca7bc 100644 (file)
@@ -4,5 +4,5 @@ error[E0282]: type annotations needed
 12 |     let x = |_| {    };
    |              ^ consider giving this closure parameter a type
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index 911f3c51f5f6005f4181f023f67218ca72bd2111..1bec6f6af83814c6f725ff3b529602c040b36a59 100644 (file)
@@ -2415,11 +2415,11 @@ fn compare_output(&self, kind: &str, actual: &str, expected: &str) -> usize {
         println!("expected {}:\n{}\n", kind, expected);
         println!("diff of {}:\n", kind);
 
-        for diff in diff::lines(actual, expected) {
+        for diff in diff::lines(expected, actual) {
             match diff {
-                diff::Result::Left(l)    => println!("+{}", l),
+                diff::Result::Left(l)    => println!("-{}", l),
                 diff::Result::Both(l, _) => println!(" {}", l),
-                diff::Result::Right(r)   => println!("-{}", r),
+                diff::Result::Right(r)   => println!("+{}", r),
             }
         }