]> git.lizzy.rs Git - rust.git/commitdiff
Auto merge of #50409 - KiChjang:issue-50343, r=nikomatsakis
authorbors <bors@rust-lang.org>
Fri, 4 May 2018 08:22:13 +0000 (08:22 +0000)
committerbors <bors@rust-lang.org>
Fri, 4 May 2018 08:22:13 +0000 (08:22 +0000)
Skip checking for unused mutable locals that have no name

Fixes #50343.

230 files changed:
src/Cargo.lock
src/Cargo.toml
src/bootstrap/config.rs
src/doc/unstable-book/src/language-features/fn-must-use.md [deleted file]
src/doc/unstable-book/src/language-features/tool-attributes.md [new file with mode: 0644]
src/liballoc/lib.rs
src/liballoc/tests/lib.rs
src/liballoc/tests/slice.rs
src/libcore/lib.rs
src/libcore/macros.rs
src/libcore/ops/range.rs
src/libcore/slice/memchr.rs
src/libcore/tests/lib.rs
src/libcore/tests/ops.rs
src/libcore/unicode/bool_trie.rs
src/librustc/Cargo.toml
src/librustc/hir/check_attr.rs
src/librustc/hir/lowering.rs
src/librustc/ich/impls_const_math.rs [deleted file]
src/librustc/ich/impls_mir.rs
src/librustc/ich/impls_syntax.rs
src/librustc/ich/impls_ty.rs
src/librustc/ich/mod.rs
src/librustc/infer/combine.rs
src/librustc/infer/higher_ranked/mod.rs
src/librustc/infer/lexical_region_resolve/mod.rs
src/librustc/infer/mod.rs
src/librustc/infer/region_constraints/mod.rs
src/librustc/infer/type_variable.rs
src/librustc/lib.rs
src/librustc/lint/levels.rs
src/librustc/lint/mod.rs
src/librustc/middle/const_val.rs
src/librustc/middle/region.rs
src/librustc/middle/stability.rs
src/librustc/mir/cache.rs
src/librustc/mir/interpret/error.rs
src/librustc/mir/interpret/mod.rs
src/librustc/mir/mod.rs
src/librustc/mir/traversal.rs
src/librustc/mir/visit.rs
src/librustc/session/config.rs
src/librustc/session/mod.rs
src/librustc/traits/on_unimplemented.rs
src/librustc/traits/project.rs
src/librustc/traits/query/normalize.rs
src/librustc/traits/select.rs
src/librustc/ty/context.rs
src/librustc/ty/fold.rs
src/librustc/ty/layout.rs
src/librustc/ty/mod.rs
src/librustc/ty/structural_impls.rs
src/librustc/ty/sty.rs
src/librustc/util/ppaux.rs
src/librustc_apfloat/ppc.rs
src/librustc_const_math/Cargo.toml [deleted file]
src/librustc_const_math/err.rs [deleted file]
src/librustc_const_math/float.rs [deleted file]
src/librustc_const_math/lib.rs [deleted file]
src/librustc_driver/lib.rs
src/librustc_incremental/assert_dep_graph.rs
src/librustc_lint/builtin.rs
src/librustc_lint/lib.rs
src/librustc_lint/unused.rs
src/librustc_mir/Cargo.toml
src/librustc_mir/borrow_check/mod.rs
src/librustc_mir/borrow_check/nll/explain_borrow/mod.rs
src/librustc_mir/borrow_check/nll/region_infer/dfs.rs
src/librustc_mir/borrow_check/nll/region_infer/mod.rs
src/librustc_mir/borrow_check/nll/type_check/mod.rs
src/librustc_mir/build/expr/as_place.rs
src/librustc_mir/build/expr/as_rvalue.rs
src/librustc_mir/dataflow/graphviz.rs
src/librustc_mir/hair/cx/mod.rs
src/librustc_mir/hair/pattern/mod.rs
src/librustc_mir/interpret/cast.rs
src/librustc_mir/interpret/eval_context.rs
src/librustc_mir/interpret/operator.rs
src/librustc_mir/interpret/terminator/mod.rs
src/librustc_mir/lib.rs
src/librustc_mir/transform/const_prop.rs
src/librustc_mir/transform/copy_prop.rs
src/librustc_mir/transform/deaggregator.rs
src/librustc_mir/transform/elaborate_drops.rs
src/librustc_mir/transform/generator.rs
src/librustc_mir/transform/inline.rs
src/librustc_mir/transform/remove_noop_landing_pads.rs
src/librustc_mir/transform/simplify.rs
src/librustc_mir/util/graphviz.rs
src/librustc_mir/util/liveness.rs
src/librustc_passes/Cargo.toml
src/librustc_passes/lib.rs
src/librustc_passes/mir_stats.rs
src/librustc_resolve/build_reduced_graph.rs
src/librustc_resolve/diagnostics.rs
src/librustc_resolve/lib.rs
src/librustc_resolve/macros.rs
src/librustc_resolve/resolve_imports.rs
src/librustc_target/abi/mod.rs
src/librustc_target/lib.rs
src/librustc_target/spec/apple_ios_base.rs
src/librustc_target/spec/i686_apple_darwin.rs
src/librustc_traits/dropck_outlives.rs
src/librustc_trans/Cargo.toml
src/librustc_trans/abi.rs
src/librustc_trans/attributes.rs
src/librustc_trans/debuginfo/metadata.rs
src/librustc_trans/debuginfo/mod.rs
src/librustc_trans/declare.rs
src/librustc_trans/lib.rs
src/librustc_trans/mir/analyze.rs
src/librustc_trans/mir/block.rs
src/librustc_trans/mir/place.rs
src/librustc_trans/mir/rvalue.rs
src/librustc_typeck/Cargo.toml
src/librustc_typeck/check/method/probe.rs
src/librustc_typeck/check/writeback.rs
src/librustc_typeck/lib.rs
src/librustdoc/clean/cfg.rs
src/librustdoc/clean/mod.rs
src/librustdoc/html/render.rs
src/librustdoc/html/static/main.js
src/librustdoc/lib.rs
src/librustdoc/visit_ast.rs
src/libstd/ffi/c_str.rs
src/libstd/lib.rs
src/libstd/macros.rs
src/libstd/path.rs
src/libstd/sync/mpsc/select.rs
src/libsyntax/ast.rs
src/libsyntax/attr.rs
src/libsyntax/diagnostic_list.rs
src/libsyntax/ext/expand.rs
src/libsyntax/ext/tt/macro_parser.rs
src/libsyntax/feature_gate.rs
src/libsyntax/lib.rs
src/libsyntax/parse/attr.rs
src/libsyntax/parse/mod.rs
src/libsyntax/parse/parser.rs
src/libsyntax/print/pp.rs
src/libsyntax/print/pprust.rs
src/libsyntax_ext/concat_idents.rs
src/libsyntax_ext/deriving/custom.rs
src/libsyntax_ext/deriving/generic/mod.rs
src/libsyntax_pos/lib.rs
src/test/codegen/force-frame-pointers.rs [new file with mode: 0644]
src/test/codegen/noreturnflag.rs
src/test/compile-fail-fulldeps/auxiliary/macro_crate_test.rs
src/test/compile-fail-fulldeps/gated-macro-reexports.rs [deleted file]
src/test/compile-fail/auxiliary/macro_non_reexport_2.rs [deleted file]
src/test/compile-fail/auxiliary/macro_reexport_1.rs [deleted file]
src/test/compile-fail/feature-gate-tool_attributes.rs [new file with mode: 0644]
src/test/compile-fail/macro-no-implicit-reexport.rs [deleted file]
src/test/compile-fail/macro-non-lifetime.rs [new file with mode: 0644]
src/test/compile-fail/macro-reexport-malformed-1.rs [deleted file]
src/test/compile-fail/macro-reexport-malformed-2.rs [deleted file]
src/test/compile-fail/macro-reexport-malformed-3.rs [deleted file]
src/test/compile-fail/macro-reexport-not-locally-visible.rs [deleted file]
src/test/compile-fail/macro-reexport-undef.rs [deleted file]
src/test/compile-fail/repr-align.rs
src/test/compile-fail/unknown-tool-name.rs [new file with mode: 0644]
src/test/compile-fail/unknown_tool_attributes-1.rs [new file with mode: 0644]
src/test/run-make-fulldeps/extern-prelude/Makefile [new file with mode: 0644]
src/test/run-make-fulldeps/extern-prelude/basic.rs [new file with mode: 0644]
src/test/run-make-fulldeps/extern-prelude/ep-lib.rs [new file with mode: 0644]
src/test/run-make-fulldeps/extern-prelude/ep-vec.rs [new file with mode: 0644]
src/test/run-make-fulldeps/extern-prelude/feature-gate.rs [new file with mode: 0644]
src/test/run-make-fulldeps/extern-prelude/relative-only.rs [new file with mode: 0644]
src/test/run-make-fulldeps/extern-prelude/shadow-mod.rs [new file with mode: 0644]
src/test/run-make-fulldeps/extern-prelude/shadow-prelude.rs [new file with mode: 0644]
src/test/run-pass-fulldeps/auxiliary/macro_crate_test.rs
src/test/run-pass-fulldeps/proc-macro/auxiliary/derive-reexport.rs [deleted file]
src/test/run-pass-fulldeps/proc-macro/use-reexport.rs [deleted file]
src/test/run-pass/auxiliary/macro_reexport_1.rs [deleted file]
src/test/run-pass/auxiliary/macro_reexport_2.rs [deleted file]
src/test/run-pass/auxiliary/macro_reexport_2_no_use.rs [deleted file]
src/test/run-pass/backtrace-debuginfo.rs
src/test/run-pass/extern-prelude-no-speculative.rs [new file with mode: 0644]
src/test/run-pass/issue-50415.rs [new file with mode: 0644]
src/test/run-pass/macro-reexport-no-intermediate-use.rs [deleted file]
src/test/run-pass/macro-reexport.rs [deleted file]
src/test/run-pass/repr_c_int_align.rs [new file with mode: 0644]
src/test/run-pass/tool_attributes.rs [new file with mode: 0644]
src/test/rustdoc-js/alias-2.js
src/test/rustdoc-js/alias.js
src/test/rustdoc-js/basic.js
src/test/rustdoc/cross-crate-links.rs
src/test/rustdoc/pub-use-extern-macros.rs
src/test/ui/const-eval/ice-packed.rs [new file with mode: 0644]
src/test/ui/const-eval/index_out_of_bound.stderr
src/test/ui/const-eval/promoted_errors.stderr
src/test/ui/error-codes/E0080.rs
src/test/ui/error-codes/E0080.stderr
src/test/ui/feature-gate-extern_prelude.rs [new file with mode: 0644]
src/test/ui/feature-gate-extern_prelude.stderr [new file with mode: 0644]
src/test/ui/feature-gate-fn_must_use-cap-lints-allow.rs [deleted file]
src/test/ui/feature-gate-fn_must_use-cap-lints-allow.stderr [deleted file]
src/test/ui/feature-gate-fn_must_use.rs [deleted file]
src/test/ui/feature-gate-fn_must_use.stderr [deleted file]
src/test/ui/feature-gate-tool_attributes.rs [new file with mode: 0644]
src/test/ui/feature-gate-tool_attributes.stderr [new file with mode: 0644]
src/test/ui/feature-gate/issue-43106-gating-of-builtin-attrs.rs
src/test/ui/feature-gate/issue-43106-gating-of-builtin-attrs.stderr
src/test/ui/fn_must_use.rs [new file with mode: 0644]
src/test/ui/fn_must_use.stderr [new file with mode: 0644]
src/test/ui/generator/borrowing.nll.stderr
src/test/ui/generator/borrowing.rs
src/test/ui/generator/dropck.nll.stderr
src/test/ui/generator/dropck.rs
src/test/ui/generator/dropck.stderr
src/test/ui/generator/ref-escapes-but-not-over-yield.nll.stderr
src/test/ui/inference_unstable.rs
src/test/ui/inference_unstable.stderr
src/test/ui/issue-50187.rs [new file with mode: 0644]
src/test/ui/issue-50403.rs [new file with mode: 0644]
src/test/ui/issue-50403.stderr [new file with mode: 0644]
src/test/ui/lint/must-use-ops.rs
src/test/ui/lint/must-use-ops.stderr
src/test/ui/macro-reexport-removed.rs [new file with mode: 0644]
src/test/ui/macro-reexport-removed.stderr [new file with mode: 0644]
src/test/ui/print_type_sizes/repr_int_c.rs [new file with mode: 0644]
src/test/ui/print_type_sizes/repr_int_c.stdout [new file with mode: 0644]
src/test/ui/rfc_1940-must_use_on_functions/fn_must_use.rs [deleted file]
src/test/ui/rfc_1940-must_use_on_functions/fn_must_use.stderr [deleted file]
src/test/ui/span/gated-features-attr-spans.rs
src/test/ui/span/gated-features-attr-spans.stderr
src/tools/cargo
src/tools/rls
src/tools/rustdoc-js/tester.js
src/tools/rustfmt

index a6f78a7e6b442a5b5a565802767e2a59c8989471..ccdb24d737551f0c3a35b086c05ae1b2cf995a12 100644 (file)
@@ -996,9 +996,10 @@ dependencies = [
 
 [[package]]
 name = "languageserver-types"
-version = "0.36.0"
+version = "0.39.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
+ "bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "enum_primitive 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "serde 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)",
  "serde_derive 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1623,7 +1624,7 @@ dependencies = [
 
 [[package]]
 name = "rls"
-version = "0.126.0"
+version = "0.127.0"
 dependencies = [
  "cargo 0.28.0",
  "cargo_metadata 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1632,7 +1633,7 @@ dependencies = [
  "failure 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "json 0.11.13 (registry+https://github.com/rust-lang/crates.io-index)",
  "jsonrpc-core 8.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "languageserver-types 0.36.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "languageserver-types 0.39.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1644,7 +1645,7 @@ dependencies = [
  "rls-rustc 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "rls-span 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "rls-vfs 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
- "rustfmt-nightly 0.6.0",
+ "rustfmt-nightly 0.6.1",
  "serde 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)",
  "serde_derive 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)",
  "serde_json 1.0.15 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1728,7 +1729,6 @@ dependencies = [
  "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "proc_macro 0.0.0",
  "rustc_apfloat 0.0.0",
- "rustc_const_math 0.0.0",
  "rustc_data_structures 0.0.0",
  "rustc_errors 0.0.0",
  "rustc_target 0.0.0",
@@ -1740,16 +1740,17 @@ dependencies = [
 
 [[package]]
 name = "rustc-ap-rustc_cratesio_shim"
-version = "110.0.0"
+version = "113.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "term 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "rustc-ap-rustc_data_structures"
-version = "110.0.0"
+version = "113.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1757,53 +1758,66 @@ dependencies = [
  "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "parking_lot 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "parking_lot_core 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)",
- "rustc-ap-serialize 110.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-rustc_cratesio_shim 113.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-serialize 113.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "stable_deref_trait 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "term 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "rustc-ap-rustc_errors"
-version = "110.0.0"
+version = "113.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "atty 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
- "rustc-ap-rustc_data_structures 110.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "rustc-ap-serialize 110.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "rustc-ap-syntax_pos 110.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-rustc_data_structures 113.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-serialize 113.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-syntax_pos 113.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "term 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "termcolor 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "unicode-width 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
+[[package]]
+name = "rustc-ap-rustc_target"
+version = "113.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-rustc_cratesio_shim 113.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-serialize 113.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "term 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
 [[package]]
 name = "rustc-ap-serialize"
-version = "110.0.0"
+version = "113.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "rustc-ap-syntax"
-version = "110.0.0"
+version = "113.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "rustc-ap-rustc_cratesio_shim 110.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "rustc-ap-rustc_data_structures 110.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "rustc-ap-rustc_errors 110.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "rustc-ap-serialize 110.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "rustc-ap-syntax_pos 110.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-rustc_data_structures 113.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-rustc_errors 113.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-rustc_target 113.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-serialize 113.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-syntax_pos 113.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "scoped-tls 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "term 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "rustc-ap-syntax_pos"
-version = "110.0.0"
+version = "113.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "rustc-ap-rustc_data_structures 110.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "rustc-ap-serialize 110.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-rustc_data_structures 113.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-serialize 113.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "scoped-tls 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "term 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "unicode-width 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1872,15 +1886,6 @@ dependencies = [
  "syntax_pos 0.0.0",
 ]
 
-[[package]]
-name = "rustc_const_math"
-version = "0.0.0"
-dependencies = [
- "rustc_apfloat 0.0.0",
- "serialize 0.0.0",
- "syntax 0.0.0",
-]
-
 [[package]]
 name = "rustc_cratesio_shim"
 version = "0.0.0"
@@ -2026,7 +2031,6 @@ dependencies = [
  "log_settings 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc 0.0.0",
  "rustc_apfloat 0.0.0",
- "rustc_const_math 0.0.0",
  "rustc_data_structures 0.0.0",
  "rustc_errors 0.0.0",
  "rustc_target 0.0.0",
@@ -2053,7 +2057,6 @@ version = "0.0.0"
 dependencies = [
  "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc 0.0.0",
- "rustc_const_math 0.0.0",
  "rustc_data_structures 0.0.0",
  "rustc_errors 0.0.0",
  "rustc_mir 0.0.0",
@@ -2154,7 +2157,6 @@ dependencies = [
  "rustc-demangle 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc_allocator 0.0.0",
  "rustc_apfloat 0.0.0",
- "rustc_const_math 0.0.0",
  "rustc_data_structures 0.0.0",
  "rustc_errors 0.0.0",
  "rustc_incremental 0.0.0",
@@ -2205,7 +2207,6 @@ dependencies = [
  "fmt_macros 0.0.0",
  "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc 0.0.0",
- "rustc_const_math 0.0.0",
  "rustc_data_structures 0.0.0",
  "rustc_errors 0.0.0",
  "rustc_platform_intrinsics 0.0.0",
@@ -2235,20 +2236,22 @@ dependencies = [
 
 [[package]]
 name = "rustfmt-nightly"
-version = "0.6.0"
+version = "0.6.1"
 dependencies = [
  "assert_cli 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)",
  "cargo_metadata 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)",
  "derive-new 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "diff 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)",
  "env_logger 0.5.8 (registry+https://github.com/rust-lang/crates.io-index)",
+ "failure 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "getopts 0.2.17 (registry+https://github.com/rust-lang/crates.io-index)",
  "itertools 0.7.8 (registry+https://github.com/rust-lang/crates.io-index)",
  "lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "regex 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)",
- "rustc-ap-syntax 110.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-rustc_target 113.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-syntax 113.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "serde 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)",
  "serde_derive 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)",
  "serde_json 1.0.15 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -3063,7 +3066,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 "checksum json 0.11.13 (registry+https://github.com/rust-lang/crates.io-index)" = "9ad0485404155f45cce53a40d4b2d6ac356418300daed05273d9e26f91c390be"
 "checksum jsonrpc-core 8.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ddf83704f4e79979a424d1082dd2c1e52683058056c9280efa19ac5f6bc9033c"
 "checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d"
-"checksum languageserver-types 0.36.0 (registry+https://github.com/rust-lang/crates.io-index)" = "174cdfb8bed13225bb419bec66ee1c970099c875688645f9c4a82e3af43ba69d"
+"checksum languageserver-types 0.39.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ad4cdd5e52d71aca47050e5b25f03082609c63a1e76b7362ebdd010895b3f854"
 "checksum lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "76f033c7ad61445c5b347c7382dd1237847eb1bce590fe50365dcb33d546be73"
 "checksum lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c8f31047daa365f19be14b47c29df4f7c3b581832407daabe6ae77397619237d"
 "checksum lazycell 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a6f08839bc70ef4a3fe1d566d5350f519c5912ea86be0df1740a7d247c7fc0ef"
@@ -3134,12 +3137,13 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 "checksum rls-rustc 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "885f66b92757420572cbb02e033d4a9558c7413ca9b7ac206f28fd58ffdb44ea"
 "checksum rls-span 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5d7c7046dc6a92f2ae02ed302746db4382e75131b9ce20ce967259f6b5867a6a"
 "checksum rls-vfs 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)" = "be231e1e559c315bc60ced5ad2cc2d7a9c208ed7d4e2c126500149836fda19bb"
-"checksum rustc-ap-rustc_cratesio_shim 110.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0256e318ad99c467d24bd7188f2d4a3028360621bb92d769b4b65fc44717d514"
-"checksum rustc-ap-rustc_data_structures 110.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "83430df7f76ea85c1f70fe145041576eee8fd5d77053bf426df24b480918d185"
-"checksum rustc-ap-rustc_errors 110.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2b03f874277103039816f6467b1ff30a81b1d6a29d4de6efccefe4c488f6535a"
-"checksum rustc-ap-serialize 110.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a2e47cf949f06b0c7ab7566c2f69d49f28cb3ecf1bb8bf0bda48b1ba5b7945ae"
-"checksum rustc-ap-syntax 110.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "625e6fb41fde299082cda3bceb08f81c9ba56b14a2ec737b4366f9c3c9be07d8"
-"checksum rustc-ap-syntax_pos 110.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "474a23ef1a1245ae02c5fd6a1e9a0725ce6fd25ca2294703c03bddce041f867b"
+"checksum rustc-ap-rustc_cratesio_shim 113.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a01334797c5c4cf56cc40bb9636d7b4c4a076665b9b9b7f100fd666cf0a02ffc"
+"checksum rustc-ap-rustc_data_structures 113.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "03d6f8f7da0de905f6ef80dc14dce3bbc372430622b6aeb421cf13190bc70e8a"
+"checksum rustc-ap-rustc_errors 113.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3dfd6183804a685c48601651d8c8c7b0daa8f83b0b5e24edfbcb6a0337085127"
+"checksum rustc-ap-rustc_target 113.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5f223157f51bf0e0621bef099de862468892ee4c4b83056f48f63e1bc00ccb72"
+"checksum rustc-ap-serialize 113.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2104a55a87d65cba8a845656f1f19a35da52af403863cd2a4bd5876ba522d879"
+"checksum rustc-ap-syntax 113.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b50671adb9b0a7c57a4690ac6a40cb614879f543b64aada42f55b66212492323"
+"checksum rustc-ap-syntax_pos 113.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "55793c2a775230c42661194c48d44b35d4c8439d79ad8528e56651e854c48c63"
 "checksum rustc-demangle 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "11fb43a206a04116ffd7cfcf9bcb941f8eb6cc7ff667272246b0a1c74259a3cb"
 "checksum rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)" = "dcf128d1287d2ea9d80910b5f1120d0b8eede3fbf1abe91c40d39ea7d51e6fda"
 "checksum same-file 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "d931a44fdaa43b8637009e7632a02adc4f2b2e0733c08caa4cf00e8da4a117a7"
index 814c054c51e41eaff3c6b155110474f8a252c3e8..35858ee286838c5b8d7563e2fb295e29036322be 100644 (file)
@@ -40,14 +40,6 @@ members = [
   "tools/rls/test_data/workspace_symbol",
 ]
 
-# Curiously, compiletest will segfault if compiled with opt-level=3 on 64-bit
-# MSVC when running the compile-fail test suite when a should-fail test panics.
-# But hey if this is removed and it gets past the bots, sounds good to me.
-[profile.release]
-opt-level = 2
-[profile.bench]
-opt-level = 2
-
 # These options are controlled from our rustc wrapper script, so turn them off
 # here and have them controlled elsewhere.
 [profile.dev]
index 1b4b2c5fb2a54cab90d9bf633b6dfabd4f6b8d78..7175f6a67642bf37c6ae92384fe15e0f140184ae 100644 (file)
@@ -325,6 +325,14 @@ struct TomlTarget {
 }
 
 impl Config {
+    fn path_from_python(var_key: &str) -> PathBuf {
+        match env::var_os(var_key) {
+            // Do not trust paths from Python and normalize them slightly (#49785).
+            Some(var_val) => Path::new(&var_val).components().collect(),
+            _ => panic!("expected '{}' to be set", var_key),
+        }
+    }
+
     pub fn default_opts() -> Config {
         let mut config = Config::default();
         config.llvm_enabled = true;
@@ -348,9 +356,9 @@ pub fn default_opts() -> Config {
         config.deny_warnings = true;
 
         // set by bootstrap.py
-        config.src = env::var_os("SRC").map(PathBuf::from).expect("'SRC' to be set");
         config.build = INTERNER.intern_str(&env::var("BUILD").expect("'BUILD' to be set"));
-        config.out = env::var_os("BUILD_DIR").map(PathBuf::from).expect("'BUILD_DIR' set");
+        config.src = Config::path_from_python("SRC");
+        config.out = Config::path_from_python("BUILD_DIR");
 
         let stage0_root = config.out.join(&config.build).join("stage0/bin");
         config.initial_rustc = stage0_root.join(exe("rustc", &config.build));
diff --git a/src/doc/unstable-book/src/language-features/fn-must-use.md b/src/doc/unstable-book/src/language-features/fn-must-use.md
deleted file mode 100644 (file)
index 71b6cd6..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-# `fn_must_use`
-
-The tracking issue for this feature is [#43302].
-
-[#43302]: https://github.com/rust-lang/rust/issues/43302
-
-------------------------
-
-The `fn_must_use` feature allows functions and methods to be annotated with
-`#[must_use]`, indicating that the `unused_must_use` lint should require their
-return values to be used (similarly to how types annotated with `must_use`,
-most notably `Result`, are linted if not used).
-
-## Examples
-
-```rust
-#![feature(fn_must_use)]
-
-#[must_use]
-fn double(x: i32) -> i32 {
-    2 * x
-}
-
-fn main() {
-    double(4); // warning: unused return value of `double` which must be used
-
-    let _ = double(4); // (no warning)
-}
-
-```
diff --git a/src/doc/unstable-book/src/language-features/tool-attributes.md b/src/doc/unstable-book/src/language-features/tool-attributes.md
new file mode 100644 (file)
index 0000000..15fc84a
--- /dev/null
@@ -0,0 +1,26 @@
+# `tool_attributes`
+
+The tracking issue for this feature is: [#44690]
+
+[#44690]: https://github.com/rust-lang/rust/issues/44690
+
+------------------------
+
+Tool attributes let you use scoped attributes to control the behavior
+of certain tools.
+
+Currently tool names which can be appear in scoped attributes are restricted to
+`clippy` and `rustfmt`.
+
+## An example
+
+```rust
+#![feature(tool_attributes)]
+
+#[rustfmt::skip]
+fn foo() { println!("hello, world"); }
+
+fn main() {
+    foo();
+}
+```
index 0493f92bc520d1747432fec5e60ab9e6f0410a33..da4b76a4d527d41ee755812ffae464e780e2e4c4 100644 (file)
@@ -96,7 +96,7 @@
 #![feature(dropck_eyepatch)]
 #![feature(exact_size_is_empty)]
 #![feature(fmt_internals)]
-#![feature(fn_must_use)]
+#![cfg_attr(stage0, feature(fn_must_use))]
 #![feature(from_ref)]
 #![feature(fundamental)]
 #![feature(lang_items)]
 #![feature(on_unimplemented)]
 #![feature(exact_chunks)]
 #![feature(pointer_methods)]
-#![feature(inclusive_range_fields)]
+#![feature(inclusive_range_methods)]
 #![cfg_attr(stage0, feature(generic_param_attrs))]
 #![feature(rustc_const_unstable)]
 
index 32272169307000cf1269593fb6f1dd1a1c5bb7ad..1c8ff316e55aab6fdaf4aae5ff8872ad835c9f5d 100644 (file)
@@ -25,7 +25,7 @@
 #![feature(try_reserve)]
 #![feature(unboxed_closures)]
 #![feature(exact_chunks)]
-#![feature(inclusive_range_fields)]
+#![feature(inclusive_range_methods)]
 
 extern crate alloc_system;
 extern crate core;
index 99d9c51efc75790c2e552c89d6490423445a2292..6fd0b33f02a60a9632249c6be29dac951d248ea7 100644 (file)
@@ -1282,6 +1282,7 @@ fn test_box_slice_clone() {
 }
 
 #[test]
+#[allow(unused_must_use)] // here, we care about the side effects of `.clone()`
 #[cfg_attr(target_os = "emscripten", ignore)]
 fn test_box_slice_clone_panics() {
     use std::sync::Arc;
index 0e21a3327fddf471f6a486fb9e1f222f5e545981..04dd42583d406eb468e646e10bfd56dbcf81be8a 100644 (file)
@@ -76,7 +76,6 @@
 #![feature(doc_cfg)]
 #![feature(doc_spotlight)]
 #![feature(extern_types)]
-#![feature(fn_must_use)]
 #![feature(fundamental)]
 #![feature(intrinsics)]
 #![feature(iterator_flatten)]
 #![feature(untagged_unions)]
 #![feature(unwind_attributes)]
 #![feature(doc_alias)]
+#![feature(inclusive_range_methods)]
 
 #![cfg_attr(not(stage0), feature(mmx_target_feature))]
 #![cfg_attr(not(stage0), feature(tbm_target_feature))]
 
 #![cfg_attr(stage0, feature(target_feature))]
 #![cfg_attr(stage0, feature(cfg_target_feature))]
+#![cfg_attr(stage0, feature(fn_must_use))]
 
 #[prelude_import]
 #[allow(unused)]
index f9371ed0575e49782f7471320d83c5b852d663a1..c830c22ee5f50b1c58a46732cbe56036882756c2 100644 (file)
@@ -606,8 +606,8 @@ macro_rules! option_env {
     #[macro_export]
     #[cfg(dox)]
     macro_rules! concat_idents {
-        ($($e:ident),*) => ({ /* compiler built-in */ });
-        ($($e:ident,)*) => ({ /* compiler built-in */ });
+        ($($e:ident),+) => ({ /* compiler built-in */ });
+        ($($e:ident,)+) => ({ /* compiler built-in */ });
     }
 
     /// Concatenates literals into a static string slice.
index d70f7ae66f9038ee27f8b8ff0e8342539cbda178..b01a769eda7fd4201e7239003425d93cbb26e937 100644 (file)
@@ -318,9 +318,9 @@ pub fn contains<U>(&self, item: &U) -> bool
 /// # Examples
 ///
 /// ```
-/// #![feature(inclusive_range_fields)]
+/// #![feature(inclusive_range_methods)]
 ///
-/// assert_eq!((3..=5), std::ops::RangeInclusive { start: 3, end: 5 });
+/// assert_eq!((3..=5), std::ops::RangeInclusive::new(3, 5));
 /// assert_eq!(3 + 4 + 5, (3..=5).sum());
 ///
 /// let arr = [0, 1, 2, 3];
@@ -331,14 +331,88 @@ pub fn contains<U>(&self, item: &U) -> bool
 #[derive(Clone, PartialEq, Eq, Hash)]  // not Copy -- see #27186
 #[stable(feature = "inclusive_range", since = "1.26.0")]
 pub struct RangeInclusive<Idx> {
+    // FIXME: The current representation follows RFC 1980,
+    // but it is known that LLVM is not able to optimize loops following that RFC.
+    // Consider adding an extra `bool` field to indicate emptiness of the range.
+    // See #45222 for performance test cases.
+    #[cfg(not(stage0))]
+    pub(crate) start: Idx,
+    #[cfg(not(stage0))]
+    pub(crate) end: Idx,
     /// The lower bound of the range (inclusive).
+    #[cfg(stage0)]
     #[unstable(feature = "inclusive_range_fields", issue = "49022")]
     pub start: Idx,
     /// The upper bound of the range (inclusive).
+    #[cfg(stage0)]
     #[unstable(feature = "inclusive_range_fields", issue = "49022")]
     pub end: Idx,
 }
 
+impl<Idx> RangeInclusive<Idx> {
+    /// Creates a new inclusive range. Equivalent to writing `start..=end`.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(inclusive_range_methods)]
+    /// use std::ops::RangeInclusive;
+    ///
+    /// assert_eq!(3..=5, RangeInclusive::new(3, 5));
+    /// ```
+    #[unstable(feature = "inclusive_range_methods", issue = "49022")]
+    #[inline]
+    pub const fn new(start: Idx, end: Idx) -> Self {
+        Self { start, end }
+    }
+
+    /// Returns the lower bound of the range (inclusive).
+    ///
+    /// When using an inclusive range for iteration, the values of `start()` and
+    /// [`end()`] are unspecified after the iteration ended. To determine
+    /// whether the inclusive range is empty, use the [`is_empty()`] method
+    /// instead of comparing `start() > end()`.
+    ///
+    /// [`end()`]: #method.end
+    /// [`is_empty()`]: #method.is_empty
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(inclusive_range_methods)]
+    ///
+    /// assert_eq!((3..=5).start(), &3);
+    /// ```
+    #[unstable(feature = "inclusive_range_methods", issue = "49022")]
+    #[inline]
+    pub fn start(&self) -> &Idx {
+        &self.start
+    }
+
+    /// Returns the upper bound of the range (inclusive).
+    ///
+    /// When using an inclusive range for iteration, the values of [`start()`]
+    /// and `end()` are unspecified after the iteration ended. To determine
+    /// whether the inclusive range is empty, use the [`is_empty()`] method
+    /// instead of comparing `start() > end()`.
+    ///
+    /// [`start()`]: #method.start
+    /// [`is_empty()`]: #method.is_empty
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(inclusive_range_methods)]
+    ///
+    /// assert_eq!((3..=5).end(), &5);
+    /// ```
+    #[unstable(feature = "inclusive_range_methods", issue = "49022")]
+    #[inline]
+    pub fn end(&self) -> &Idx {
+        &self.end
+    }
+}
+
 #[stable(feature = "inclusive_range", since = "1.26.0")]
 impl<Idx: fmt::Debug> fmt::Debug for RangeInclusive<Idx> {
     fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
index 69c9cb37dcfd3278aa1a6a347a35d51b98bba32a..469404f7f6bb080d7c55209bc89cd6c884ff4597 100644 (file)
@@ -39,21 +39,10 @@ fn repeat_byte(b: u8) -> usize {
     (b as usize) << 8 | b as usize
 }
 
-#[cfg(target_pointer_width = "32")]
+#[cfg(not(target_pointer_width = "16"))]
 #[inline]
 fn repeat_byte(b: u8) -> usize {
-    let mut rep = (b as usize) << 8 | b as usize;
-    rep = rep << 16 | rep;
-    rep
-}
-
-#[cfg(target_pointer_width = "64")]
-#[inline]
-fn repeat_byte(b: u8) -> usize {
-    let mut rep = (b as usize) << 8 | b as usize;
-    rep = rep << 16 | rep;
-    rep = rep << 32 | rep;
-    rep
+    (b as usize) * (::usize::MAX / 255)
 }
 
 /// Return the first index matching the byte `x` in `text`.
index e4d277179382f3e522259bbc67abebafaab8b3d4..f6750c590b33ab97303f7f5b3231bbd7caa334df 100644 (file)
@@ -44,7 +44,7 @@
 #![feature(exact_chunks)]
 #![cfg_attr(stage0, feature(atomic_nand))]
 #![feature(reverse_bits)]
-#![feature(inclusive_range_fields)]
+#![feature(inclusive_range_methods)]
 #![feature(iterator_find_map)]
 
 extern crate core;
index bed08f86d72c124e4851f46364ddaf4eaee80b74..d66193b1687c86c921687f589862cbbf2cd94815 100644 (file)
@@ -50,21 +50,21 @@ fn test_full_range() {
 
 #[test]
 fn test_range_inclusive() {
-    let mut r = RangeInclusive { start: 1i8, end: 2 };
+    let mut r = RangeInclusive::new(1i8, 2);
     assert_eq!(r.next(), Some(1));
     assert_eq!(r.next(), Some(2));
     assert_eq!(r.next(), None);
 
-    r = RangeInclusive { start: 127i8, end: 127 };
+    r = RangeInclusive::new(127i8, 127);
     assert_eq!(r.next(), Some(127));
     assert_eq!(r.next(), None);
 
-    r = RangeInclusive { start: -128i8, end: -128 };
+    r = RangeInclusive::new(-128i8, -128);
     assert_eq!(r.next_back(), Some(-128));
     assert_eq!(r.next_back(), None);
 
     // degenerate
-    r = RangeInclusive { start: 1, end: -1 };
+    r = RangeInclusive::new(1, -1);
     assert_eq!(r.size_hint(), (0, Some(0)));
     assert_eq!(r.next(), None);
 }
index 3e45b08f399dca57d0fe3535f211b47a987130e6..0e6437fded594c3a18a8a5a5ed6b0fc474026ab3 100644 (file)
@@ -42,15 +42,15 @@ pub struct BoolTrie {
 }
 impl BoolTrie {
     pub fn lookup(&self, c: char) -> bool {
-        let c = c as usize;
+        let c = c as u32;
         if c < 0x800 {
-            trie_range_leaf(c, self.r1[c >> 6])
+            trie_range_leaf(c, self.r1[(c >> 6) as usize])
         } else if c < 0x10000 {
-            let child = self.r2[(c >> 6) - 0x20];
+            let child = self.r2[(c >> 6) as usize - 0x20];
             trie_range_leaf(c, self.r3[child as usize])
         } else {
-            let child = self.r4[(c >> 12) - 0x10];
-            let leaf = self.r5[((child as usize) << 6) + ((c >> 6) & 0x3f)];
+            let child = self.r4[(c >> 12) as usize - 0x10];
+            let leaf = self.r5[((child as usize) << 6) + ((c >> 6) as usize & 0x3f)];
             trie_range_leaf(c, self.r6[leaf as usize])
         }
     }
@@ -63,14 +63,14 @@ pub struct SmallBoolTrie {
 
 impl SmallBoolTrie {
     pub fn lookup(&self, c: char) -> bool {
-        let c = c as usize;
-        match self.r1.get(c >> 6) {
+        let c = c as u32;
+        match self.r1.get((c >> 6) as usize) {
             Some(&child) => trie_range_leaf(c, self.r2[child as usize]),
             None => false,
         }
     }
 }
 
-fn trie_range_leaf(c: usize, bitmap_chunk: u64) -> bool {
+fn trie_range_leaf(c: u32, bitmap_chunk: u64) -> bool {
     ((bitmap_chunk >> (c & 63)) & 1) != 0
 }
index 357ebb89fb65242bfdd31cb96e95a4be1be9bdc2..af108188ce0f476b5d40da5a697701b1be49b65c 100644 (file)
@@ -19,7 +19,6 @@ log = { version = "0.4", features = ["release_max_level_info", "std"] }
 proc_macro = { path = "../libproc_macro" }
 rustc_apfloat = { path = "../librustc_apfloat" }
 rustc_target = { path = "../librustc_target" }
-rustc_const_math = { path = "../librustc_const_math" }
 rustc_data_structures = { path = "../librustc_data_structures" }
 rustc_errors = { path = "../librustc_errors" }
 serialize = { path = "../libserialize" }
index cad6ff8ae9fc2a1ca584d853810f5eaab159d1be..24a1256c9d35bdf16bdaccd11a99c563f1a99f33 100644 (file)
@@ -153,10 +153,7 @@ fn check_repr(&self, item: &hir::Item, target: Target) {
         // ```
         let hints: Vec<_> = item.attrs
             .iter()
-            .filter(|attr| match attr.name() {
-                Some(name) => name == "repr",
-                None => false,
-            })
+            .filter(|attr| attr.name() == "repr")
             .filter_map(|attr| attr.meta_item_list())
             .flat_map(|hints| hints)
             .collect();
@@ -311,7 +308,7 @@ fn check_expr_attributes(&self, expr: &hir::Expr) {
 
     fn check_used(&self, item: &hir::Item, target: Target) {
         for attr in &item.attrs {
-            if attr.name().map(|name| name == "used").unwrap_or(false) && target != Target::Static {
+            if attr.name() == "used" && target != Target::Static {
                 self.tcx.sess
                     .span_err(attr.span, "attribute must be applied to a `static` variable");
             }
index e4b9fc1385d4070904d0f850aa0068d27f9fee35..51f0c1d7047c91613c76e3ece8213546ec6db877 100644 (file)
@@ -3119,6 +3119,20 @@ fn lower_expr(&mut self, e: &Expr) -> hir::Expr {
             ExprKind::Index(ref el, ref er) => {
                 hir::ExprIndex(P(self.lower_expr(el)), P(self.lower_expr(er)))
             }
+            // Desugar `<start>..=<end>` to `std::ops::RangeInclusive::new(<start>, <end>)`
+            ExprKind::Range(Some(ref e1), Some(ref e2), RangeLimits::Closed) => {
+                // FIXME: Use e.span directly after RangeInclusive::new() is stabilized in stage0.
+                let span = self.allow_internal_unstable(CompilerDesugaringKind::DotFill, e.span);
+                let id = self.next_id();
+                let e1 = self.lower_expr(e1);
+                let e2 = self.lower_expr(e2);
+                let ty_path = P(self.std_path(span, &["ops", "RangeInclusive"], false));
+                let ty = self.ty_path(id, span, hir::QPath::Resolved(None, ty_path));
+                let new_seg = P(hir::PathSegment::from_name(Symbol::intern("new")));
+                let new_path = hir::QPath::TypeRelative(ty, new_seg);
+                let new = P(self.expr(span, hir::ExprPath(new_path), ThinVec::new()));
+                hir::ExprCall(new, hir_vec![e1, e2])
+            }
             ExprKind::Range(ref e1, ref e2, lims) => {
                 use syntax::ast::RangeLimits::*;
 
@@ -3128,7 +3142,7 @@ fn lower_expr(&mut self, e: &Expr) -> hir::Expr {
                     (&None, &Some(..), HalfOpen) => "RangeTo",
                     (&Some(..), &Some(..), HalfOpen) => "Range",
                     (&None, &Some(..), Closed) => "RangeToInclusive",
-                    (&Some(..), &Some(..), Closed) => "RangeInclusive",
+                    (&Some(..), &Some(..), Closed) => unreachable!(),
                     (_, &None, Closed) => self.diagnostic()
                         .span_fatal(e.span, "inclusive range with no end")
                         .raise(),
diff --git a/src/librustc/ich/impls_const_math.rs b/src/librustc/ich/impls_const_math.rs
deleted file mode 100644 (file)
index 5f3ff46..0000000
+++ /dev/null
@@ -1,44 +0,0 @@
-// 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.
-
-//! This module contains `HashStable` implementations for various data types
-//! from `rustc_const_math` in no particular order.
-
-impl_stable_hash_for!(struct ::rustc_const_math::ConstFloat {
-    ty,
-    bits
-});
-
-impl_stable_hash_for!(enum ::rustc_const_math::ConstMathErr {
-    NotInRange,
-    CmpBetweenUnequalTypes,
-    UnequalTypes(op),
-    Overflow(op),
-    ShiftNegative,
-    DivisionByZero,
-    RemainderByZero,
-    UnsignedNegation,
-    ULitOutOfRange(int_ty),
-    LitOutOfRange(int_ty)
-});
-
-impl_stable_hash_for!(enum ::rustc_const_math::Op {
-    Add,
-    Sub,
-    Mul,
-    Div,
-    Rem,
-    Shr,
-    Shl,
-    Neg,
-    BitAnd,
-    BitOr,
-    BitXor
-});
index 437626ff5369abd40814b959d38b2cb2b8a434d6..33f43e53394f59905335e50ed4420360a052ea97 100644 (file)
@@ -227,27 +227,6 @@ fn hash_stable<W: StableHasherResult>(&self,
     }
 }
 
-impl<'a, 'gcx> HashStable<StableHashingContext<'a>>
-for mir::AssertMessage<'gcx> {
-    fn hash_stable<W: StableHasherResult>(&self,
-                                          hcx: &mut StableHashingContext<'a>,
-                                          hasher: &mut StableHasher<W>) {
-        mem::discriminant(self).hash_stable(hcx, hasher);
-
-        match *self {
-            mir::AssertMessage::BoundsCheck { ref len, ref index } => {
-                len.hash_stable(hcx, hasher);
-                index.hash_stable(hcx, hasher);
-            }
-            mir::AssertMessage::Math(ref const_math_err) => {
-                const_math_err.hash_stable(hcx, hasher);
-            }
-            mir::AssertMessage::GeneratorResumedAfterReturn => (),
-            mir::AssertMessage::GeneratorResumedAfterPanic => (),
-        }
-    }
-}
-
 impl_stable_hash_for!(struct mir::Statement<'tcx> { source_info, kind });
 
 impl<'a, 'gcx> HashStable<StableHashingContext<'a>>
index c1e86473996d0f82bb3416954ec4e3634e95936f..1cf9b7bf4780e785a8a2b52a4035201fc7e465ce 100644 (file)
@@ -199,8 +199,7 @@ fn hash_stable<W: StableHasherResult>(&self,
         let filtered: AccumulateVec<[&ast::Attribute; 8]> = self
             .iter()
             .filter(|attr| {
-                !attr.is_sugared_doc &&
-                attr.name().map(|name| !hcx.is_ignored_attr(name)).unwrap_or(true)
+                !attr.is_sugared_doc && !hcx.is_ignored_attr(attr.name())
             })
             .collect();
 
@@ -211,12 +210,23 @@ fn hash_stable<W: StableHasherResult>(&self,
     }
 }
 
+impl<'a> HashStable<StableHashingContext<'a>> for ast::Path {
+    fn hash_stable<W: StableHasherResult>(&self,
+                                          hcx: &mut StableHashingContext<'a>,
+                                          hasher: &mut StableHasher<W>) {
+        self.segments.len().hash_stable(hcx, hasher);
+        for segment in &self.segments {
+            segment.ident.name.hash_stable(hcx, hasher);
+        }
+    }
+}
+
 impl<'a> HashStable<StableHashingContext<'a>> for ast::Attribute {
     fn hash_stable<W: StableHasherResult>(&self,
                                           hcx: &mut StableHashingContext<'a>,
                                           hasher: &mut StableHasher<W>) {
         // Make sure that these have been filtered out.
-        debug_assert!(self.name().map(|name| !hcx.is_ignored_attr(name)).unwrap_or(true));
+        debug_assert!(!hcx.is_ignored_attr(self.name()));
         debug_assert!(!self.is_sugared_doc);
 
         let ast::Attribute {
@@ -229,10 +239,7 @@ fn hash_stable<W: StableHasherResult>(&self,
         } = *self;
 
         style.hash_stable(hcx, hasher);
-        path.segments.len().hash_stable(hcx, hasher);
-        for segment in &path.segments {
-            segment.ident.name.hash_stable(hcx, hasher);
-        }
+        path.hash_stable(hcx, hasher);
         for tt in tokens.trees() {
             tt.hash_stable(hcx, hasher);
         }
index 5ab8d6eb7b3e011de9fe1fb65518dac861827b44..a40d8e09277406397ec1415f75e77afb8fb7b002 100644 (file)
@@ -505,9 +505,6 @@ fn hash_stable<W: StableHasherResult>(&self,
                 len.hash_stable(hcx, hasher);
                 index.hash_stable(hcx, hasher);
             }
-            Math(ref const_math_err) => {
-                const_math_err.hash_stable(hcx, hasher);
-            }
             LayoutError(ref layout_error) => {
                 layout_error.hash_stable(hcx, hasher);
             }
@@ -528,16 +525,26 @@ fn hash_stable<W: StableHasherResult>(&self,
     predicates
 });
 
+
 impl<'a, 'gcx> HashStable<StableHashingContext<'a>>
 for ::mir::interpret::EvalError<'gcx> {
+    fn hash_stable<W: StableHasherResult>(&self,
+                                          hcx: &mut StableHashingContext<'a>,
+                                          hasher: &mut StableHasher<W>) {
+        self.kind.hash_stable(hcx, hasher)
+    }
+}
+
+impl<'a, 'gcx, O: HashStable<StableHashingContext<'a>>> HashStable<StableHashingContext<'a>>
+for ::mir::interpret::EvalErrorKind<'gcx, O> {
     fn hash_stable<W: StableHasherResult>(&self,
                                           hcx: &mut StableHashingContext<'a>,
                                           hasher: &mut StableHasher<W>) {
         use mir::interpret::EvalErrorKind::*;
 
-        mem::discriminant(&self.kind).hash_stable(hcx, hasher);
+        mem::discriminant(&self).hash_stable(hcx, hasher);
 
-        match self.kind {
+        match *self {
             DanglingPointerDeref |
             DoubleFree |
             InvalidMemoryAccess |
@@ -568,8 +575,12 @@ fn hash_stable<W: StableHasherResult>(&self,
             TypeckError |
             DerefFunctionPointer |
             ExecuteMemory |
-            ReferencedConstant |
-            OverflowingMath => {}
+            OverflowNeg |
+            RemainderByZero |
+            DivisionByZero |
+            GeneratorResumedAfterReturn |
+            GeneratorResumedAfterPanic |
+            ReferencedConstant => {}
             MachineError(ref err) => err.hash_stable(hcx, hasher),
             FunctionPointerTyMismatch(a, b) => {
                 a.hash_stable(hcx, hasher);
@@ -588,14 +599,9 @@ fn hash_stable<W: StableHasherResult>(&self,
             },
             InvalidBoolOp(bop) => bop.hash_stable(hcx, hasher),
             Unimplemented(ref s) => s.hash_stable(hcx, hasher),
-            ArrayIndexOutOfBounds(sp, a, b) => {
-                sp.hash_stable(hcx, hasher);
-                a.hash_stable(hcx, hasher);
-                b.hash_stable(hcx, hasher)
-            },
-            Math(sp, ref err) => {
-                sp.hash_stable(hcx, hasher);
-                err.hash_stable(hcx, hasher)
+            BoundsCheck { ref len, ref index } => {
+                len.hash_stable(hcx, hasher);
+                index.hash_stable(hcx, hasher)
             },
             Intrinsic(ref s) => s.hash_stable(hcx, hasher),
             InvalidChar(c) => c.hash_stable(hcx, hasher),
@@ -668,6 +674,7 @@ fn hash_stable<W: StableHasherResult>(&self,
             Layout(lay) => lay.hash_stable(hcx, hasher),
             HeapAllocNonPowerOfTwoAlignment(n) => n.hash_stable(hcx, hasher),
             PathNotFound(ref v) => v.hash_stable(hcx, hasher),
+            Overflow(op) => op.hash_stable(hcx, hasher),
         }
     }
 }
index 1b77a2e7c82b985d119b0fbdef3d9dd2e1c18d7e..a0c6bbbb2393f83929c88980f2740ac515d6f4dc 100644 (file)
@@ -18,7 +18,6 @@
 mod caching_codemap_view;
 mod hcx;
 
-mod impls_const_math;
 mod impls_cstore;
 mod impls_hir;
 mod impls_mir;
index 096aed85f55e05ac0de46b23f33566ad3041d022..ccba5a09cf6cc92433f3430288ad30cb567d4389 100644 (file)
@@ -407,7 +407,7 @@ fn tys(&mut self, t: Ty<'tcx>, t2: Ty<'tcx>) -> RelateResult<'tcx, Ty<'tcx>> {
                             drop(variables);
                             self.relate(&u, &u)
                         }
-                        TypeVariableValue::Unknown { .. } => {
+                        TypeVariableValue::Unknown { universe } => {
                             match self.ambient_variance {
                                 // Invariant: no need to make a fresh type variable.
                                 ty::Invariant => return Ok(t),
@@ -424,7 +424,7 @@ fn tys(&mut self, t: Ty<'tcx>, t2: Ty<'tcx>) -> RelateResult<'tcx, Ty<'tcx>> {
                             }
 
                             let origin = *variables.var_origin(vid);
-                            let new_var_id = variables.new_var(false, origin);
+                            let new_var_id = variables.new_var(universe, false, origin);
                             let u = self.tcx().mk_var(new_var_id);
                             debug!("generalize: replacing original vid={:?} with new={:?}",
                                    vid, u);
index c35cdf91fe7bfecb7d8f10d8e6d0b14c97849e6e..b8437e39ddca48c6118fbbc91ba5e0b52fed6297 100644 (file)
@@ -62,7 +62,7 @@ pub fn higher_ranked_sub<T>(&mut self, a: &Binder<T>, b: &Binder<T>, a_is_expect
             // Second, we instantiate each bound region in the supertype with a
             // fresh concrete region.
             let (b_prime, skol_map) =
-                self.infcx.skolemize_late_bound_regions(b, snapshot);
+                self.infcx.skolemize_late_bound_regions(b);
 
             debug!("a_prime={:?}", a_prime);
             debug!("b_prime={:?}", b_prime);
@@ -114,7 +114,7 @@ pub fn higher_ranked_match<T, U>(&mut self,
             // First, we instantiate each bound region in the matcher
             // with a skolemized region.
             let ((a_match, a_value), skol_map) =
-                self.infcx.skolemize_late_bound_regions(a_pair, snapshot);
+                self.infcx.skolemize_late_bound_regions(a_pair);
 
             debug!("higher_ranked_match: a_match={:?}", a_match);
             debug!("higher_ranked_match: skol_map={:?}", skol_map);
@@ -587,14 +587,13 @@ fn region_vars_confined_to_snapshot(&self,
     ///
     /// [rustc guide]: https://rust-lang-nursery.github.io/rustc-guide/trait-hrtb.html
     pub fn skolemize_late_bound_regions<T>(&self,
-                                           binder: &ty::Binder<T>,
-                                           snapshot: &CombinedSnapshot<'a, 'tcx>)
+                                           binder: &ty::Binder<T>)
                                            -> (T, SkolemizationMap<'tcx>)
         where T : TypeFoldable<'tcx>
     {
         let (result, map) = self.tcx.replace_late_bound_regions(binder, |br| {
-            self.borrow_region_constraints()
-                .push_skolemized(self.tcx, br, &snapshot.region_constraints_snapshot)
+            self.universe.set(self.universe().subuniverse());
+            self.tcx.mk_region(ty::ReSkolemized(self.universe(), br))
         });
 
         debug!("skolemize_bound_regions(binder={:?}, result={:?}, map={:?})",
@@ -779,7 +778,8 @@ pub fn pop_skolemized(&self,
         debug!("pop_skolemized({:?})", skol_map);
         let skol_regions: FxHashSet<_> = skol_map.values().cloned().collect();
         self.borrow_region_constraints()
-            .pop_skolemized(self.tcx, &skol_regions, &snapshot.region_constraints_snapshot);
+            .pop_skolemized(self.universe(), &skol_regions, &snapshot.region_constraints_snapshot);
+        self.universe.set(snapshot.universe);
         if !skol_map.is_empty() {
             self.projection_cache.borrow_mut().rollback_skolemized(
                 &snapshot.projection_cache_snapshot);
index 00b2ac7449f7e9a9ac1e5378296d3c560b25eadb..5984a831e6fa0eeb4028a539040af99763d2de31 100644 (file)
@@ -15,7 +15,7 @@
 use infer::region_constraints::Constraint;
 use infer::region_constraints::GenericKind;
 use infer::region_constraints::RegionConstraintData;
-use infer::region_constraints::VarOrigins;
+use infer::region_constraints::VarInfos;
 use infer::region_constraints::VerifyBound;
 use middle::free_region::RegionRelations;
 use rustc_data_structures::indexed_vec::{Idx, IndexVec};
@@ -37,7 +37,7 @@
 /// all the variables as well as a set of errors that must be reported.
 pub fn resolve<'tcx>(
     region_rels: &RegionRelations<'_, '_, 'tcx>,
-    var_origins: VarOrigins,
+    var_infos: VarInfos,
     data: RegionConstraintData<'tcx>,
 ) -> (
     LexicalRegionResolutions<'tcx>,
@@ -47,7 +47,7 @@ pub fn resolve<'tcx>(
     let mut errors = vec![];
     let mut resolver = LexicalResolver {
         region_rels,
-        var_origins,
+        var_infos,
         data,
     };
     let values = resolver.infer_variable_values(&mut errors);
@@ -103,7 +103,7 @@ struct RegionAndOrigin<'tcx> {
 
 struct LexicalResolver<'cx, 'gcx: 'tcx, 'tcx: 'cx> {
     region_rels: &'cx RegionRelations<'cx, 'gcx, 'tcx>,
-    var_origins: VarOrigins,
+    var_infos: VarInfos,
     data: RegionConstraintData<'tcx>,
 }
 
@@ -132,7 +132,7 @@ fn infer_variable_values(
     }
 
     fn num_vars(&self) -> usize {
-        self.var_origins.len()
+        self.var_infos.len()
     }
 
     /// Initially, the value for all variables is set to `'empty`, the
@@ -279,7 +279,7 @@ fn lub_concrete_regions(&self, a: Region<'tcx>, b: Region<'tcx>) -> Region<'tcx>
 
             (&ReVar(v_id), _) | (_, &ReVar(v_id)) => {
                 span_bug!(
-                    self.var_origins[v_id].span(),
+                    self.var_infos[v_id].origin.span(),
                     "lub_concrete_regions invoked with non-concrete \
                      regions: {:?}, {:?}",
                     a,
@@ -576,7 +576,7 @@ fn region_order_key(x: &RegionAndOrigin) -> u8 {
                 if !self.region_rels
                     .is_subregion_of(lower_bound.region, upper_bound.region)
                 {
-                    let origin = self.var_origins[node_idx].clone();
+                    let origin = self.var_infos[node_idx].origin.clone();
                     debug!(
                         "region inference error at {:?} for {:?}: SubSupConflict sub: {:?} \
                          sup: {:?}",
@@ -598,7 +598,7 @@ fn region_order_key(x: &RegionAndOrigin) -> u8 {
         }
 
         span_bug!(
-            self.var_origins[node_idx].span(),
+            self.var_infos[node_idx].origin.span(),
             "collect_error_for_expanding_node() could not find \
              error for var {:?}, lower_bounds={:?}, \
              upper_bounds={:?}",
index 553926dba8f98e1cdcc7e50a0b763671026cc359..c62e7f8d9b6350a8a20350625a08c0b9f8039909 100644 (file)
@@ -42,7 +42,7 @@
 use self::combine::CombineFields;
 use self::higher_ranked::HrMatchResult;
 use self::region_constraints::{RegionConstraintCollector, RegionSnapshot};
-use self::region_constraints::{GenericKind, VerifyBound, RegionConstraintData, VarOrigins};
+use self::region_constraints::{GenericKind, VerifyBound, RegionConstraintData, VarInfos};
 use self::lexical_region_resolve::LexicalRegionResolutions;
 use self::outlives::env::OutlivesEnvironment;
 use self::type_variable::TypeVariableOrigin;
@@ -183,6 +183,17 @@ pub struct InferCtxt<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
     // obligations within. This is expected to be done 'late enough'
     // that all type inference variables have been bound and so forth.
     pub region_obligations: RefCell<Vec<(ast::NodeId, RegionObligation<'tcx>)>>,
+
+    /// What is the innermost universe we have created? Starts out as
+    /// `UniverseIndex::root()` but grows from there as we enter
+    /// universal quantifiers.
+    ///
+    /// NB: At present, we exclude the universal quantifiers on the
+    /// item we are type-checking, and just consider those names as
+    /// part of the root universe. So this would only get incremented
+    /// when we enter into a higher-ranked (`for<..>`) type or trait
+    /// bound.
+    universe: Cell<ty::UniverseIndex>,
 }
 
 /// A map returned by `skolemize_late_bound_regions()` indicating the skolemized
@@ -455,6 +466,7 @@ pub fn enter<F, R>(&'tcx mut self, f: F) -> R
             err_count_on_creation: tcx.sess.err_count(),
             in_snapshot: Cell::new(false),
             region_obligations: RefCell::new(vec![]),
+            universe: Cell::new(ty::UniverseIndex::ROOT),
         }))
     }
 }
@@ -489,6 +501,7 @@ pub struct CombinedSnapshot<'a, 'tcx:'a> {
     float_snapshot: ut::Snapshot<ut::InPlace<ty::FloatVid>>,
     region_constraints_snapshot: RegionSnapshot,
     region_obligations_snapshot: usize,
+    universe: ty::UniverseIndex,
     was_in_snapshot: bool,
     _in_progress_tables: Option<Ref<'a, ty::TypeckTables<'tcx>>>,
 }
@@ -618,6 +631,7 @@ fn start_snapshot(&self) -> CombinedSnapshot<'a, 'tcx> {
             float_snapshot: self.float_unification_table.borrow_mut().snapshot(),
             region_constraints_snapshot: self.borrow_region_constraints().start_snapshot(),
             region_obligations_snapshot: self.region_obligations.borrow().len(),
+            universe: self.universe(),
             was_in_snapshot: in_snapshot,
             // Borrow tables "in progress" (i.e. during typeck)
             // to ban writes from within a snapshot to them.
@@ -635,10 +649,12 @@ fn rollback_to(&self, cause: &str, snapshot: CombinedSnapshot<'a, 'tcx>) {
                                float_snapshot,
                                region_constraints_snapshot,
                                region_obligations_snapshot,
+                               universe,
                                was_in_snapshot,
                                _in_progress_tables } = snapshot;
 
         self.in_snapshot.set(was_in_snapshot);
+        self.universe.set(universe);
 
         self.projection_cache
             .borrow_mut()
@@ -667,6 +683,7 @@ fn commit_from(&self, snapshot: CombinedSnapshot<'a, 'tcx>) {
                                float_snapshot,
                                region_constraints_snapshot,
                                region_obligations_snapshot: _,
+                               universe: _,
                                was_in_snapshot,
                                _in_progress_tables } = snapshot;
 
@@ -811,7 +828,7 @@ pub fn subtype_predicate(&self,
 
         Some(self.commit_if_ok(|snapshot| {
             let (ty::SubtypePredicate { a_is_expected, a, b}, skol_map) =
-                self.skolemize_late_bound_regions(predicate, snapshot);
+                self.skolemize_late_bound_regions(predicate);
 
             let cause_span = cause.span;
             let ok = self.at(cause, param_env).sub_exp(a_is_expected, a, b)?;
@@ -828,7 +845,7 @@ pub fn region_outlives_predicate(&self,
     {
         self.commit_if_ok(|snapshot| {
             let (ty::OutlivesPredicate(r_a, r_b), skol_map) =
-                self.skolemize_late_bound_regions(predicate, snapshot);
+                self.skolemize_late_bound_regions(predicate);
             let origin =
                 SubregionOrigin::from_obligation_cause(cause,
                                                        || RelateRegionParamBound(cause.span));
@@ -841,7 +858,7 @@ pub fn region_outlives_predicate(&self,
     pub fn next_ty_var_id(&self, diverging: bool, origin: TypeVariableOrigin) -> TyVid {
         self.type_variables
             .borrow_mut()
-            .new_var(diverging, origin)
+            .new_var(self.universe(), diverging, origin)
     }
 
     pub fn next_ty_var(&self, origin: TypeVariableOrigin) -> Ty<'tcx> {
@@ -872,12 +889,14 @@ pub fn next_float_var_id(&self) -> FloatVid {
     ///   during diagnostics / error-reporting.
     pub fn next_region_var(&self, origin: RegionVariableOrigin)
                            -> ty::Region<'tcx> {
-        self.tcx.mk_region(ty::ReVar(self.borrow_region_constraints().new_region_var(origin)))
+        let region_var = self.borrow_region_constraints()
+            .new_region_var(self.universe(), origin);
+        self.tcx.mk_region(ty::ReVar(region_var))
     }
 
     /// Number of region variables created so far.
     pub fn num_region_vars(&self) -> usize {
-        self.borrow_region_constraints().var_origins().len()
+        self.borrow_region_constraints().num_region_vars()
     }
 
     /// Just a convenient wrapper of `next_region_var` for using during NLL.
@@ -909,7 +928,8 @@ pub fn type_var_for_def(&self,
                             -> Ty<'tcx> {
         let ty_var_id = self.type_variables
                             .borrow_mut()
-                            .new_var(false,
+                            .new_var(self.universe(),
+                                     false,
                                      TypeVariableOrigin::TypeParameterDefinition(span, def.name));
 
         self.tcx.mk_var(ty_var_id)
@@ -1004,12 +1024,12 @@ fn resolve_regions_and_report_errors_inner(
                                                 region_context,
                                                 region_map,
                                                 outlives_env.free_region_map());
-        let (var_origins, data) = self.region_constraints.borrow_mut()
+        let (var_infos, data) = self.region_constraints.borrow_mut()
                                                          .take()
                                                          .expect("regions already resolved")
-                                                         .into_origins_and_data();
+                                                         .into_infos_and_data();
         let (lexical_region_resolutions, errors) =
-            lexical_region_resolve::resolve(region_rels, var_origins, data);
+            lexical_region_resolve::resolve(region_rels, var_infos, data);
 
         let old_value = self.lexical_region_resolutions.replace(Some(lexical_region_resolutions));
         assert!(old_value.is_none());
@@ -1057,13 +1077,13 @@ pub fn with_region_constraints<R>(
     /// hence that `resolve_regions_and_report_errors` can never be
     /// called. This is used only during NLL processing to "hand off" ownership
     /// of the set of region vairables into the NLL region context.
-    pub fn take_region_var_origins(&self) -> VarOrigins {
-        let (var_origins, data) = self.region_constraints.borrow_mut()
+    pub fn take_region_var_origins(&self) -> VarInfos {
+        let (var_infos, data) = self.region_constraints.borrow_mut()
                                                          .take()
                                                          .expect("regions already resolved")
-                                                         .into_origins_and_data();
+                                                         .into_infos_and_data();
         assert!(data.is_empty());
-        var_origins
+        var_infos
     }
 
     pub fn ty_to_string(&self, t: Ty<'tcx>) -> String {
@@ -1356,6 +1376,10 @@ pub fn clear_caches(&self) {
         self.evaluation_cache.clear();
         self.projection_cache.borrow_mut().clear();
     }
+
+    fn universe(&self) -> ty::UniverseIndex {
+        self.universe.get()
+    }
 }
 
 impl<'a, 'gcx, 'tcx> TypeTrace<'tcx> {
index 4113a2dd4178bfd8e92a162d6e8d2c6ab673c642..c388fa21371923ae3e23e3fd25c2bbf86c4e31e6 100644 (file)
 use ty::{self, Ty, TyCtxt};
 use ty::{Region, RegionVid};
 use ty::ReStatic;
-use ty::{BrFresh, ReLateBound, ReSkolemized, ReVar};
+use ty::{BrFresh, ReLateBound, ReVar};
 
 use std::collections::BTreeMap;
-use std::fmt;
-use std::mem;
-use std::u32;
+use std::{cmp, fmt, mem, u32};
 
 mod taint;
 
 pub struct RegionConstraintCollector<'tcx> {
     /// For each `RegionVid`, the corresponding `RegionVariableOrigin`.
-    var_origins: IndexVec<RegionVid, RegionVariableOrigin>,
+    var_infos: IndexVec<RegionVid, RegionVariableInfo>,
 
     data: RegionConstraintData<'tcx>,
 
@@ -47,9 +45,6 @@ pub struct RegionConstraintCollector<'tcx> {
     /// exist). This prevents us from making many such regions.
     glbs: CombineMap<'tcx>,
 
-    /// Number of skolemized variables currently active.
-    skolemization_count: u32,
-
     /// Global counter used during the GLB algorithm to create unique
     /// names for fresh bound regions
     bound_count: u32,
@@ -76,7 +71,7 @@ pub struct RegionConstraintCollector<'tcx> {
     unification_table: ut::UnificationTable<ut::InPlace<ty::RegionVid>>,
 }
 
-pub type VarOrigins = IndexVec<RegionVid, RegionVariableOrigin>;
+pub type VarInfos = IndexVec<RegionVid, RegionVariableInfo>;
 
 /// The full set of region constraints gathered up by the collector.
 /// Describes constraints between the region variables and other
@@ -230,10 +225,15 @@ enum CombineMapType {
 
 type CombineMap<'tcx> = FxHashMap<TwoRegions<'tcx>, RegionVid>;
 
+#[derive(Debug, Clone, Copy)]
+pub struct RegionVariableInfo {
+    pub origin: RegionVariableOrigin,
+    pub universe: ty::UniverseIndex,
+}
+
 pub struct RegionSnapshot {
     length: usize,
     region_snapshot: ut::Snapshot<ut::InPlace<ty::RegionVid>>,
-    skolemization_count: u32,
 }
 
 /// When working with skolemized regions, we often wish to find all of
@@ -273,19 +273,18 @@ pub fn both() -> Self {
 impl<'tcx> RegionConstraintCollector<'tcx> {
     pub fn new() -> RegionConstraintCollector<'tcx> {
         RegionConstraintCollector {
-            var_origins: VarOrigins::default(),
+            var_infos: VarInfos::default(),
             data: RegionConstraintData::default(),
             lubs: FxHashMap(),
             glbs: FxHashMap(),
-            skolemization_count: 0,
             bound_count: 0,
             undo_log: Vec::new(),
             unification_table: ut::UnificationTable::new(),
         }
     }
 
-    pub fn var_origins(&self) -> &VarOrigins {
-        &self.var_origins
+    pub fn num_region_vars(&self) -> usize {
+        self.var_infos.len()
     }
 
     pub fn region_constraint_data(&self) -> &RegionConstraintData<'tcx> {
@@ -295,9 +294,9 @@ pub fn region_constraint_data(&self) -> &RegionConstraintData<'tcx> {
     /// Once all the constraints have been gathered, extract out the final data.
     ///
     /// Not legal during a snapshot.
-    pub fn into_origins_and_data(self) -> (VarOrigins, RegionConstraintData<'tcx>) {
+    pub fn into_infos_and_data(self) -> (VarInfos, RegionConstraintData<'tcx>) {
         assert!(!self.in_snapshot());
-        (self.var_origins, self.data)
+        (self.var_infos, self.data)
     }
 
     /// Takes (and clears) the current set of constraints. Note that
@@ -319,18 +318,15 @@ pub fn take_and_reset_data(&mut self) -> RegionConstraintData<'tcx> {
         // should think carefully about whether it needs to be cleared
         // or updated in some way.
         let RegionConstraintCollector {
-            var_origins,
+            var_infos,
             data,
             lubs,
             glbs,
-            skolemization_count,
             bound_count: _,
             undo_log: _,
             unification_table,
         } = self;
 
-        assert_eq!(*skolemization_count, 0);
-
         // Clear the tables of (lubs, glbs), so that we will create
         // fresh regions if we do a LUB operation. As it happens,
         // LUB/GLB are not performed by the MIR type-checker, which is
@@ -343,7 +339,7 @@ pub fn take_and_reset_data(&mut self) -> RegionConstraintData<'tcx> {
         // also insert `a <= b` and a `b <= a` edges, so the
         // `RegionConstraintData` contains the relationship here.
         *unification_table = ut::UnificationTable::new();
-        for vid in var_origins.indices() {
+        for vid in var_infos.indices() {
             unification_table.new_key(unify_key::RegionVidKey { min_vid: vid });
         }
 
@@ -365,7 +361,6 @@ pub fn start_snapshot(&mut self) -> RegionSnapshot {
         RegionSnapshot {
             length,
             region_snapshot: self.unification_table.snapshot(),
-            skolemization_count: self.skolemization_count,
         }
     }
 
@@ -373,12 +368,6 @@ pub fn commit(&mut self, snapshot: RegionSnapshot) {
         debug!("RegionConstraintCollector: commit({})", snapshot.length);
         assert!(self.undo_log.len() > snapshot.length);
         assert!(self.undo_log[snapshot.length] == OpenSnapshot);
-        assert!(
-            self.skolemization_count == snapshot.skolemization_count,
-            "failed to pop skolemized regions: {} now vs {} at start",
-            self.skolemization_count,
-            snapshot.skolemization_count
-        );
 
         if snapshot.length == 0 {
             self.undo_log.truncate(0);
@@ -398,7 +387,6 @@ pub fn rollback_to(&mut self, snapshot: RegionSnapshot) {
         }
         let c = self.undo_log.pop().unwrap();
         assert!(c == OpenSnapshot);
-        self.skolemization_count = snapshot.skolemization_count;
         self.unification_table.rollback_to(snapshot.region_snapshot);
     }
 
@@ -411,8 +399,8 @@ fn rollback_undo_entry(&mut self, undo_entry: UndoLogEntry<'tcx>) {
                 // nothing to do here
             }
             AddVar(vid) => {
-                self.var_origins.pop().unwrap();
-                assert_eq!(self.var_origins.len(), vid.index() as usize);
+                self.var_infos.pop().unwrap();
+                assert_eq!(self.var_infos.len(), vid.index() as usize);
             }
             AddConstraint(ref constraint) => {
                 self.data.constraints.remove(constraint);
@@ -433,8 +421,13 @@ fn rollback_undo_entry(&mut self, undo_entry: UndoLogEntry<'tcx>) {
         }
     }
 
-    pub fn new_region_var(&mut self, origin: RegionVariableOrigin) -> RegionVid {
-        let vid = self.var_origins.push(origin.clone());
+    pub fn new_region_var(&mut self,
+                          universe: ty::UniverseIndex,
+                          origin: RegionVariableOrigin) -> RegionVid {
+        let vid = self.var_infos.push(RegionVariableInfo {
+            origin,
+            universe,
+        });
 
         let u_vid = self.unification_table
             .new_key(unify_key::RegionVidKey { min_vid: vid });
@@ -450,44 +443,14 @@ pub fn new_region_var(&mut self, origin: RegionVariableOrigin) -> RegionVid {
         return vid;
     }
 
-    /// Returns the origin for the given variable.
-    pub fn var_origin(&self, vid: RegionVid) -> RegionVariableOrigin {
-        self.var_origins[vid].clone()
+    /// Returns the universe for the given variable.
+    pub fn var_universe(&self, vid: RegionVid) -> ty::UniverseIndex {
+        self.var_infos[vid].universe
     }
 
-    /// Creates a new skolemized region. Skolemized regions are fresh
-    /// regions used when performing higher-ranked computations. They
-    /// must be used in a very particular way and are never supposed
-    /// to "escape" out into error messages or the code at large.
-    ///
-    /// The idea is to always create a snapshot. Skolemized regions
-    /// can be created in the context of this snapshot, but before the
-    /// snapshot is committed or rolled back, they must be popped
-    /// (using `pop_skolemized_regions`), so that their numbers can be
-    /// recycled. Normally you don't have to think about this: you use
-    /// the APIs in `higher_ranked/mod.rs`, such as
-    /// `skolemize_late_bound_regions` and `plug_leaks`, which will
-    /// guide you on this path (ensure that the `SkolemizationMap` is
-    /// consumed and you are good). For more info on how skolemization
-    /// for HRTBs works, see the [rustc guide].
-    ///
-    /// [rustc guide]: https://rust-lang-nursery.github.io/rustc-guide/trait-hrtb.html
-    ///
-    /// The `snapshot` argument to this function is not really used;
-    /// it's just there to make it explicit which snapshot bounds the
-    /// skolemized region that results. It should always be the top-most snapshot.
-    pub fn push_skolemized(
-        &mut self,
-        tcx: TyCtxt<'_, '_, 'tcx>,
-        br: ty::BoundRegion,
-        snapshot: &RegionSnapshot,
-    ) -> Region<'tcx> {
-        assert!(self.in_snapshot());
-        assert!(self.undo_log[snapshot.length] == OpenSnapshot);
-
-        let sc = self.skolemization_count;
-        self.skolemization_count = sc + 1;
-        tcx.mk_region(ReSkolemized(ty::SkolemizedRegionVid { index: sc }, br))
+    /// Returns the origin for the given variable.
+    pub fn var_origin(&self, vid: RegionVid) -> RegionVariableOrigin {
+        self.var_infos[vid].origin
     }
 
     /// Removes all the edges to/from the skolemized regions that are
@@ -496,7 +459,7 @@ pub fn push_skolemized(
     /// created in that time.
     pub fn pop_skolemized(
         &mut self,
-        _tcx: TyCtxt<'_, '_, 'tcx>,
+        skolemization_count: ty::UniverseIndex,
         skols: &FxHashSet<ty::Region<'tcx>>,
         snapshot: &RegionSnapshot,
     ) {
@@ -505,36 +468,28 @@ pub fn pop_skolemized(
         assert!(self.in_snapshot());
         assert!(self.undo_log[snapshot.length] == OpenSnapshot);
         assert!(
-            self.skolemization_count as usize >= skols.len(),
+            skolemization_count.as_usize() >= skols.len(),
             "popping more skolemized variables than actually exist, \
-             sc now = {}, skols.len = {}",
-            self.skolemization_count,
+             sc now = {:?}, skols.len = {:?}",
+            skolemization_count,
             skols.len()
         );
 
-        let last_to_pop = self.skolemization_count;
-        let first_to_pop = last_to_pop - (skols.len() as u32);
+        let last_to_pop = skolemization_count.subuniverse();
+        let first_to_pop = ty::UniverseIndex::from(last_to_pop.as_u32() - skols.len() as u32);
 
-        assert!(
-            first_to_pop >= snapshot.skolemization_count,
-            "popping more regions than snapshot contains, \
-             sc now = {}, sc then = {}, skols.len = {}",
-            self.skolemization_count,
-            snapshot.skolemization_count,
-            skols.len()
-        );
         debug_assert! {
             skols.iter()
                  .all(|&k| match *k {
-                     ty::ReSkolemized(index, _) =>
-                         index.index >= first_to_pop &&
-                         index.index < last_to_pop,
+                     ty::ReSkolemized(universe, _) =>
+                         universe >= first_to_pop &&
+                         universe < last_to_pop,
                      _ =>
                          false
                  }),
-            "invalid skolemization keys or keys out of range ({}..{}): {:?}",
-            snapshot.skolemization_count,
-            self.skolemization_count,
+            "invalid skolemization keys or keys out of range ({:?}..{:?}): {:?}",
+            first_to_pop,
+            last_to_pop,
             skols
         }
 
@@ -551,7 +506,6 @@ pub fn pop_skolemized(
             self.rollback_undo_entry(undo_entry);
         }
 
-        self.skolemization_count = snapshot.skolemization_count;
         return;
 
         fn kill_constraint<'tcx>(
@@ -805,7 +759,10 @@ fn combine_vars(
         if let Some(&c) = self.combine_map(t).get(&vars) {
             return tcx.mk_region(ReVar(c));
         }
-        let c = self.new_region_var(MiscVariable(origin.span()));
+        let a_universe = self.universe(a);
+        let b_universe = self.universe(b);
+        let c_universe = cmp::max(a_universe, b_universe);
+        let c = self.new_region_var(c_universe, MiscVariable(origin.span()));
         self.combine_map(t).insert(vars, c);
         if self.in_snapshot() {
             self.undo_log.push(AddCombination(t, vars));
@@ -821,6 +778,24 @@ fn combine_vars(
         new_r
     }
 
+    fn universe(&self, region: Region<'tcx>) -> ty::UniverseIndex {
+        match *region {
+            ty::ReScope(..) |
+            ty::ReStatic |
+            ty::ReEmpty |
+            ty::ReErased |
+            ty::ReFree(..) |
+            ty::ReEarlyBound(..) => ty::UniverseIndex::ROOT,
+            ty::ReSkolemized(universe, _) => universe,
+            ty::ReClosureBound(vid) |
+            ty::ReVar(vid) => self.var_universe(vid),
+            ty::ReLateBound(..) =>
+                bug!("universe(): encountered bound region {:?}", region),
+            ty::ReCanonical(..) =>
+                bug!("region_universe(): encountered canonical region {:?}", region),
+        }
+    }
+
     pub fn vars_created_since_snapshot(&self, mark: &RegionSnapshot) -> Vec<RegionVid> {
         self.undo_log[mark.length..]
             .iter()
@@ -865,12 +840,7 @@ pub fn tainted(
 
 impl fmt::Debug for RegionSnapshot {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        write!(
-            f,
-            "RegionSnapshot(length={},skolemization={})",
-            self.length,
-            self.skolemization_count
-        )
+        write!(f, "RegionSnapshot(length={})", self.length)
     }
 }
 
index 5e96f4eb576f523e5d20e79454de36ec4f1f95bd..d40e1b3760f0361a2bcf62877c1f528d46159269 100644 (file)
@@ -78,10 +78,12 @@ struct TypeVariableData {
 #[derive(Copy, Clone, Debug)]
 pub enum TypeVariableValue<'tcx> {
     Known { value: Ty<'tcx> },
-    Unknown,
+    Unknown { universe: ty::UniverseIndex },
 }
 
 impl<'tcx> TypeVariableValue<'tcx> {
+    /// If this value is known, returns the type it is known to be.
+    /// Otherwise, `None`.
     pub fn known(&self) -> Option<Ty<'tcx>> {
         match *self {
             TypeVariableValue::Unknown { .. } => None,
@@ -181,10 +183,11 @@ pub fn instantiate(&mut self, vid: ty::TyVid, ty: Ty<'tcx>) {
     ///   The code in this module doesn't care, but it can be useful
     ///   for improving error messages.
     pub fn new_var(&mut self,
+                   universe: ty::UniverseIndex,
                    diverging: bool,
                    origin: TypeVariableOrigin)
                    -> ty::TyVid {
-        let eq_key = self.eq_relations.new_key(TypeVariableValue::Unknown);
+        let eq_key = self.eq_relations.new_key(TypeVariableValue::Unknown { universe });
 
         let sub_key = self.sub_relations.new_key(());
         assert_eq!(eq_key.vid, sub_key);
@@ -437,7 +440,16 @@ fn unify_values(value1: &Self, value2: &Self) -> Result<Self, ut::NoError> {
             (&TypeVariableValue::Unknown { .. }, &TypeVariableValue::Known { .. }) => Ok(*value2),
 
             // If both sides are *unknown*, it hardly matters, does it?
-            (&TypeVariableValue::Unknown, &TypeVariableValue::Unknown) => Ok(*value1),
+            (&TypeVariableValue::Unknown { universe: universe1 },
+             &TypeVariableValue::Unknown { universe: universe2 }) =>  {
+                // If we unify two unbound variables, ?T and ?U, then whatever
+                // value they wind up taking (which must be the same value) must
+                // be nameable by both universes. Therefore, the resulting
+                // universe is the minimum of the two universes, because that is
+                // the one which contains the fewest names in scope.
+                let universe = cmp::min(universe1, universe2);
+                Ok(TypeVariableValue::Unknown { universe })
+            }
         }
     }
 }
index 24892dfcc8f7d63d034b3dd15635990708235136..879d38c4894435613efa148027289b1f64281672 100644 (file)
@@ -69,7 +69,7 @@
 #![feature(trusted_len)]
 #![feature(catch_expr)]
 #![feature(test)]
-#![feature(inclusive_range_fields)]
+#![feature(inclusive_range_methods)]
 
 #![recursion_limit="512"]
 
@@ -85,7 +85,6 @@
 extern crate rustc_target;
 #[macro_use] extern crate rustc_data_structures;
 extern crate serialize;
-extern crate rustc_const_math;
 extern crate rustc_errors as errors;
 #[macro_use] extern crate log;
 #[macro_use] extern crate syntax;
index e8b536d52676382e356f723d64564451376c2e27..d158f52c643ceca2c2896acabe6c8cf02bd21add 100644 (file)
@@ -198,7 +198,7 @@ pub fn push(&mut self, attrs: &[ast::Attribute]) -> BuilderPush {
                       "malformed lint attribute");
         };
         for attr in attrs {
-            let level = match attr.name().and_then(|name| Level::from_str(&name.as_str())) {
+            let level = match Level::from_str(&attr.name().as_str()) {
                 None => continue,
                 Some(lvl) => lvl,
             };
@@ -221,7 +221,7 @@ pub fn push(&mut self, attrs: &[ast::Attribute]) -> BuilderPush {
                         continue
                     }
                 };
-                let name = word.ident.name;
+                let name = word.name();
                 match store.check_lint_name(&name.as_str()) {
                     CheckLintNameResult::Ok(ids) => {
                         let src = LintSource::Node(name, li.span);
@@ -260,7 +260,7 @@ pub fn push(&mut self, attrs: &[ast::Attribute]) -> BuilderPush {
                                                 Some(li.span.into()),
                                                 &msg);
                         if name.as_str().chars().any(|c| c.is_uppercase()) {
-                            let name_lower = name.as_str().to_lowercase();
+                            let name_lower = name.as_str().to_lowercase().to_string();
                             if let CheckLintNameResult::NoLint =
                                     store.check_lint_name(&name_lower) {
                                 db.emit();
index 0d4fd99995f7ed2d57d4fefe61d16cb20ab4b28f..d6c6f9dc0f61a0b1e5c72fee9af09b4b2634d6e3 100644 (file)
@@ -507,7 +507,7 @@ pub fn struct_lint_level<'a>(sess: &'a Session,
 
         let explanation = if lint_id == LintId::of(::lint::builtin::UNSTABLE_NAME_COLLISION) {
             "once this method is added to the standard library, \
-             there will be ambiguity here, which will cause a hard error!"
+             the ambiguity may cause an error or change in behavior!"
                 .to_owned()
         } else if let Some(edition) = future_incompatible.edition {
             format!("{} in the {} edition!", STANDARD_MESSAGE, edition)
index 19a7576b7ceac4ed1abd99d739a9c89751ebb46b..0ecab50dda22989faeb57d53f0bc642ff068e37d 100644 (file)
@@ -11,7 +11,6 @@
 use hir::def_id::DefId;
 use ty::{self, TyCtxt, layout};
 use ty::subst::Substs;
-use rustc_const_math::*;
 use mir::interpret::{Value, PrimVal};
 use errors::DiagnosticBuilder;
 
@@ -62,7 +61,6 @@ pub enum ErrKind<'tcx> {
     UnimplementedConstVal(&'static str),
     IndexOutOfBounds { len: u64, index: u64 },
 
-    Math(ConstMathErr),
     LayoutError(layout::LayoutError<'tcx>),
 
     TypeckError,
@@ -76,15 +74,6 @@ pub struct FrameInfo {
     pub location: String,
 }
 
-impl<'tcx> From<ConstMathErr> for ErrKind<'tcx> {
-    fn from(err: ConstMathErr) -> ErrKind<'tcx> {
-        match err {
-            ConstMathErr::UnsignedNegation => ErrKind::TypeckError,
-            _ => ErrKind::Math(err)
-        }
-    }
-}
-
 #[derive(Clone, Debug)]
 pub enum ConstEvalErrDescription<'a, 'tcx: 'a> {
     Simple(Cow<'a, str>),
@@ -122,7 +111,6 @@ macro_rules! simple {
                         len, index)
             }
 
-            Math(ref err) => Simple(err.description().into_cow()),
             LayoutError(ref err) => Simple(err.to_string().into_cow()),
 
             TypeckError => simple!("type-checking failed"),
index 5f4efbeeaa8762da80ffc0cf8119189a29e418d7..bfc9ff6660de9890254f9d37eb06660d413da73d 100644 (file)
@@ -690,21 +690,22 @@ pub fn nearest_common_ancestor(&self,
         // the start. So this algorithm is faster.
         let mut ma = Some(scope_a);
         let mut mb = Some(scope_b);
-        let mut seen: SmallVec<[Scope; 32]> = SmallVec::new();
+        let mut seen_a: SmallVec<[Scope; 32]> = SmallVec::new();
+        let mut seen_b: SmallVec<[Scope; 32]> = SmallVec::new();
         loop {
             if let Some(a) = ma {
-                if seen.iter().position(|s| *s == a).is_some() {
+                if seen_b.iter().position(|s| *s == a).is_some() {
                     return a;
                 }
-                seen.push(a);
+                seen_a.push(a);
                 ma = self.parent_map.get(&a).map(|s| *s);
             }
 
             if let Some(b) = mb {
-                if seen.iter().position(|s| *s == b).is_some() {
+                if seen_a.iter().position(|s| *s == b).is_some() {
                     return b;
                 }
-                seen.push(b);
+                seen_b.push(b);
                 mb = self.parent_map.get(&b).map(|s| *s);
             }
 
index 328b2db2b58282ade9b5d6267842fb50af59aa29..279908d2b675fae372bbb13780bf293d39fc7220 100644 (file)
@@ -205,7 +205,7 @@ fn annotate<F>(&mut self, id: NodeId, attrs: &[Attribute],
         } else {
             // Emit errors for non-staged-api crates.
             for attr in attrs {
-                let tag = unwrap_or!(attr.name(), continue);
+                let tag = attr.name();
                 if tag == "unstable" || tag == "stable" || tag == "rustc_deprecated" {
                     attr::mark_used(attr);
                     self.tcx.sess.span_err(attr.span(), "stability attributes may not be used \
index 1ed5a22257c537e53446b2013d1c2e842984c55c..41ba526b73fefdafd3d707eac79698e10da0ddd9 100644 (file)
@@ -68,7 +68,7 @@ fn calculate_predecessors(mir: &Mir) -> IndexVec<BasicBlock, Vec<BasicBlock>> {
     let mut result = IndexVec::from_elem(vec![], mir.basic_blocks());
     for (bb, data) in mir.basic_blocks().iter_enumerated() {
         if let Some(ref term) = data.terminator {
-            for &tgt in term.successors().iter() {
+            for &tgt in term.successors() {
                 result[tgt].push(bb);
             }
         }
index b919f4d15a840a479678aafc968ffafc4cb05bfe..1e1d50c3fc036d36d26369c18ed4d5ffdfc19db7 100644 (file)
@@ -1,4 +1,3 @@
-use std::error::Error;
 use std::{fmt, env};
 
 use mir;
@@ -8,18 +7,16 @@
     MemoryPointer, Lock, AccessKind
 };
 
-use rustc_const_math::ConstMathErr;
-use syntax::codemap::Span;
 use backtrace::Backtrace;
 
 #[derive(Debug, Clone)]
 pub struct EvalError<'tcx> {
-    pub kind: EvalErrorKind<'tcx>,
+    pub kind: EvalErrorKind<'tcx, u64>,
     pub backtrace: Option<Backtrace>,
 }
 
-impl<'tcx> From<EvalErrorKind<'tcx>> for EvalError<'tcx> {
-    fn from(kind: EvalErrorKind<'tcx>) -> Self {
+impl<'tcx> From<EvalErrorKind<'tcx, u64>> for EvalError<'tcx> {
+    fn from(kind: EvalErrorKind<'tcx, u64>) -> Self {
         let backtrace = match env::var("MIRI_BACKTRACE") {
             Ok(ref val) if !val.is_empty() => Some(Backtrace::new_unresolved()),
             _ => None
@@ -31,8 +28,10 @@ fn from(kind: EvalErrorKind<'tcx>) -> Self {
     }
 }
 
-#[derive(Debug, Clone)]
-pub enum EvalErrorKind<'tcx> {
+pub type AssertMessage<'tcx> = EvalErrorKind<'tcx, mir::Operand<'tcx>>;
+
+#[derive(Clone, RustcEncodable, RustcDecodable)]
+pub enum EvalErrorKind<'tcx, O> {
     /// This variant is used by machines to signal their own errors that do not
     /// match an existing variant
     MachineError(String),
@@ -60,10 +59,12 @@ pub enum EvalErrorKind<'tcx> {
     Unimplemented(String),
     DerefFunctionPointer,
     ExecuteMemory,
-    ArrayIndexOutOfBounds(Span, u64, u64),
-    Math(Span, ConstMathErr),
+    BoundsCheck { len: O, index: O },
+    Overflow(mir::BinOp),
+    OverflowNeg,
+    DivisionByZero,
+    RemainderByZero,
     Intrinsic(String),
-    OverflowingMath,
     InvalidChar(u128),
     StackFrameLimitReached,
     OutOfTls,
@@ -121,14 +122,16 @@ pub enum EvalErrorKind<'tcx> {
     /// Cannot compute this constant because it depends on another one
     /// which already produced an error
     ReferencedConstant,
+    GeneratorResumedAfterReturn,
+    GeneratorResumedAfterPanic,
 }
 
 pub type EvalResult<'tcx, T = ()> = Result<T, EvalError<'tcx>>;
 
-impl<'tcx> Error for EvalError<'tcx> {
-    fn description(&self) -> &str {
+impl<'tcx, O> EvalErrorKind<'tcx, O> {
+    pub fn description(&self) -> &str {
         use self::EvalErrorKind::*;
-        match self.kind {
+        match *self {
             MachineError(ref inner) => inner,
             FunctionPointerTyMismatch(..) =>
                 "tried to call a function through a function pointer of a different type",
@@ -175,14 +178,10 @@ fn description(&self) -> &str {
                 "tried to dereference a function pointer",
             ExecuteMemory =>
                 "tried to treat a memory pointer as a function pointer",
-            ArrayIndexOutOfBounds(..) =>
+            BoundsCheck{..} =>
                 "array index out of bounds",
-            Math(..) =>
-                "mathematical operation failed",
             Intrinsic(..) =>
                 "intrinsic failed",
-            OverflowingMath =>
-                "attempted to do overflowing math",
             NoMirFor(..) =>
                 "mir not found",
             InvalidChar(..) =>
@@ -232,7 +231,7 @@ fn description(&self) -> &str {
                 "the evaluated program panicked",
             ReadFromReturnPointer =>
                 "tried to read from the return pointer",
-            EvalErrorKind::PathNotFound(_) =>
+            PathNotFound(_) =>
                 "a path could not be resolved, maybe the crate is not loaded",
             UnimplementedTraitSelection =>
                 "there were unresolved type arguments during trait selection",
@@ -240,14 +239,33 @@ fn description(&self) -> &str {
                 "encountered constants with type errors, stopping evaluation",
             ReferencedConstant =>
                 "referenced constant has errors",
+            Overflow(mir::BinOp::Add) => "attempt to add with overflow",
+            Overflow(mir::BinOp::Sub) => "attempt to subtract with overflow",
+            Overflow(mir::BinOp::Mul) => "attempt to multiply with overflow",
+            Overflow(mir::BinOp::Div) => "attempt to divide with overflow",
+            Overflow(mir::BinOp::Rem) => "attempt to calculate the remainder with overflow",
+            OverflowNeg => "attempt to negate with overflow",
+            Overflow(mir::BinOp::Shr) => "attempt to shift right with overflow",
+            Overflow(mir::BinOp::Shl) => "attempt to shift left with overflow",
+            Overflow(op) => bug!("{:?} cannot overflow", op),
+            DivisionByZero => "attempt to divide by zero",
+            RemainderByZero => "attempt to calculate the remainder with a divisor of zero",
+            GeneratorResumedAfterReturn => "generator resumed after completion",
+            GeneratorResumedAfterPanic => "generator resumed after panicking",
         }
     }
 }
 
 impl<'tcx> fmt::Display for EvalError<'tcx> {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        write!(f, "{:?}", self.kind)
+    }
+}
+
+impl<'tcx, O: fmt::Debug> fmt::Debug for EvalErrorKind<'tcx, O> {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         use self::EvalErrorKind::*;
-        match self.kind {
+        match *self {
             PointerOutOfBounds { ptr, access, allocation_size } => {
                 write!(f, "{} at offset {}, outside bounds of allocation {} which has size {}",
                        if access { "memory access" } else { "pointer computed" },
@@ -275,14 +293,12 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
             NoMirFor(ref func) => write!(f, "no mir for `{}`", func),
             FunctionPointerTyMismatch(sig, got) =>
                 write!(f, "tried to call a function with sig {} through a function pointer of type {}", sig, got),
-            ArrayIndexOutOfBounds(span, len, index) =>
-                write!(f, "index out of bounds: the len is {} but the index is {} at {:?}", len, index, span),
+            BoundsCheck { ref len, ref index } =>
+                write!(f, "index out of bounds: the len is {:?} but the index is {:?}", len, index),
             ReallocatedWrongMemoryKind(ref old, ref new) =>
                 write!(f, "tried to reallocate memory from {} to {}", old, new),
             DeallocatedWrongMemoryKind(ref old, ref new) =>
                 write!(f, "tried to deallocate {} memory but gave {} as the kind", old, new),
-            Math(_, ref err) =>
-                write!(f, "{}", err.description()),
             Intrinsic(ref err) =>
                 write!(f, "{}", err),
             InvalidChar(c) =>
index c9eed0e4a288580a0452c5ca4b647ff9229e07a4..546c7a920d538fd6d12a653ea0c41ccf9f510088 100644 (file)
@@ -8,7 +8,7 @@ macro_rules! err {
 mod error;
 mod value;
 
-pub use self::error::{EvalError, EvalResult, EvalErrorKind};
+pub use self::error::{EvalError, EvalResult, EvalErrorKind, AssertMessage};
 
 pub use self::value::{PrimVal, PrimValKind, Value, Pointer};
 
@@ -23,7 +23,7 @@ macro_rules! err {
 use syntax::ast::Mutability;
 use rustc_serialize::{Encoder, Decoder, Decodable, Encodable};
 
-#[derive(Clone, Debug, PartialEq)]
+#[derive(Clone, Debug, PartialEq, RustcEncodable, RustcDecodable)]
 pub enum Lock {
     NoLock,
     WriteLock(DynamicLifetime),
@@ -31,13 +31,13 @@ pub enum Lock {
     ReadLock(Vec<DynamicLifetime>),
 }
 
-#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
+#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)]
 pub struct DynamicLifetime {
     pub frame: usize,
     pub region: Option<region::Scope>, // "None" indicates "until the function ends"
 }
 
-#[derive(Copy, Clone, Debug, PartialEq, Eq)]
+#[derive(Copy, Clone, Debug, PartialEq, Eq, RustcEncodable, RustcDecodable)]
 pub enum AccessKind {
     Read,
     Write,
@@ -88,12 +88,12 @@ fn overflowing_offset(self, val: u64, i: u64) -> (u64, bool) {
 
     fn signed_offset<'tcx>(self, val: u64, i: i64) -> EvalResult<'tcx, u64> {
         let (res, over) = self.overflowing_signed_offset(val, i as i128);
-        if over { err!(OverflowingMath) } else { Ok(res) }
+        if over { err!(Overflow(mir::BinOp::Add)) } else { Ok(res) }
     }
 
     fn offset<'tcx>(self, val: u64, i: u64) -> EvalResult<'tcx, u64> {
         let (res, over) = self.overflowing_offset(val, i);
-        if over { err!(OverflowingMath) } else { Ok(res) }
+        if over { err!(Overflow(mir::BinOp::Add)) } else { Ok(res) }
     }
 
     fn wrapping_signed_offset(self, val: u64, i: i64) -> u64 {
index c26b3014e53dd05dae5f815bb4e7d7e3c5e4e75b..55bfbed0b393c0082b57ef16d5a86b7fecde1b47 100644 (file)
@@ -15,7 +15,6 @@
 use graphviz::IntoCow;
 use middle::const_val::ConstVal;
 use middle::region;
-use rustc_const_math::ConstMathErr;
 use rustc_data_structures::sync::{Lrc};
 use rustc_data_structures::indexed_vec::{IndexVec, Idx};
 use rustc_data_structures::control_flow_graph::dominators::{Dominators, dominators};
@@ -26,7 +25,7 @@
 use hir::def::CtorKind;
 use hir::def_id::DefId;
 use mir::visit::MirVisitable;
-use mir::interpret::{Value, PrimVal};
+use mir::interpret::{Value, PrimVal, EvalErrorKind};
 use ty::subst::{Subst, Substs};
 use ty::{self, AdtDef, CanonicalTy, ClosureSubsts, Region, Ty, TyCtxt, GeneratorInterior};
 use ty::fold::{TypeFoldable, TypeFolder, TypeVisitor};
 use std::borrow::{Cow};
 use rustc_data_structures::sync::ReadGuard;
 use std::fmt::{self, Debug, Formatter, Write};
-use std::{iter, mem, u32};
+use std::{iter, mem, option, u32};
 use std::ops::{Index, IndexMut};
 use std::vec::IntoIter;
 use syntax::ast::{self, Name};
 use syntax::symbol::InternedString;
 use syntax_pos::{Span, DUMMY_SP};
+use rustc_apfloat::ieee::{Single, Double};
+use rustc_apfloat::Float;
+
+pub use mir::interpret::AssertMessage;
 
 mod cache;
 pub mod tcx;
@@ -859,12 +862,17 @@ pub enum TerminatorKind<'tcx> {
     },
 }
 
+pub type Successors<'a> =
+    iter::Chain<option::IntoIter<&'a BasicBlock>, slice::Iter<'a, BasicBlock>>;
+pub type SuccessorsMut<'a> =
+    iter::Chain<option::IntoIter<&'a mut BasicBlock>, slice::IterMut<'a, BasicBlock>>;
+
 impl<'tcx> Terminator<'tcx> {
-    pub fn successors(&self) -> Cow<[BasicBlock]> {
+    pub fn successors(&self) -> Successors {
         self.kind.successors()
     }
 
-    pub fn successors_mut(&mut self) -> Vec<&mut BasicBlock> {
+    pub fn successors_mut(&mut self) -> SuccessorsMut {
         self.kind.successors_mut()
     }
 
@@ -885,72 +893,71 @@ pub fn if_<'a, 'gcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>, cond: Operand<'tcx>,
         }
     }
 
-    pub fn successors(&self) -> Cow<[BasicBlock]> {
+    pub fn successors(&self) -> Successors {
         use self::TerminatorKind::*;
         match *self {
-            Goto { target: ref b } => slice::from_ref(b).into_cow(),
-            SwitchInt { targets: ref b, .. } => b[..].into_cow(),
-            Resume | Abort | GeneratorDrop => (&[]).into_cow(),
-            Return => (&[]).into_cow(),
-            Unreachable => (&[]).into_cow(),
-            Call { destination: Some((_, t)), cleanup: Some(c), .. } => vec![t, c].into_cow(),
-            Call { destination: Some((_, ref t)), cleanup: None, .. } =>
-                slice::from_ref(t).into_cow(),
-            Call { destination: None, cleanup: Some(ref c), .. } => slice::from_ref(c).into_cow(),
-            Call { destination: None, cleanup: None, .. } => (&[]).into_cow(),
-            Yield { resume: t, drop: Some(c), .. } => vec![t, c].into_cow(),
-            Yield { resume: ref t, drop: None, .. } => slice::from_ref(t).into_cow(),
-            DropAndReplace { target, unwind: Some(unwind), .. } |
-            Drop { target, unwind: Some(unwind), .. } => {
-                vec![target, unwind].into_cow()
+            Resume | Abort | GeneratorDrop | Return | Unreachable |
+            Call { destination: None, cleanup: None, .. } => {
+                None.into_iter().chain(&[])
+            }
+            Goto { target: ref t } |
+            Call { destination: None, cleanup: Some(ref t), .. } |
+            Call { destination: Some((_, ref t)), cleanup: None, .. } |
+            Yield { resume: ref t, drop: None, .. } |
+            DropAndReplace { target: ref t, unwind: None, .. } |
+            Drop { target: ref t, unwind: None, .. } |
+            Assert { target: ref t, cleanup: None, .. } |
+            FalseUnwind { real_target: ref t, unwind: None } => {
+                Some(t).into_iter().chain(&[])
             }
-            DropAndReplace { ref target, unwind: None, .. } |
-            Drop { ref target, unwind: None, .. } => {
-                slice::from_ref(target).into_cow()
+            Call { destination: Some((_, ref t)), cleanup: Some(ref u), .. } |
+            Yield { resume: ref t, drop: Some(ref u), .. } |
+            DropAndReplace { target: ref t, unwind: Some(ref u), .. } |
+            Drop { target: ref t, unwind: Some(ref u), .. } |
+            Assert { target: ref t, cleanup: Some(ref u), .. } |
+            FalseUnwind { real_target: ref t, unwind: Some(ref u) } => {
+                Some(t).into_iter().chain(slice::from_ref(u))
+            }
+            SwitchInt { ref targets, .. } => {
+                None.into_iter().chain(&targets[..])
             }
-            Assert { target, cleanup: Some(unwind), .. } => vec![target, unwind].into_cow(),
-            Assert { ref target, .. } => slice::from_ref(target).into_cow(),
             FalseEdges { ref real_target, ref imaginary_targets } => {
-                let mut s = vec![*real_target];
-                s.extend_from_slice(imaginary_targets);
-                s.into_cow()
+                Some(real_target).into_iter().chain(&imaginary_targets[..])
             }
-            FalseUnwind { real_target: t, unwind: Some(u) } => vec![t, u].into_cow(),
-            FalseUnwind { real_target: ref t, unwind: None } => slice::from_ref(t).into_cow(),
         }
     }
 
-    // FIXME: no mootable cow. I’m honestly not sure what a “cow” between `&mut [BasicBlock]` and
-    // `Vec<&mut BasicBlock>` would look like in the first place.
-    pub fn successors_mut(&mut self) -> Vec<&mut BasicBlock> {
+    pub fn successors_mut(&mut self) -> SuccessorsMut {
         use self::TerminatorKind::*;
         match *self {
-            Goto { target: ref mut b } => vec![b],
-            SwitchInt { targets: ref mut b, .. } => b.iter_mut().collect(),
-            Resume | Abort | GeneratorDrop => Vec::new(),
-            Return => Vec::new(),
-            Unreachable => Vec::new(),
-            Call { destination: Some((_, ref mut t)), cleanup: Some(ref mut c), .. } => vec![t, c],
-            Call { destination: Some((_, ref mut t)), cleanup: None, .. } => vec![t],
-            Call { destination: None, cleanup: Some(ref mut c), .. } => vec![c],
-            Call { destination: None, cleanup: None, .. } => vec![],
-            Yield { resume: ref mut t, drop: Some(ref mut c), .. } => vec![t, c],
-            Yield { resume: ref mut t, drop: None, .. } => vec![t],
-            DropAndReplace { ref mut target, unwind: Some(ref mut unwind), .. } |
-            Drop { ref mut target, unwind: Some(ref mut unwind), .. } => vec![target, unwind],
-            DropAndReplace { ref mut target, unwind: None, .. } |
-            Drop { ref mut target, unwind: None, .. } => {
-                vec![target]
+            Resume | Abort | GeneratorDrop | Return | Unreachable |
+            Call { destination: None, cleanup: None, .. } => {
+                None.into_iter().chain(&mut [])
+            }
+            Goto { target: ref mut t } |
+            Call { destination: None, cleanup: Some(ref mut t), .. } |
+            Call { destination: Some((_, ref mut t)), cleanup: None, .. } |
+            Yield { resume: ref mut t, drop: None, .. } |
+            DropAndReplace { target: ref mut t, unwind: None, .. } |
+            Drop { target: ref mut t, unwind: None, .. } |
+            Assert { target: ref mut t, cleanup: None, .. } |
+            FalseUnwind { real_target: ref mut t, unwind: None } => {
+                Some(t).into_iter().chain(&mut [])
+            }
+            Call { destination: Some((_, ref mut t)), cleanup: Some(ref mut u), .. } |
+            Yield { resume: ref mut t, drop: Some(ref mut u), .. } |
+            DropAndReplace { target: ref mut t, unwind: Some(ref mut u), .. } |
+            Drop { target: ref mut t, unwind: Some(ref mut u), .. } |
+            Assert { target: ref mut t, cleanup: Some(ref mut u), .. } |
+            FalseUnwind { real_target: ref mut t, unwind: Some(ref mut u) } => {
+                Some(t).into_iter().chain(slice::from_ref_mut(u))
+            }
+            SwitchInt { ref mut targets, .. } => {
+                None.into_iter().chain(&mut targets[..])
             }
-            Assert { ref mut target, cleanup: Some(ref mut unwind), .. } => vec![target, unwind],
-            Assert { ref mut target, .. } => vec![target],
             FalseEdges { ref mut real_target, ref mut imaginary_targets } => {
-                let mut s = vec![real_target];
-                s.extend(imaginary_targets.iter_mut());
-                s
+                Some(real_target).into_iter().chain(&mut imaginary_targets[..])
             }
-            FalseUnwind { real_target: ref mut t, unwind: Some(ref mut u) } => vec![t, u],
-            FalseUnwind { ref mut real_target, unwind: None } => vec![real_target],
         }
     }
 
@@ -1070,18 +1077,18 @@ pub fn visitable(&self, index: usize) -> &dyn MirVisitable<'tcx> {
 impl<'tcx> Debug for TerminatorKind<'tcx> {
     fn fmt(&self, fmt: &mut Formatter) -> fmt::Result {
         self.fmt_head(fmt)?;
-        let successors = self.successors();
+        let successor_count = self.successors().count();
         let labels = self.fmt_successor_labels();
-        assert_eq!(successors.len(), labels.len());
+        assert_eq!(successor_count, labels.len());
 
-        match successors.len() {
+        match successor_count {
             0 => Ok(()),
 
-            1 => write!(fmt, " -> {:?}", successors[0]),
+            1 => write!(fmt, " -> {:?}", self.successors().nth(0).unwrap()),
 
             _ => {
                 write!(fmt, " -> [")?;
-                for (i, target) in successors.iter().enumerate() {
+                for (i, target) in self.successors().enumerate() {
                     if i > 0 {
                         write!(fmt, ", ")?;
                     }
@@ -1130,26 +1137,7 @@ pub fn fmt_head<W: Write>(&self, fmt: &mut W) -> fmt::Result {
                 if !expected {
                     write!(fmt, "!")?;
                 }
-                write!(fmt, "{:?}, ", cond)?;
-
-                match *msg {
-                    AssertMessage::BoundsCheck { ref len, ref index } => {
-                        write!(fmt, "{:?}, {:?}, {:?}",
-                               "index out of bounds: the len is {} but the index is {}",
-                               len, index)?;
-                    }
-                    AssertMessage::Math(ref err) => {
-                        write!(fmt, "{:?}", err.description())?;
-                    }
-                    AssertMessage::GeneratorResumedAfterReturn => {
-                        write!(fmt, "{:?}", "generator resumed after completion")?;
-                    }
-                    AssertMessage::GeneratorResumedAfterPanic => {
-                        write!(fmt, "{:?}", "generator resumed after panicking")?;
-                    }
-                }
-
-                write!(fmt, ")")
+                write!(fmt, "{:?}, \"{:?}\")", cond, msg)
             },
             FalseEdges { .. } => write!(fmt, "falseEdges"),
             FalseUnwind { .. } => write!(fmt, "falseUnwind"),
@@ -1204,17 +1192,6 @@ pub fn fmt_successor_labels(&self) -> Vec<Cow<'static, str>> {
     }
 }
 
-#[derive(Clone, Debug, RustcEncodable, RustcDecodable)]
-pub enum AssertMessage<'tcx> {
-    BoundsCheck {
-        len: Operand<'tcx>,
-        index: Operand<'tcx>
-    },
-    Math(ConstMathErr),
-    GeneratorResumedAfterReturn,
-    GeneratorResumedAfterPanic,
-}
-
 ///////////////////////////////////////////////////////////////////////////
 // Statements
 
@@ -1915,12 +1892,13 @@ fn fmt_const_val<W: Write>(fmt: &mut W, const_val: &ty::Const) -> fmt::Result {
 
 pub fn print_miri_value<W: Write>(value: Value, ty: Ty, f: &mut W) -> fmt::Result {
     use ty::TypeVariants::*;
-    use rustc_const_math::ConstFloat;
     match (value, &ty.sty) {
         (Value::ByVal(PrimVal::Bytes(0)), &TyBool) => write!(f, "false"),
         (Value::ByVal(PrimVal::Bytes(1)), &TyBool) => write!(f, "true"),
-        (Value::ByVal(PrimVal::Bytes(bits)), &TyFloat(fty)) =>
-            write!(f, "{}", ConstFloat { bits, ty: fty }),
+        (Value::ByVal(PrimVal::Bytes(bits)), &TyFloat(ast::FloatTy::F32)) =>
+            write!(f, "{}f32", Single::from_bits(bits)),
+        (Value::ByVal(PrimVal::Bytes(bits)), &TyFloat(ast::FloatTy::F64)) =>
+            write!(f, "{}f64", Double::from_bits(bits)),
         (Value::ByVal(PrimVal::Bytes(n)), &TyUint(ui)) => write!(f, "{:?}{}", n, ui),
         (Value::ByVal(PrimVal::Bytes(n)), &TyInt(i)) => write!(f, "{:?}{}", n as i128, i),
         (Value::ByVal(PrimVal::Bytes(n)), &TyChar) =>
@@ -1969,7 +1947,7 @@ fn predecessors<'graph>(&'graph self, node: Self::Node)
     fn successors<'graph>(&'graph self, node: Self::Node)
                           -> <Self as GraphSuccessors<'graph>>::Iter
     {
-        self.basic_blocks[node].terminator().successors().into_owned().into_iter()
+        self.basic_blocks[node].terminator().successors().cloned()
     }
 }
 
@@ -1980,7 +1958,7 @@ impl<'a, 'b> GraphPredecessors<'b> for Mir<'a> {
 
 impl<'a, 'b>  GraphSuccessors<'b> for Mir<'a> {
     type Item = BasicBlock;
-    type Iter = IntoIter<BasicBlock>;
+    type Iter = iter::Cloned<Successors<'b>>;
 }
 
 #[derive(Copy, Clone, PartialEq, Eq, Hash, Ord, PartialOrd)]
@@ -2279,8 +2257,8 @@ fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F)
                 }
             },
             Assert { ref cond, expected, ref msg, target, cleanup } => {
-                let msg = if let AssertMessage::BoundsCheck { ref len, ref index } = *msg {
-                    AssertMessage::BoundsCheck {
+                let msg = if let EvalErrorKind::BoundsCheck { ref len, ref index } = *msg {
+                    EvalErrorKind::BoundsCheck {
                         len: len.fold_with(folder),
                         index: index.fold_with(folder),
                     }
@@ -2329,7 +2307,7 @@ fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
             },
             Assert { ref cond, ref msg, .. } => {
                 if cond.visit_with(visitor) {
-                    if let AssertMessage::BoundsCheck { ref len, ref index } = *msg {
+                    if let EvalErrorKind::BoundsCheck { ref len, ref index } = *msg {
                         len.visit_with(visitor) || index.visit_with(visitor)
                     } else {
                         false
index 666ca5eabe81b93485f5ba5cf3718ceaef1b43e1..92888ed99e4729b395968a992cc69c8f7512c454 100644 (file)
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use std::vec;
-
 use rustc_data_structures::bitvec::BitVector;
 use rustc_data_structures::indexed_vec::Idx;
 
@@ -67,7 +65,7 @@ fn next(&mut self) -> Option<(BasicBlock, &'a BasicBlockData<'tcx>)> {
             let data = &self.mir[idx];
 
             if let Some(ref term) = data.terminator {
-                for &succ in term.successors().iter() {
+                for &succ in term.successors() {
                     self.worklist.push(succ);
                 }
             }
@@ -110,7 +108,7 @@ impl<'a, 'tcx> ExactSizeIterator for Preorder<'a, 'tcx> {}
 pub struct Postorder<'a, 'tcx: 'a> {
     mir: &'a Mir<'tcx>,
     visited: BitVector,
-    visit_stack: Vec<(BasicBlock, vec::IntoIter<BasicBlock>)>
+    visit_stack: Vec<(BasicBlock, Successors<'a>)>
 }
 
 impl<'a, 'tcx> Postorder<'a, 'tcx> {
@@ -126,10 +124,7 @@ pub fn new(mir: &'a Mir<'tcx>, root: BasicBlock) -> Postorder<'a, 'tcx> {
 
         if let Some(ref term) = data.terminator {
             po.visited.insert(root.index());
-
-            let succs = term.successors().into_owned().into_iter();
-
-            po.visit_stack.push((root, succs));
+            po.visit_stack.push((root, term.successors()));
             po.traverse_successor();
         }
 
@@ -186,7 +181,7 @@ fn traverse_successor(&mut self) {
         // two iterations yield `C` and finally `A` for a final traversal of [E, D, B, C, A]
         loop {
             let bb = if let Some(&mut (_, ref mut iter)) = self.visit_stack.last_mut() {
-                if let Some(bb) = iter.next() {
+                if let Some(&bb) = iter.next() {
                     bb
                 } else {
                     break;
@@ -197,8 +192,7 @@ fn traverse_successor(&mut self) {
 
             if self.visited.insert(bb.index()) {
                 if let Some(ref term) = self.mir[bb].terminator {
-                    let succs = term.successors().into_owned().into_iter();
-                    self.visit_stack.push((bb, succs));
+                    self.visit_stack.push((bb, term.successors()));
                 }
             }
         }
index a3fdb6f73abb0e97f13c49244a33f39fa16ff7d3..59b6f3697541a0c8083079caf3d1f05391e25d45 100644 (file)
@@ -511,17 +511,13 @@ fn super_terminator_kind(&mut self,
             fn super_assert_message(&mut self,
                                     msg: & $($mutability)* AssertMessage<'tcx>,
                                     location: Location) {
-                match *msg {
-                    AssertMessage::BoundsCheck {
+                use mir::interpret::EvalErrorKind::*;
+                if let BoundsCheck {
                         ref $($mutability)* len,
                         ref $($mutability)* index
-                    } => {
-                        self.visit_operand(len, location);
-                        self.visit_operand(index, location);
-                    }
-                    AssertMessage::Math(_) => {},
-                    AssertMessage::GeneratorResumedAfterReturn => {},
-                    AssertMessage::GeneratorResumedAfterPanic => {},
+                    } = *msg {
+                    self.visit_operand(len, location);
+                    self.visit_operand(index, location);
                 }
             }
 
index 06922d986b3ce48df83cb732820e7b87d31f9310..dc97c941567059cd5912250a945af3fdc4f0e938 100644 (file)
@@ -1053,6 +1053,8 @@ fn parse_lto(slot: &mut Lto, v: Option<&str>) -> bool {
          2 = full debug info with variable and type information"),
     opt_level: Option<String> = (None, parse_opt_string, [TRACKED],
         "optimize with possible levels 0-3, s, or z"),
+    force_frame_pointers: Option<bool> = (None, parse_opt_bool, [TRACKED],
+        "force use of the frame pointers"),
     debug_assertions: Option<bool> = (None, parse_opt_bool, [TRACKED],
         "explicitly enable the cfg(debug_assertions) directive"),
     inline_threshold: Option<usize> = (None, parse_opt_uint, [TRACKED],
@@ -1681,7 +1683,7 @@ pub fn parse_cfgspecs(cfgspecs: Vec<String>) -> ast::CrateConfig {
                 early_error(ErrorOutputType::default(), &msg)
             }
 
-            (meta_item.ident.name, meta_item.value_str())
+            (meta_item.name(), meta_item.value_str())
         })
         .collect::<ast::CrateConfig>()
 }
@@ -2965,6 +2967,10 @@ fn test_codegen_options_tracking_hash() {
         opts.cg.debuginfo = Some(0xba5eba11);
         assert!(reference.dep_tracking_hash() != opts.dep_tracking_hash());
 
+        opts = reference.clone();
+        opts.cg.force_frame_pointers = Some(false);
+        assert!(reference.dep_tracking_hash() != opts.dep_tracking_hash());
+
         opts = reference.clone();
         opts.cg.debug_assertions = Some(true);
         assert!(reference.dep_tracking_hash() != opts.dep_tracking_hash());
index 37a6b2e79f7dbd0c97a0b6fda514c8aa52484ff9..2ab72ba20bf4fc4b321ed9bd76b144e60efea2ea 100644 (file)
@@ -20,7 +20,7 @@
 use middle::allocator::AllocatorKind;
 use middle::dependency_format;
 use session::search_paths::PathKind;
-use session::config::{DebugInfoLevel, OutputType};
+use session::config::{OutputType};
 use ty::tls;
 use util::nodemap::{FxHashSet};
 use util::common::{duration_to_secs_str, ErrorReported};
@@ -658,8 +658,11 @@ pub fn crt_static_feature(&self) -> bool {
     }
 
     pub fn must_not_eliminate_frame_pointers(&self) -> bool {
-        self.opts.debuginfo != DebugInfoLevel::NoDebugInfo
-            || !self.target.target.options.eliminate_frame_pointer
+        if let Some(x) = self.opts.cg.force_frame_pointers {
+            x
+        } else {
+            !self.target.target.options.eliminate_frame_pointer
+        }
     }
 
     /// Returns the symbol name for the registrar function,
index d1fd70ae02d6987b4ec5170570259079822a9367..3cf7af30b3d551a0442f509f2a5279f2494cd5a3 100644 (file)
@@ -190,7 +190,7 @@ pub fn evaluate(&self,
         for command in self.subcommands.iter().chain(Some(self)).rev() {
             if let Some(ref condition) = command.condition {
                 if !attr::eval_condition(condition, &tcx.sess.parse_sess, &mut |c| {
-                    options.contains(&(c.ident.name.as_str().to_string(),
+                    options.contains(&(c.name().as_str().to_string(),
                                       match c.value_str().map(|s| s.as_str().to_string()) {
                                           Some(s) => Some(s),
                                           None => None
index 0c35e20324c9ce0a304cd18cdc7f2e1ae60b95f6..45fa588bbf5334f821beec5a26a839d722d28274 100644 (file)
@@ -188,7 +188,7 @@ pub fn poly_project_and_unify_type<'cx, 'gcx, 'tcx>(
     let infcx = selcx.infcx();
     infcx.commit_if_ok(|snapshot| {
         let (skol_predicate, skol_map) =
-            infcx.skolemize_late_bound_regions(&obligation.predicate, snapshot);
+            infcx.skolemize_late_bound_regions(&obligation.predicate);
 
         let skol_obligation = obligation.with(skol_predicate);
         let r = match project_and_unify_type(selcx, &skol_obligation) {
@@ -409,7 +409,7 @@ fn fold_const(&mut self, constant: &'tcx ty::Const<'tcx>) -> &'tcx ty::Const<'tc
         if let ConstVal::Unevaluated(def_id, substs) = constant.val {
             let tcx = self.selcx.tcx().global_tcx();
             if let Some(param_env) = self.tcx().lift_to_global(&self.param_env) {
-                if substs.needs_infer() {
+                if substs.needs_infer() || substs.has_skol() {
                     let identity_substs = Substs::identity_for_item(tcx, def_id);
                     let instance = ty::Instance::resolve(tcx, param_env, def_id, identity_substs);
                     if let Some(instance) = instance {
index 5e0a4ca3305526fbc3aafcc3252959440066f429..f074e06165311bb12d26344fe7611457280ce010 100644 (file)
@@ -196,7 +196,7 @@ fn fold_const(&mut self, constant: &'tcx ty::Const<'tcx>) -> &'tcx ty::Const<'tc
         if let ConstVal::Unevaluated(def_id, substs) = constant.val {
             let tcx = self.infcx.tcx.global_tcx();
             if let Some(param_env) = self.tcx().lift_to_global(&self.param_env) {
-                if substs.needs_infer() {
+                if substs.needs_infer() || substs.has_skol() {
                     let identity_substs = Substs::identity_for_item(tcx, def_id);
                     let instance = ty::Instance::resolve(tcx, param_env, def_id, identity_substs);
                     if let Some(instance) = instance {
index 4ba3655bb644abec51a0c615aedd4d0d58e55ba9..54b2cf2808282fba665ed7f2ac777a088a59c458 100644 (file)
@@ -1509,7 +1509,7 @@ fn match_projection_obligation_against_definition_bounds(
         let poly_trait_predicate =
             self.infcx().resolve_type_vars_if_possible(&obligation.predicate);
         let (skol_trait_predicate, skol_map) =
-            self.infcx().skolemize_late_bound_regions(&poly_trait_predicate, snapshot);
+            self.infcx().skolemize_late_bound_regions(&poly_trait_predicate);
         debug!("match_projection_obligation_against_definition_bounds: \
                 skol_trait_predicate={:?} skol_map={:?}",
                skol_trait_predicate,
@@ -2338,7 +2338,7 @@ fn collect_predicates_for_types(&mut self,
 
             self.in_snapshot(|this, snapshot| {
                 let (skol_ty, skol_map) =
-                    this.infcx().skolemize_late_bound_regions(&ty, snapshot);
+                    this.infcx().skolemize_late_bound_regions(&ty);
                 let Normalized { value: normalized_ty, mut obligations } =
                     project::normalize_with_depth(this,
                                                   param_env,
@@ -2559,7 +2559,7 @@ fn vtable_auto_impl(&mut self,
         let trait_obligations = self.in_snapshot(|this, snapshot| {
             let poly_trait_ref = obligation.predicate.to_poly_trait_ref();
             let (trait_ref, skol_map) =
-                this.infcx().skolemize_late_bound_regions(&poly_trait_ref, snapshot);
+                this.infcx().skolemize_late_bound_regions(&poly_trait_ref);
             let cause = obligation.derived_cause(ImplDerivedObligation);
             this.impl_or_trait_obligations(cause,
                                            obligation.recursion_depth + 1,
@@ -3142,8 +3142,7 @@ fn match_impl(&mut self,
         }
 
         let (skol_obligation, skol_map) = self.infcx().skolemize_late_bound_regions(
-            &obligation.predicate,
-            snapshot);
+            &obligation.predicate);
         let skol_obligation_trait_ref = skol_obligation.trait_ref;
 
         let impl_substs = self.infcx.fresh_substs_for_item(obligation.cause.span,
index c28fcfe88059f2dfcc03d55b08f855be12dfeac5..ce4439e7c54648fa2735b8d4e804aa3665913bfa 100644 (file)
@@ -2119,7 +2119,7 @@ macro_rules! intern_method {
                                             $alloc_method:ident,
                                             $alloc_to_key:expr,
                                             $alloc_to_ret:expr,
-                                            $needs_infer:expr) -> $ty:ty) => {
+                                            $keep_in_local_tcx:expr) -> $ty:ty) => {
         impl<'a, 'gcx, $lt_tcx> TyCtxt<'a, 'gcx, $lt_tcx> {
             pub fn $method(self, v: $alloc) -> &$lt_tcx $ty {
                 {
@@ -2137,7 +2137,7 @@ pub fn $method(self, v: $alloc) -> &$lt_tcx $ty {
                 // HACK(eddyb) Depend on flags being accurate to
                 // determine that all contents are in the global tcx.
                 // See comments on Lift for why we can't use that.
-                if !($needs_infer)(&v) {
+                if !($keep_in_local_tcx)(&v) {
                     if !self.is_global() {
                         let v = unsafe {
                             mem::transmute(v)
@@ -2165,7 +2165,7 @@ pub fn $method(self, v: $alloc) -> &$lt_tcx $ty {
 }
 
 macro_rules! direct_interners {
-    ($lt_tcx:tt, $($name:ident: $method:ident($needs_infer:expr) -> $ty:ty),+) => {
+    ($lt_tcx:tt, $($name:ident: $method:ident($keep_in_local_tcx:expr) -> $ty:ty),+) => {
         $(impl<$lt_tcx> PartialEq for Interned<$lt_tcx, $ty> {
             fn eq(&self, other: &Self) -> bool {
                 self.0 == other.0
@@ -2180,7 +2180,10 @@ fn hash<H: Hasher>(&self, s: &mut H) {
             }
         }
 
-        intern_method!($lt_tcx, $name: $method($ty, alloc, |x| x, |x| x, $needs_infer) -> $ty);)+
+        intern_method!(
+            $lt_tcx,
+            $name: $method($ty, alloc, |x| x, |x| x, $keep_in_local_tcx) -> $ty
+        );)+
     }
 }
 
@@ -2189,12 +2192,7 @@ pub fn keep_local<'tcx, T: ty::TypeFoldable<'tcx>>(x: &T) -> bool {
 }
 
 direct_interners!('tcx,
-    region: mk_region(|r| {
-        match r {
-            &ty::ReVar(_) | &ty::ReSkolemized(..) => true,
-            _ => false
-        }
-    }) -> RegionKind,
+    region: mk_region(|r: &RegionKind| r.keep_in_local_tcx()) -> RegionKind,
     const_: mk_const(|c: &Const| keep_local(&c.ty) || keep_local(&c.val)) -> Const<'tcx>
 );
 
index 650ac4e6f6db6faf1fb037a6e66a3b1e0cc28415..1793b5e1edba8e0f3ca76ee956775bd8bb82cb1e 100644 (file)
@@ -91,6 +91,9 @@ fn has_infer_types(&self) -> bool {
     fn needs_infer(&self) -> bool {
         self.has_type_flags(TypeFlags::HAS_TY_INFER | TypeFlags::HAS_RE_INFER)
     }
+    fn has_skol(&self) -> bool {
+        self.has_type_flags(TypeFlags::HAS_RE_SKOL)
+    }
     fn needs_subst(&self) -> bool {
         self.has_type_flags(TypeFlags::NEEDS_SUBST)
     }
@@ -111,15 +114,6 @@ fn has_erasable_regions(&self) -> bool {
         self.has_type_flags(TypeFlags::HAS_FREE_REGIONS)
     }
 
-    fn is_normalized_for_trans(&self) -> bool {
-        !self.has_type_flags(TypeFlags::HAS_RE_INFER |
-                             TypeFlags::HAS_FREE_REGIONS |
-                             TypeFlags::HAS_TY_INFER |
-                             TypeFlags::HAS_PARAMS |
-                             TypeFlags::HAS_NORMALIZABLE_PROJECTION |
-                             TypeFlags::HAS_TY_ERR |
-                             TypeFlags::HAS_SELF)
-    }
     /// Indicates whether this value references only 'global'
     /// types/lifetimes that are the same regardless of what fn we are
     /// in. This is used for caching. Errs on the side of returning
index 55137e2891123a3b8c2bc453fff76345b603dc89..a319b341ebbf06ee2bbc82d07829668c31393ad8 100644 (file)
@@ -19,7 +19,6 @@
 use std::fmt;
 use std::i128;
 use std::mem;
-use std::ops::RangeInclusive;
 
 use ich::StableHashingContext;
 use rustc_data_structures::stable_hasher::{HashStable, StableHasher,
@@ -149,7 +148,7 @@ fn to_ty<'a, 'tcx>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>) -> Ty<'tcx> {
 /// - For a slice, this is the length.
 pub const FAT_PTR_EXTRA: usize = 1;
 
-#[derive(Copy, Clone, Debug)]
+#[derive(Copy, Clone, Debug, RustcEncodable, RustcDecodable)]
 pub enum LayoutError<'tcx> {
     Unknown(Ty<'tcx>),
     SizeOverflow(Ty<'tcx>)
@@ -492,7 +491,7 @@ enum StructKind {
             ty::TyFloat(FloatTy::F64) => scalar(F64),
             ty::TyFnPtr(_) => {
                 let mut ptr = scalar_unit(Pointer);
-                ptr.valid_range.start = 1;
+                ptr.valid_range = 1..=*ptr.valid_range.end();
                 tcx.intern_layout(LayoutDetails::scalar(self, ptr))
             }
 
@@ -506,7 +505,7 @@ enum StructKind {
             ty::TyRawPtr(ty::TypeAndMut { ty: pointee, .. }) => {
                 let mut data_ptr = scalar_unit(Pointer);
                 if !ty.is_unsafe_ptr() {
-                    data_ptr.valid_range.start = 1;
+                    data_ptr.valid_range = 1..=*data_ptr.valid_range.end();
                 }
 
                 let pointee = tcx.normalize_erasing_regions(param_env, pointee);
@@ -524,7 +523,7 @@ enum StructKind {
                     }
                     ty::TyDynamic(..) => {
                         let mut vtable = scalar_unit(Pointer);
-                        vtable.valid_range.start = 1;
+                        vtable.valid_range = 1..=*vtable.valid_range.end();
                         vtable
                     }
                     _ => return Err(LayoutError::Unknown(unsized_part))
@@ -751,8 +750,8 @@ enum StructKind {
                         match st.abi {
                             Abi::Scalar(ref mut scalar) |
                             Abi::ScalarPair(ref mut scalar, _) => {
-                                if scalar.valid_range.start == 0 {
-                                    scalar.valid_range.start = 1;
+                                if *scalar.valid_range.start() == 0 {
+                                    scalar.valid_range = 1..=*scalar.valid_range.end();
                                 }
                             }
                             _ => {}
@@ -788,18 +787,15 @@ enum StructKind {
                                 }
                             }
                         }
-                        if niche_variants.start > v {
-                            niche_variants.start = v;
-                        }
-                        niche_variants.end = v;
+                        niche_variants = *niche_variants.start().min(&v)..=v;
                     }
 
-                    if niche_variants.start > niche_variants.end {
+                    if niche_variants.start() > niche_variants.end() {
                         dataful_variant = None;
                     }
 
                     if let Some(i) = dataful_variant {
-                        let count = (niche_variants.end - niche_variants.start + 1) as u128;
+                        let count = (niche_variants.end() - niche_variants.start() + 1) as u128;
                         for (field_index, &field) in variants[i].iter().enumerate() {
                             let (offset, niche, niche_start) =
                                 match self.find_niche(field, count)? {
@@ -944,11 +940,15 @@ enum StructKind {
                 // We increase the size of the discriminant to avoid LLVM copying
                 // padding when it doesn't need to. This normally causes unaligned
                 // load/stores and excessive memcpy/memset operations. By using a
-                // bigger integer size, LLVM can be sure about it's contents and
+                // bigger integer size, LLVM can be sure about its contents and
                 // won't be so conservative.
 
                 // Use the initial field alignment
-                let mut ity = Integer::for_abi_align(dl, start_align).unwrap_or(min_ity);
+                let mut ity = if def.repr.c() || def.repr.int.is_some() {
+                    min_ity
+                } else {
+                    Integer::for_abi_align(dl, start_align).unwrap_or(min_ity)
+                };
 
                 // If the alignment is not larger than the chosen discriminant size,
                 // don't use the alignment as the final size.
@@ -1659,10 +1659,10 @@ fn find_niche(self, layout: TyLayout<'tcx>, count: u128)
             let max_value = !0u128 >> (128 - bits);
 
             // Find out how many values are outside the valid range.
-            let niches = if v.start <= v.end {
-                v.start + (max_value - v.end)
+            let niches = if v.start() <= v.end() {
+                v.start() + (max_value - v.end())
             } else {
-                v.start - v.end - 1
+                v.start() - v.end() - 1
             };
 
             // Give up if we can't fit `count` consecutive niches.
@@ -1670,11 +1670,11 @@ fn find_niche(self, layout: TyLayout<'tcx>, count: u128)
                 return None;
             }
 
-            let niche_start = v.end.wrapping_add(1) & max_value;
-            let niche_end = v.end.wrapping_add(count) & max_value;
+            let niche_start = v.end().wrapping_add(1) & max_value;
+            let niche_end = v.end().wrapping_add(count) & max_value;
             Some((offset, Scalar {
                 value,
-                valid_range: v.start..=niche_end
+                valid_range: *v.start()..=niche_end
             }, niche_start))
         };
 
@@ -1744,14 +1744,14 @@ fn hash_stable<W: StableHasherResult>(&self,
             }
             NicheFilling {
                 dataful_variant,
-                niche_variants: RangeInclusive { start, end },
+                ref niche_variants,
                 ref niche,
                 niche_start,
                 ref variants,
             } => {
                 dataful_variant.hash_stable(hcx, hasher);
-                start.hash_stable(hcx, hasher);
-                end.hash_stable(hcx, hasher);
+                niche_variants.start().hash_stable(hcx, hasher);
+                niche_variants.end().hash_stable(hcx, hasher);
                 niche.hash_stable(hcx, hasher);
                 niche_start.hash_stable(hcx, hasher);
                 variants.hash_stable(hcx, hasher);
@@ -1814,10 +1814,10 @@ impl<'a> HashStable<StableHashingContext<'a>> for Scalar {
     fn hash_stable<W: StableHasherResult>(&self,
                                           hcx: &mut StableHashingContext<'a>,
                                           hasher: &mut StableHasher<W>) {
-        let Scalar { value, valid_range: RangeInclusive { start, end } } = *self;
+        let Scalar { value, ref valid_range } = *self;
         value.hash_stable(hcx, hasher);
-        start.hash_stable(hcx, hasher);
-        end.hash_stable(hcx, hasher);
+        valid_range.start().hash_stable(hcx, hasher);
+        valid_range.end().hash_stable(hcx, hasher);
     }
 }
 
index 5a121d3edbe31f7a62c958675b9d892de4492114..c4fe112a9e913206ffbd1466d14cb9f390972bcf 100644 (file)
@@ -69,7 +69,7 @@
 pub use self::sty::{ExistentialProjection, PolyExistentialProjection, Const};
 pub use self::sty::{BoundRegion, EarlyBoundRegion, FreeRegion, Region};
 pub use self::sty::RegionKind;
-pub use self::sty::{TyVid, IntVid, FloatVid, RegionVid, SkolemizedRegionVid};
+pub use self::sty::{TyVid, IntVid, FloatVid, RegionVid};
 pub use self::sty::BoundRegion::*;
 pub use self::sty::InferTy::*;
 pub use self::sty::RegionKind::*;
@@ -1370,15 +1370,13 @@ pub fn is_empty(&self) -> bool {
 /// type name in a non-zero universe is a skolemized type -- an
 /// idealized representative of "types in general" that we use for
 /// checking generic functions.
-#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
+#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, RustcEncodable, RustcDecodable)]
 pub struct UniverseIndex(u32);
 
 impl UniverseIndex {
     /// The root universe, where things that the user defined are
     /// visible.
-    pub fn root() -> UniverseIndex {
-        UniverseIndex(0)
-    }
+    pub const ROOT: Self = UniverseIndex(0);
 
     /// A "subuniverse" corresponds to being inside a `forall` quantifier.
     /// So, for example, suppose we have this type in universe `U`:
@@ -1392,7 +1390,21 @@ pub fn root() -> UniverseIndex {
     /// region `'a`, but that region was not nameable from `U` because
     /// it was not in scope there.
     pub fn subuniverse(self) -> UniverseIndex {
-        UniverseIndex(self.0 + 1)
+        UniverseIndex(self.0.checked_add(1).unwrap())
+    }
+
+    pub fn as_u32(&self) -> u32 {
+        self.0
+    }
+
+    pub fn as_usize(&self) -> usize {
+        self.0 as usize
+    }
+}
+
+impl From<u32> for UniverseIndex {
+    fn from(index: u32) -> Self {
+        UniverseIndex(index)
     }
 }
 
@@ -1476,7 +1488,11 @@ pub fn and<T: TypeFoldable<'tcx>>(self, value: T) -> ParamEnvAnd<'tcx, T> {
             }
 
             Reveal::All => {
-                if value.needs_infer() || value.has_param_types() || value.has_self_ty() {
+                if value.has_skol()
+                    || value.needs_infer()
+                    || value.has_param_types()
+                    || value.has_self_ty()
+                {
                     ParamEnvAnd {
                         param_env: self,
                         value,
index 9b20fce667318ea1fbd3a8d0062c9f0868321c67..d4ed6c60e0efa6baae51eef83e6132c3cdd4e8cc 100644 (file)
@@ -473,9 +473,19 @@ fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<Self::Lif
 
 impl<'a, 'tcx> Lift<'tcx> for interpret::EvalError<'a> {
     type Lifted = interpret::EvalError<'tcx>;
+    fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<Self::Lifted> {
+        Some(interpret::EvalError {
+            kind: tcx.lift(&self.kind)?,
+            backtrace: self.backtrace.clone(),
+        })
+    }
+}
+
+impl<'a, 'tcx, O: Lift<'tcx>> Lift<'tcx> for interpret::EvalErrorKind<'a, O> {
+    type Lifted = interpret::EvalErrorKind<'tcx, <O as Lift<'tcx>>::Lifted>;
     fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<Self::Lifted> {
         use ::mir::interpret::EvalErrorKind::*;
-        let kind = match self.kind {
+        Some(match *self {
             MachineError(ref err) => MachineError(err.clone()),
             FunctionPointerTyMismatch(a, b) => FunctionPointerTyMismatch(
                 tcx.lift(&a)?,
@@ -504,10 +514,11 @@ fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<Self::Lif
             Unimplemented(ref s) => Unimplemented(s.clone()),
             DerefFunctionPointer => DerefFunctionPointer,
             ExecuteMemory => ExecuteMemory,
-            ArrayIndexOutOfBounds(sp, a, b) => ArrayIndexOutOfBounds(sp, a, b),
-            Math(sp, ref err) => Math(sp, err.clone()),
+            BoundsCheck { ref len, ref index } => BoundsCheck {
+                len: tcx.lift(len)?,
+                index: tcx.lift(index)?,
+            },
             Intrinsic(ref s) => Intrinsic(s.clone()),
-            OverflowingMath => OverflowingMath,
             InvalidChar(c) => InvalidChar(c),
             StackFrameLimitReached => StackFrameLimitReached,
             OutOfTls => OutOfTls,
@@ -568,10 +579,12 @@ fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<Self::Lif
             UnimplementedTraitSelection => UnimplementedTraitSelection,
             TypeckError => TypeckError,
             ReferencedConstant => ReferencedConstant,
-        };
-        Some(interpret::EvalError {
-            kind: kind,
-            backtrace: self.backtrace.clone(),
+            OverflowNeg => OverflowNeg,
+            Overflow(op) => Overflow(op),
+            DivisionByZero => DivisionByZero,
+            RemainderByZero => RemainderByZero,
+            GeneratorResumedAfterReturn => GeneratorResumedAfterReturn,
+            GeneratorResumedAfterPanic => GeneratorResumedAfterPanic,
         })
     }
 }
@@ -585,7 +598,6 @@ fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<Self::Lif
             NonConstPath => NonConstPath,
             UnimplementedConstVal(s) => UnimplementedConstVal(s),
             IndexOutOfBounds { len, index } => IndexOutOfBounds { len, index },
-            Math(ref e) => Math(e.clone()),
 
             LayoutError(ref e) => {
                 return tcx.lift(e).map(LayoutError)
index e9c1e87676b5d13846e1cf56721aabe51a632fe2..382db571b524eea6bdad0f09c15aa4977661edde 100644 (file)
@@ -1021,7 +1021,7 @@ pub enum RegionKind {
 
     /// A skolemized region - basically the higher-ranked version of ReFree.
     /// Should not exist after typeck.
-    ReSkolemized(SkolemizedRegionVid, BoundRegion),
+    ReSkolemized(ty::UniverseIndex, BoundRegion),
 
     /// Empty lifetime is for data that is never accessed.
     /// Bottom in the region lattice. We treat ReEmpty somewhat
@@ -1075,11 +1075,6 @@ pub struct FloatVid {
         DEBUG_FORMAT = custom,
     });
 
-#[derive(Clone, Copy, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable, PartialOrd, Ord)]
-pub struct SkolemizedRegionVid {
-    pub index: u32,
-}
-
 #[derive(Clone, Copy, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)]
 pub enum InferTy {
     TyVar(TyVid),
@@ -1171,13 +1166,6 @@ pub fn is_late_bound(&self) -> bool {
         }
     }
 
-    pub fn needs_infer(&self) -> bool {
-        match *self {
-            ty::ReVar(..) | ty::ReSkolemized(..) => true,
-            _ => false
-        }
-    }
-
     pub fn escapes_depth(&self, depth: u32) -> bool {
         match *self {
             ty::ReLateBound(debruijn, _) => debruijn.depth > depth,
@@ -1195,20 +1183,29 @@ pub fn from_depth(&self, depth: u32) -> RegionKind {
         }
     }
 
+    pub fn keep_in_local_tcx(&self) -> bool {
+        if let ty::ReVar(..) = self {
+            true
+        } else {
+            false
+        }
+    }
+
     pub fn type_flags(&self) -> TypeFlags {
         let mut flags = TypeFlags::empty();
 
+        if self.keep_in_local_tcx() {
+            flags = flags | TypeFlags::KEEP_IN_LOCAL_TCX;
+        }
+
         match *self {
             ty::ReVar(..) => {
                 flags = flags | TypeFlags::HAS_FREE_REGIONS;
                 flags = flags | TypeFlags::HAS_RE_INFER;
-                flags = flags | TypeFlags::KEEP_IN_LOCAL_TCX;
             }
             ty::ReSkolemized(..) => {
                 flags = flags | TypeFlags::HAS_FREE_REGIONS;
-                flags = flags | TypeFlags::HAS_RE_INFER;
                 flags = flags | TypeFlags::HAS_RE_SKOL;
-                flags = flags | TypeFlags::KEEP_IN_LOCAL_TCX;
             }
             ty::ReLateBound(..) => { }
             ty::ReEarlyBound(..) => {
index b777f513e6df072425698918e36935642be51525..894a18b79ccb2ad8916312e3a1921224c4db663a 100644 (file)
@@ -808,8 +808,8 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
                     write!(f, "'?{}", c.index())
                 }
 
-                ty::ReSkolemized(id, ref bound_region) => {
-                    write!(f, "ReSkolemized({}, {:?})", id.index, bound_region)
+                ty::ReSkolemized(universe, ref bound_region) => {
+                    write!(f, "ReSkolemized({:?}, {:?})", universe, bound_region)
                 }
 
                 ty::ReEmpty => write!(f, "ReEmpty"),
index dec88eb62cc60ef94eecf6a5517544c35951dd08..e662088e82fb09724338560c36cddb60e7641965 100644 (file)
@@ -20,7 +20,7 @@
 pub struct DoubleFloat<F>(F, F);
 pub type DoubleDouble = DoubleFloat<ieee::Double>;
 
-// These are legacy semantics for the Fallback, inaccrurate implementation of
+// These are legacy semantics for the Fallback, inaccurate implementation of
 // IBM double-double, if the accurate DoubleDouble doesn't handle the
 // operation. It's equivalent to having an IEEE number with consecutive 106
 // bits of mantissa and 11 bits of exponent.
diff --git a/src/librustc_const_math/Cargo.toml b/src/librustc_const_math/Cargo.toml
deleted file mode 100644 (file)
index 41310ed..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-[package]
-authors = ["The Rust Project Developers"]
-name = "rustc_const_math"
-version = "0.0.0"
-
-[lib]
-name = "rustc_const_math"
-path = "lib.rs"
-crate-type = ["dylib"]
-
-[dependencies]
-rustc_apfloat = { path = "../librustc_apfloat" }
-serialize = { path = "../libserialize" }
-syntax = { path = "../libsyntax" }
diff --git a/src/librustc_const_math/err.rs b/src/librustc_const_math/err.rs
deleted file mode 100644 (file)
index bd0a332..0000000
+++ /dev/null
@@ -1,87 +0,0 @@
-// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-use syntax::ast;
-
-#[derive(Debug, PartialEq, Eq, Clone, RustcEncodable, RustcDecodable)]
-pub enum ConstMathErr {
-    NotInRange,
-    CmpBetweenUnequalTypes,
-    UnequalTypes(Op),
-    Overflow(Op),
-    ShiftNegative,
-    DivisionByZero,
-    RemainderByZero,
-    UnsignedNegation,
-    ULitOutOfRange(ast::UintTy),
-    LitOutOfRange(ast::IntTy),
-}
-pub use self::ConstMathErr::*;
-
-#[derive(Debug, PartialEq, Eq, Clone, RustcEncodable, RustcDecodable)]
-pub enum Op {
-    Add,
-    Sub,
-    Mul,
-    Div,
-    Rem,
-    Shr,
-    Shl,
-    Neg,
-    BitAnd,
-    BitOr,
-    BitXor,
-}
-
-impl ConstMathErr {
-    pub fn description(&self) -> &'static str {
-        use self::Op::*;
-        match *self {
-            NotInRange => "inferred value out of range",
-            CmpBetweenUnequalTypes => "compared two values of different types",
-            UnequalTypes(Add) => "tried to add two values of different types",
-            UnequalTypes(Sub) => "tried to subtract two values of different types",
-            UnequalTypes(Mul) => "tried to multiply two values of different types",
-            UnequalTypes(Div) => "tried to divide two values of different types",
-            UnequalTypes(Rem) => {
-                "tried to calculate the remainder of two values of different types"
-            },
-            UnequalTypes(BitAnd) => "tried to bitand two values of different types",
-            UnequalTypes(BitOr) => "tried to bitor two values of different types",
-            UnequalTypes(BitXor) => "tried to xor two values of different types",
-            UnequalTypes(_) => unreachable!(),
-            Overflow(Add) => "attempt to add with overflow",
-            Overflow(Sub) => "attempt to subtract with overflow",
-            Overflow(Mul) => "attempt to multiply with overflow",
-            Overflow(Div) => "attempt to divide with overflow",
-            Overflow(Rem) => "attempt to calculate the remainder with overflow",
-            Overflow(Neg) => "attempt to negate with overflow",
-            Overflow(Shr) => "attempt to shift right with overflow",
-            Overflow(Shl) => "attempt to shift left with overflow",
-            Overflow(_) => unreachable!(),
-            ShiftNegative => "attempt to shift by a negative amount",
-            DivisionByZero => "attempt to divide by zero",
-            RemainderByZero => "attempt to calculate the remainder with a divisor of zero",
-            UnsignedNegation => "unary negation of unsigned integer",
-            ULitOutOfRange(ast::UintTy::U8) => "literal out of range for u8",
-            ULitOutOfRange(ast::UintTy::U16) => "literal out of range for u16",
-            ULitOutOfRange(ast::UintTy::U32) => "literal out of range for u32",
-            ULitOutOfRange(ast::UintTy::U64) => "literal out of range for u64",
-            ULitOutOfRange(ast::UintTy::U128) => "literal out of range for u128",
-            ULitOutOfRange(ast::UintTy::Usize) => "literal out of range for usize",
-            LitOutOfRange(ast::IntTy::I8) => "literal out of range for i8",
-            LitOutOfRange(ast::IntTy::I16) => "literal out of range for i16",
-            LitOutOfRange(ast::IntTy::I32) => "literal out of range for i32",
-            LitOutOfRange(ast::IntTy::I64) => "literal out of range for i64",
-            LitOutOfRange(ast::IntTy::I128) => "literal out of range for i128",
-            LitOutOfRange(ast::IntTy::Isize) => "literal out of range for isize",
-        }
-    }
-}
diff --git a/src/librustc_const_math/float.rs b/src/librustc_const_math/float.rs
deleted file mode 100644 (file)
index 9d820ea..0000000
+++ /dev/null
@@ -1,213 +0,0 @@
-// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-use std::cmp::Ordering;
-use std::num::ParseFloatError;
-
-use syntax::ast;
-
-use rustc_apfloat::{Float, FloatConvert, Status};
-use rustc_apfloat::ieee::{Single, Double};
-
-use super::err::*;
-
-// Note that equality for `ConstFloat` means that the it is the same
-// constant, not that the rust values are equal. In particular, `NaN
-// == NaN` (at least if it's the same NaN; distinct encodings for NaN
-// are considering unequal).
-#[derive(Copy, Clone, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)]
-pub struct ConstFloat {
-    pub ty: ast::FloatTy,
-
-    // This is a bit inefficient but it makes conversions below more
-    // ergonomic, and all of this will go away once `miri` is merged.
-    pub bits: u128,
-}
-
-impl ConstFloat {
-    /// Description of the type, not the value
-    pub fn description(&self) -> &'static str {
-        self.ty.ty_to_string()
-    }
-
-    /// Compares the values if they are of the same type
-    pub fn try_cmp(self, rhs: Self) -> Result<Ordering, ConstMathErr> {
-        match (self.ty, rhs.ty) {
-            (ast::FloatTy::F64, ast::FloatTy::F64)  => {
-                let a = Double::from_bits(self.bits);
-                let b = Double::from_bits(rhs.bits);
-                // This is pretty bad but it is the existing behavior.
-                Ok(a.partial_cmp(&b).unwrap_or(Ordering::Greater))
-            }
-
-            (ast::FloatTy::F32, ast::FloatTy::F32) => {
-                let a = Single::from_bits(self.bits);
-                let b = Single::from_bits(rhs.bits);
-                Ok(a.partial_cmp(&b).unwrap_or(Ordering::Greater))
-            }
-
-            _ => Err(CmpBetweenUnequalTypes),
-        }
-    }
-
-    pub fn from_i128(input: i128, ty: ast::FloatTy) -> Self {
-        let bits = match ty {
-            ast::FloatTy::F32 => Single::from_i128(input).value.to_bits(),
-            ast::FloatTy::F64 => Double::from_i128(input).value.to_bits()
-        };
-        ConstFloat { bits, ty }
-    }
-
-    pub fn from_u128(input: u128, ty: ast::FloatTy) -> Self {
-        let bits = match ty {
-            ast::FloatTy::F32 => Single::from_u128(input).value.to_bits(),
-            ast::FloatTy::F64 => Double::from_u128(input).value.to_bits()
-        };
-        ConstFloat { bits, ty }
-    }
-
-    pub fn from_str(num: &str, ty: ast::FloatTy) -> Result<Self, ParseFloatError> {
-        let bits = match ty {
-            ast::FloatTy::F32 => {
-                let rust_bits = num.parse::<f32>()?.to_bits() as u128;
-                let apfloat = num.parse::<Single>().unwrap_or_else(|e| {
-                    panic!("apfloat::ieee::Single failed to parse `{}`: {:?}", num, e);
-                });
-                let apfloat_bits = apfloat.to_bits();
-                assert!(rust_bits == apfloat_bits,
-                    "apfloat::ieee::Single gave different result for `{}`: \
-                     {}({:#x}) vs Rust's {}({:#x})",
-                    num, apfloat, apfloat_bits,
-                    Single::from_bits(rust_bits), rust_bits);
-                apfloat_bits
-            }
-            ast::FloatTy::F64 => {
-                let rust_bits = num.parse::<f64>()?.to_bits() as u128;
-                let apfloat = num.parse::<Double>().unwrap_or_else(|e| {
-                    panic!("apfloat::ieee::Double failed to parse `{}`: {:?}", num, e);
-                });
-                let apfloat_bits = apfloat.to_bits();
-                assert!(rust_bits == apfloat_bits,
-                    "apfloat::ieee::Double gave different result for `{}`: \
-                     {}({:#x}) vs Rust's {}({:#x})",
-                    num, apfloat, apfloat_bits,
-                    Double::from_bits(rust_bits), rust_bits);
-                apfloat_bits
-            }
-        };
-        Ok(ConstFloat { bits, ty })
-    }
-
-    pub fn to_i128(self, width: usize) -> Option<i128> {
-        assert!(width <= 128);
-        let r = match self.ty {
-            ast::FloatTy::F32 => Single::from_bits(self.bits).to_i128(width),
-            ast::FloatTy::F64 => Double::from_bits(self.bits).to_i128(width)
-        };
-        if r.status.intersects(Status::INVALID_OP) {
-            None
-        } else {
-            Some(r.value)
-        }
-    }
-
-    pub fn to_u128(self, width: usize) -> Option<u128> {
-        assert!(width <= 128);
-        let r = match self.ty {
-            ast::FloatTy::F32 => Single::from_bits(self.bits).to_u128(width),
-            ast::FloatTy::F64 => Double::from_bits(self.bits).to_u128(width)
-        };
-        if r.status.intersects(Status::INVALID_OP) {
-            None
-        } else {
-            Some(r.value)
-        }
-    }
-
-    pub fn convert(self, to: ast::FloatTy) -> Self {
-        let bits = match (self.ty, to) {
-            (ast::FloatTy::F32, ast::FloatTy::F32) |
-            (ast::FloatTy::F64, ast::FloatTy::F64) => return self,
-
-            (ast::FloatTy::F32, ast::FloatTy::F64) => {
-                Double::to_bits(Single::from_bits(self.bits).convert(&mut false).value)
-            }
-            (ast::FloatTy::F64, ast::FloatTy::F32) => {
-                Single::to_bits(Double::from_bits(self.bits).convert(&mut false).value)
-            }
-        };
-        ConstFloat { bits, ty: to }
-    }
-}
-
-impl ::std::fmt::Display for ConstFloat {
-    fn fmt(&self, fmt: &mut ::std::fmt::Formatter) -> Result<(), ::std::fmt::Error> {
-        match self.ty {
-            ast::FloatTy::F32 => write!(fmt, "{:#}", Single::from_bits(self.bits))?,
-            ast::FloatTy::F64 => write!(fmt, "{:#}", Double::from_bits(self.bits))?,
-        }
-        write!(fmt, "{}", self.ty)
-    }
-}
-
-impl ::std::fmt::Debug for ConstFloat {
-    fn fmt(&self, fmt: &mut ::std::fmt::Formatter) -> Result<(), ::std::fmt::Error> {
-        ::std::fmt::Display::fmt(self, fmt)
-    }
-}
-
-macro_rules! derive_binop {
-    ($op:ident, $func:ident) => {
-        impl ::std::ops::$op for ConstFloat {
-            type Output = Result<Self, ConstMathErr>;
-            fn $func(self, rhs: Self) -> Result<Self, ConstMathErr> {
-                let bits = match (self.ty, rhs.ty) {
-                    (ast::FloatTy::F32, ast::FloatTy::F32) =>{
-                        let a = Single::from_bits(self.bits);
-                        let b = Single::from_bits(rhs.bits);
-                        a.$func(b).value.to_bits()
-                    }
-                    (ast::FloatTy::F64, ast::FloatTy::F64) => {
-                        let a = Double::from_bits(self.bits);
-                        let b = Double::from_bits(rhs.bits);
-                        a.$func(b).value.to_bits()
-                    }
-                    _ => return Err(UnequalTypes(Op::$op)),
-                };
-                Ok(ConstFloat { bits, ty: self.ty })
-            }
-        }
-    }
-}
-
-derive_binop!(Add, add);
-derive_binop!(Sub, sub);
-derive_binop!(Mul, mul);
-derive_binop!(Div, div);
-derive_binop!(Rem, rem);
-
-impl ::std::ops::Neg for ConstFloat {
-    type Output = Self;
-    fn neg(self) -> Self {
-        let bits = match self.ty {
-            ast::FloatTy::F32 => (-Single::from_bits(self.bits)).to_bits(),
-            ast::FloatTy::F64 => (-Double::from_bits(self.bits)).to_bits(),
-        };
-        ConstFloat { bits, ty: self.ty }
-    }
-}
-
-/// This is `f32::MAX + (0.5 ULP)` as an integer. Numbers greater or equal to this
-/// are rounded to infinity when converted to `f32`.
-///
-/// NB: Computed as maximum significand with an extra 1 bit added (for the half ULP)
-/// shifted by the maximum exponent (accounting for normalization).
-pub const MAX_F32_PLUS_HALF_ULP: u128 = ((1 << (Single::PRECISION + 1)) - 1)
-                                        << (Single::MAX_EXP - Single::PRECISION as i16);
diff --git a/src/librustc_const_math/lib.rs b/src/librustc_const_math/lib.rs
deleted file mode 100644 (file)
index 499c330..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-//! Rusty Mathematics
-//!
-//! # Note
-//!
-//! This API is completely unstable and subject to change.
-
-#![doc(html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
-      html_favicon_url = "https://doc.rust-lang.org/favicon.ico",
-      html_root_url = "https://doc.rust-lang.org/nightly/")]
-
-extern crate rustc_apfloat;
-
-extern crate syntax;
-
-extern crate serialize as rustc_serialize; // used by deriving
-
-mod float;
-mod err;
-
-pub use float::*;
-pub use err::{ConstMathErr, Op};
index 3f166daac717e082a15548b3b7019e935af46e7b..a1052ca6c3ca9520fc7cf8f4e38ebc106f8263a7 100644 (file)
@@ -1060,7 +1060,7 @@ fn print_crate_info(trans: &TransCrate,
                     let mut cfgs = Vec::new();
                     for &(name, ref value) in sess.parse_sess.config.iter() {
                         let gated_cfg = GatedCfg::gate(&ast::MetaItem {
-                            ident: ast::Ident::with_empty_ctxt(name),
+                            ident: ast::Path::from_ident(name.to_ident()),
                             node: ast::MetaItemKind::Word,
                             span: DUMMY_SP,
                         });
index 57311a7b588a049fdf3580c25ae63503475fa286..38e891008f7308c073fb30b82c976418a4760b4e 100644 (file)
@@ -110,7 +110,7 @@ fn argument(&self, attr: &ast::Attribute) -> Option<ast::Name> {
         for list_item in attr.meta_item_list().unwrap_or_default() {
             match list_item.word() {
                 Some(word) if value.is_none() =>
-                    value = Some(word.ident.name),
+                    value = Some(word.name()),
                 _ =>
                     // FIXME better-encapsulate meta_item (don't directly access `node`)
                     span_bug!(list_item.span(), "unexpected meta-item {:?}", list_item.node),
index 91ce6f3854a501cb17f5ba01842975cf1bc67cec..f06062fa4ac83091dddc7945df8660ef7672d202 100644 (file)
@@ -675,9 +675,8 @@ fn get_lints(&self) -> LintArray {
 
 impl EarlyLintPass for DeprecatedAttr {
     fn check_attribute(&mut self, cx: &EarlyContext, attr: &ast::Attribute) {
-        let name = unwrap_or!(attr.name(), return);
         for &&(n, _, ref g) in &self.depr_attrs {
-            if name == n {
+            if attr.name() == n {
                 if let &AttributeGate::Gated(Stability::Deprecated(link),
                                              ref name,
                                              ref reason,
index 65b340d65686d13c7e2730ebcc28e711962adf7c..4f6d23dce6dbb835c27a520e48737323c3ff8d9c 100644 (file)
@@ -30,7 +30,6 @@
 #![feature(quote)]
 #![feature(rustc_diagnostic_macros)]
 
-#[macro_use]
 extern crate syntax;
 #[macro_use]
 extern crate rustc;
index 5ec8305de788c3ecb4fa4fa84ca4a05b6466c47c..8df40b62ddd1253d66cfd874ecce18377502ba69 100644 (file)
@@ -8,6 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+use rustc::hir::def::Def;
 use rustc::hir::def_id::DefId;
 use rustc::ty;
 use rustc::ty::adjustment;
@@ -72,54 +73,59 @@ fn check_stmt(&mut self, cx: &LateContext, s: &hir::Stmt) {
 
         let mut fn_warned = false;
         let mut op_warned = false;
-        if cx.tcx.features().fn_must_use {
-            let maybe_def = match expr.node {
-                hir::ExprCall(ref callee, _) => {
-                    match callee.node {
-                        hir::ExprPath(ref qpath) => {
-                            Some(cx.tables.qpath_def(qpath, callee.hir_id))
-                        },
-                        _ => None
-                    }
-                },
-                hir::ExprMethodCall(..) => {
-                    cx.tables.type_dependent_defs().get(expr.hir_id).cloned()
-                },
-                _ => None
-            };
-            if let Some(def) = maybe_def {
-                let def_id = def.def_id();
-                fn_warned = check_must_use(cx, def_id, s.span, "return value of ");
-            }
-            let must_use_op = match expr.node {
-                // Hardcoding operators here seemed more expedient than the
-                // refactoring that would be needed to look up the `#[must_use]`
-                // attribute which does exist on the comparison trait methods
-                hir::ExprBinary(bin_op, ..)  => {
-                    match bin_op.node {
-                        hir::BiEq | hir::BiLt | hir::BiLe | hir::BiNe | hir::BiGe | hir::BiGt => {
-                            Some("comparison")
-                        },
-                        hir::BiAdd | hir::BiSub | hir::BiDiv | hir::BiMul | hir::BiRem => {
-                            Some("arithmetic operation")
-                        },
-                        hir::BiAnd | hir::BiOr => {
-                            Some("logical operation")
-                        },
-                        hir::BiBitXor | hir::BiBitAnd | hir::BiBitOr | hir::BiShl | hir::BiShr => {
-                            Some("bitwise operation")
-                        },
-                    }
-                },
-                hir::ExprUnary(..) => Some("unary operation"),
-                _ => None
-            };
-            if let Some(must_use_op) = must_use_op {
-                cx.span_lint(UNUSED_MUST_USE, expr.span,
-                    &format!("unused {} which must be used", must_use_op));
-                op_warned = true;
-            }
+        let maybe_def = match expr.node {
+            hir::ExprCall(ref callee, _) => {
+                match callee.node {
+                    hir::ExprPath(ref qpath) => {
+                        let def = cx.tables.qpath_def(qpath, callee.hir_id);
+                        if let Def::Fn(_) = def {
+                            Some(def)
+                        } else {  // `Def::Local` if it was a closure, for which we
+                            None  // do not currently support must-use linting
+                        }
+                    },
+                    _ => None
+                }
+            },
+            hir::ExprMethodCall(..) => {
+                cx.tables.type_dependent_defs().get(expr.hir_id).cloned()
+            },
+            _ => None
+        };
+        if let Some(def) = maybe_def {
+            let def_id = def.def_id();
+            fn_warned = check_must_use(cx, def_id, s.span, "return value of ");
         }
+        let must_use_op = match expr.node {
+            // Hardcoding operators here seemed more expedient than the
+            // refactoring that would be needed to look up the `#[must_use]`
+            // attribute which does exist on the comparison trait methods
+            hir::ExprBinary(bin_op, ..)  => {
+                match bin_op.node {
+                    hir::BiEq | hir::BiLt | hir::BiLe | hir::BiNe | hir::BiGe | hir::BiGt => {
+                        Some("comparison")
+                    },
+                    hir::BiAdd | hir::BiSub | hir::BiDiv | hir::BiMul | hir::BiRem => {
+                        Some("arithmetic operation")
+                    },
+                    hir::BiAnd | hir::BiOr => {
+                        Some("logical operation")
+                    },
+                    hir::BiBitXor | hir::BiBitAnd | hir::BiBitOr | hir::BiShl | hir::BiShr => {
+                        Some("bitwise operation")
+                    },
+                }
+            },
+            hir::ExprUnary(..) => Some("unary operation"),
+            _ => None
+        };
+
+        if let Some(must_use_op) = must_use_op {
+            cx.span_lint(UNUSED_MUST_USE, expr.span,
+                         &format!("unused {} which must be used", must_use_op));
+            op_warned = true;
+        }
+
         if !(ty_warned || fn_warned || op_warned) {
             cx.span_lint(UNUSED_RESULTS, s.span, "unused result");
         }
@@ -186,8 +192,6 @@ fn get_lints(&self) -> LintArray {
 impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnusedAttributes {
     fn check_attribute(&mut self, cx: &LateContext, attr: &ast::Attribute) {
         debug!("checking attribute: {:?}", attr);
-        let name = unwrap_or!(attr.name(), return);
-
         // Note that check_name() marks the attribute as used if it matches.
         for &(ref name, ty, _) in BUILTIN_ATTRIBUTES {
             match ty {
@@ -207,6 +211,7 @@ fn check_attribute(&mut self, cx: &LateContext, attr: &ast::Attribute) {
             }
         }
 
+        let name = attr.name();
         if !attr::is_used(attr) {
             debug!("Emitting warning for: {:?}", attr);
             cx.span_lint(UNUSED_ATTRIBUTES, attr.span, "unused attribute");
index a1b348774b163bb8f750d3a0ac79d20305ea4ed0..62964745b6f9eb49ff8c8730a4375dd4dd1b255a 100644 (file)
@@ -16,7 +16,6 @@ log = "0.4"
 log_settings = "0.1.1"
 rustc = { path = "../librustc" }
 rustc_target = { path = "../librustc_target" }
-rustc_const_math = { path = "../librustc_const_math" }
 rustc_data_structures = { path = "../librustc_data_structures" }
 rustc_errors = { path = "../librustc_errors" }
 serialize = { path = "../libserialize" }
index 4b714100816beb5d8376fddc0fa0f8a404078824..c619f350f58de10da593624a17a31ce56eb50591 100644 (file)
@@ -18,7 +18,7 @@
 use rustc::ty::{self, ParamEnv, TyCtxt};
 use rustc::ty::maps::Providers;
 use rustc::lint::builtin::UNUSED_MUT;
-use rustc::mir::{AssertMessage, AggregateKind, BasicBlock, BorrowCheckResult, BorrowKind};
+use rustc::mir::{AggregateKind, BasicBlock, BorrowCheckResult, BorrowKind};
 use rustc::mir::{ClearCrossCrate, Local, Location, Place, Mir, Mutability, Operand};
 use rustc::mir::{Projection, ProjectionElem, Rvalue, Field, Statement, StatementKind};
 use rustc::mir::{Terminator, TerminatorKind};
@@ -586,18 +586,14 @@ fn visit_terminator_entry(
                 cleanup: _,
             } => {
                 self.consume_operand(ContextKind::Assert.new(loc), (cond, span), flow_state);
-                match *msg {
-                    AssertMessage::BoundsCheck { ref len, ref index } => {
-                        self.consume_operand(ContextKind::Assert.new(loc), (len, span), flow_state);
-                        self.consume_operand(
-                            ContextKind::Assert.new(loc),
-                            (index, span),
-                            flow_state,
-                        );
-                    }
-                    AssertMessage::Math(_ /*const_math_err*/) => {}
-                    AssertMessage::GeneratorResumedAfterReturn => {}
-                    AssertMessage::GeneratorResumedAfterPanic => {}
+                use rustc::mir::interpret::EvalErrorKind::BoundsCheck;
+                if let BoundsCheck { ref len, ref index } = *msg {
+                    self.consume_operand(ContextKind::Assert.new(loc), (len, span), flow_state);
+                    self.consume_operand(
+                        ContextKind::Assert.new(loc),
+                        (index, span),
+                        flow_state,
+                    );
                 }
             }
 
index d5e11a312ec26fb763f3be5dc6f8e9c5162131be..56e388a5b6094b81d87df6e46a7006a359ba72ca 100644 (file)
@@ -193,7 +193,6 @@ fn find(&mut self) -> Option<Location> {
                         block_data
                             .terminator()
                             .successors()
-                            .iter()
                             .map(|&basic_block| Location {
                                 statement_index: 0,
                                 block: basic_block,
index 4fcd3118f91081db6587ef0e63fd4dbb382c7e02..f68394d6149818833bc862f9854d233eceb191f9 100644 (file)
@@ -95,7 +95,6 @@ pub(super) fn dfs<C>(
                     block_data
                         .terminator()
                         .successors()
-                        .iter()
                         .map(|&basic_block| Location {
                             statement_index: 0,
                             block: basic_block,
index 08391401cc696e45fc0252f5961ecf25a0778267..4d1f3e2b4300ab30a8ed6927cfe0029b6f78bca9 100644 (file)
@@ -16,7 +16,7 @@
 use rustc::infer::RegionVariableOrigin;
 use rustc::infer::SubregionOrigin;
 use rustc::infer::error_reporting::nice_region_error::NiceRegionError;
-use rustc::infer::region_constraints::{GenericKind, VarOrigins};
+use rustc::infer::region_constraints::{GenericKind, VarInfos};
 use rustc::mir::{ClosureOutlivesRequirement, ClosureOutlivesSubject, ClosureRegionRequirements,
                  Local, Location, Mir};
 use rustc::traits::ObligationCause;
@@ -256,19 +256,19 @@ impl<'tcx> RegionInferenceContext<'tcx> {
     /// of those will be constant regions representing the free
     /// regions defined in `universal_regions`.
     pub(crate) fn new(
-        var_origins: VarOrigins,
+        var_infos: VarInfos,
         universal_regions: UniversalRegions<'tcx>,
         mir: &Mir<'tcx>,
     ) -> Self {
-        let num_region_variables = var_origins.len();
+        let num_region_variables = var_infos.len();
         let num_universal_regions = universal_regions.len();
 
         let elements = &Rc::new(RegionValueElements::new(mir, num_universal_regions));
 
         // Create a RegionDefinition for each inference variable.
-        let definitions = var_origins
+        let definitions = var_infos
             .into_iter()
-            .map(|origin| RegionDefinition::new(origin))
+            .map(|info| RegionDefinition::new(info.origin))
             .collect();
 
         let mut result = Self {
index a811b2c147e98d392a696490f6455622e1718637..a21b9196badb5856b5fba5c3e8575114662bdf09 100644 (file)
@@ -22,6 +22,7 @@
 use rustc::infer::{InferCtxt, InferOk, InferResult, LateBoundRegionConversionTime, UnitResult};
 use rustc::mir::tcx::PlaceTy;
 use rustc::mir::visit::{PlaceContext, Visitor};
+use rustc::mir::interpret::EvalErrorKind::BoundsCheck;
 use rustc::mir::*;
 use rustc::traits::query::NoSolution;
 use rustc::traits::{self, Normalized, TraitEngine};
@@ -928,7 +929,7 @@ fn check_terminator(
                     span_mirbug!(self, term, "bad Assert ({:?}, not bool", cond_ty);
                 }
 
-                if let AssertMessage::BoundsCheck { ref len, ref index } = *msg {
+                if let BoundsCheck { ref len, ref index } = *msg {
                     if len.ty(mir, tcx) != tcx.types.usize {
                         span_mirbug!(self, len, "bounds-check length non-usize {:?}", len)
                     }
index 9e21790851167c3be29513c493189c969b36f5ef..19ec13324d6b4a8c287a51505f03e7ed82c158c9 100644 (file)
@@ -14,6 +14,7 @@
 use build::expr::category::Category;
 use hair::*;
 use rustc::mir::*;
+use rustc::mir::interpret::EvalErrorKind::BoundsCheck;
 
 use rustc_data_structures::indexed_vec::Idx;
 
@@ -73,7 +74,7 @@ fn expr_as_place(&mut self,
                                                            Operand::Copy(Place::Local(idx)),
                                                            Operand::Copy(len.clone())));
 
-                let msg = AssertMessage::BoundsCheck {
+                let msg = BoundsCheck {
                     len: Operand::Move(len),
                     index: Operand::Copy(Place::Local(idx))
                 };
index b7f402f61a9c1d5ac8f56a6bd4ab927168f13c31..9e96fdf821417f7bdcf7ecad1be5bb5ca7baa92a 100644 (file)
@@ -10,7 +10,6 @@
 
 //! See docs in build/expr/mod.rs
 
-use rustc_const_math::{ConstMathErr, Op};
 use rustc_data_structures::fx::FxHashMap;
 use rustc_data_structures::indexed_vec::Idx;
 
@@ -21,7 +20,7 @@
 use rustc::middle::region;
 use rustc::ty::{self, Ty};
 use rustc::mir::*;
-use rustc::mir::interpret::{Value, PrimVal};
+use rustc::mir::interpret::{Value, PrimVal, EvalErrorKind};
 use syntax_pos::Span;
 
 impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
@@ -86,9 +85,8 @@ fn expr_as_rvalue(&mut self,
                     this.cfg.push_assign(block, source_info, &is_min,
                                          Rvalue::BinaryOp(BinOp::Eq, arg.to_copy(), minval));
 
-                    let err = ConstMathErr::Overflow(Op::Neg);
                     block = this.assert(block, Operand::Move(is_min), false,
-                                        AssertMessage::Math(err), expr_span);
+                                        EvalErrorKind::OverflowNeg, expr_span);
                 }
                 block.and(Rvalue::UnaryOp(op, arg))
             }
@@ -311,19 +309,10 @@ pub fn build_binary_op(&mut self, mut block: BasicBlock,
             let val = result_value.clone().field(val_fld, ty);
             let of = result_value.field(of_fld, bool_ty);
 
-            let err = ConstMathErr::Overflow(match op {
-                BinOp::Add => Op::Add,
-                BinOp::Sub => Op::Sub,
-                BinOp::Mul => Op::Mul,
-                BinOp::Shl => Op::Shl,
-                BinOp::Shr => Op::Shr,
-                _ => {
-                    bug!("MIR build_binary_op: {:?} is not checkable", op)
-                }
-            });
+            let err = EvalErrorKind::Overflow(op);
 
             block = self.assert(block, Operand::Move(of), false,
-                                AssertMessage::Math(err), span);
+                                err, span);
 
             block.and(Rvalue::Use(Operand::Move(val)))
         } else {
@@ -332,11 +321,11 @@ pub fn build_binary_op(&mut self, mut block: BasicBlock,
                 // and 2. there are two possible failure cases, divide-by-zero and overflow.
 
                 let (zero_err, overflow_err) = if op == BinOp::Div {
-                    (ConstMathErr::DivisionByZero,
-                     ConstMathErr::Overflow(Op::Div))
+                    (EvalErrorKind::DivisionByZero,
+                     EvalErrorKind::Overflow(op))
                 } else {
-                    (ConstMathErr::RemainderByZero,
-                     ConstMathErr::Overflow(Op::Rem))
+                    (EvalErrorKind::RemainderByZero,
+                     EvalErrorKind::Overflow(op))
                 };
 
                 // Check for / 0
@@ -346,7 +335,7 @@ pub fn build_binary_op(&mut self, mut block: BasicBlock,
                                      Rvalue::BinaryOp(BinOp::Eq, rhs.to_copy(), zero));
 
                 block = self.assert(block, Operand::Move(is_zero), false,
-                                    AssertMessage::Math(zero_err), span);
+                                    zero_err, span);
 
                 // We only need to check for the overflow in one case:
                 // MIN / -1, and only for signed values.
@@ -371,7 +360,7 @@ pub fn build_binary_op(&mut self, mut block: BasicBlock,
                                          Rvalue::BinaryOp(BinOp::BitAnd, is_neg_1, is_min));
 
                     block = self.assert(block, Operand::Move(of), false,
-                                        AssertMessage::Math(overflow_err), span);
+                                        overflow_err, span);
                 }
             }
 
index 07585c08f6a295d068f36ca5b7127ac91821c8e3..9096ac1444cfc98854b6d3d3dfc2a3750157c1c1 100644 (file)
@@ -73,8 +73,8 @@ pub(crate) fn print_borrowck_graph_to<'a, 'tcx, BD, P>(
 pub struct Edge { source: BasicBlock, index: usize }
 
 fn outgoing(mir: &Mir, bb: BasicBlock) -> Vec<Edge> {
-    let succ_len = mir[bb].terminator().successors().len();
-    (0..succ_len).map(|index| Edge { source: bb, index: index}).collect()
+    mir[bb].terminator().successors().enumerate()
+        .map(|(index, _)| Edge { source: bb, index: index}).collect()
 }
 
 impl<'a, 'tcx, MWF, P> dot::Labeller<'a> for Graph<'a, 'tcx, MWF, P>
@@ -285,6 +285,6 @@ fn source(&self, edge: &Edge) -> Node {
 
     fn target(&self, edge: &Edge) -> Node {
         let mir = self.mbcx.mir();
-        mir[edge.source].terminator().successors()[edge.index]
+        *mir[edge.source].terminator().successors().nth(edge.index).unwrap()
     }
 }
index e6aa2d3abb7e025de7d3f76b01a8a3ef6f1e563c..5890ea5c9d0c653cc8d186986dbb1c4dd303ade1 100644 (file)
@@ -30,9 +30,9 @@
 use syntax::attr;
 use syntax::symbol::Symbol;
 use rustc::hir;
-use rustc_const_math::ConstFloat;
 use rustc_data_structures::sync::Lrc;
 use rustc::mir::interpret::{Value, PrimVal};
+use hair::pattern::parse_float;
 
 #[derive(Clone)]
 pub struct Cx<'a, 'gcx: 'a + 'tcx, 'tcx: 'a> {
@@ -170,12 +170,11 @@ pub fn const_eval_literal(
         neg: bool,
     ) -> Literal<'tcx> {
         trace!("const_eval_literal: {:#?}, {:?}, {:?}, {:?}", lit, ty, sp, neg);
-        let tcx = self.tcx.global_tcx();
 
-        let parse_float = |num: &str, fty| -> ConstFloat {
-            ConstFloat::from_str(num, fty).unwrap_or_else(|_| {
+        let parse_float = |num, fty| -> Value {
+            parse_float(num, fty, neg).unwrap_or_else(|_| {
                 // FIXME(#31407) this is only necessary because float parsing is buggy
-                tcx.sess.span_fatal(sp, "could not evaluate float literal (see issue #31407)");
+                self.tcx.sess.span_fatal(sp, "could not evaluate float literal (see issue #31407)");
             })
         };
 
@@ -213,26 +212,14 @@ pub fn const_eval_literal(
             },
             LitKind::Int(n, _) => Value::ByVal(PrimVal::Bytes(clamp(n))),
             LitKind::Float(n, fty) => {
-                let n = n.as_str();
-                let mut f = parse_float(&n, fty);
-                if neg {
-                    f = -f;
-                }
-                let bits = f.bits;
-                Value::ByVal(PrimVal::Bytes(bits))
+                parse_float(n, fty)
             }
             LitKind::FloatUnsuffixed(n) => {
                 let fty = match ty.sty {
                     ty::TyFloat(fty) => fty,
                     _ => bug!()
                 };
-                let n = n.as_str();
-                let mut f = parse_float(&n, fty);
-                if neg {
-                    f = -f;
-                }
-                let bits = f.bits;
-                Value::ByVal(PrimVal::Bytes(bits))
+                parse_float(n, fty)
             }
             LitKind::Bool(b) => Value::ByVal(PrimVal::Bytes(b as u128)),
             LitKind::Char(c) => Value::ByVal(PrimVal::Bytes(c as u128)),
index c2da8c11d87e9382339c0eda9e0990cb7a9479cd..623e0de478bcaf6979361d138b70674651fbdd36 100644 (file)
 use rustc::hir::pat_util::EnumerateAndAdjustIterator;
 
 use rustc_data_structures::indexed_vec::Idx;
-use rustc_const_math::ConstFloat;
 
 use std::cmp::Ordering;
 use std::fmt;
 use syntax::ast;
 use syntax::ptr::P;
 use syntax_pos::Span;
+use syntax_pos::symbol::Symbol;
 
 #[derive(Clone, Debug)]
 pub enum PatternError {
@@ -792,7 +792,7 @@ fn const_to_pat(
                 ConstVal::Value(miri) => const_val_field(
                     self.tcx, self.param_env, instance,
                     variant_opt, field, miri, cv.ty,
-                ).unwrap(),
+                ).expect("field access failed"),
                 _ => bug!("{:#?} is not a valid adt", cv),
             };
             self.const_to_pat(instance, val, id, span)
@@ -1053,24 +1053,22 @@ pub fn compare_const_vals<'a, 'tcx>(
     b: &ConstVal,
     ty: Ty<'tcx>,
 ) -> Option<Ordering> {
-    use rustc_const_math::ConstFloat;
     trace!("compare_const_vals: {:?}, {:?}", a, b);
     use rustc::mir::interpret::{Value, PrimVal};
     match (a, b) {
         (&ConstVal::Value(Value::ByVal(PrimVal::Bytes(a))),
          &ConstVal::Value(Value::ByVal(PrimVal::Bytes(b)))) => {
+            use ::rustc_apfloat::Float;
             match ty.sty {
-                ty::TyFloat(ty) => {
-                    let l = ConstFloat {
-                        bits: a,
-                        ty,
-                    };
-                    let r = ConstFloat {
-                        bits: b,
-                        ty,
-                    };
-                    // FIXME(oli-obk): report cmp errors?
-                    l.try_cmp(r).ok()
+                ty::TyFloat(ast::FloatTy::F32) => {
+                    let l = ::rustc_apfloat::ieee::Single::from_bits(a);
+                    let r = ::rustc_apfloat::ieee::Single::from_bits(b);
+                    l.partial_cmp(&r)
+                },
+                ty::TyFloat(ast::FloatTy::F64) => {
+                    let l = ::rustc_apfloat::ieee::Double::from_bits(a);
+                    let r = ::rustc_apfloat::ieee::Double::from_bits(b);
+                    l.partial_cmp(&r)
                 },
                 ty::TyInt(_) => {
                     let a = interpret::sign_extend(tcx, a, ty).expect("layout error for TyInt");
@@ -1148,26 +1146,14 @@ enum Int {
             Value::ByVal(PrimVal::Bytes(n))
         },
         LitKind::Float(n, fty) => {
-            let n = n.as_str();
-            let mut f = parse_float(&n, fty)?;
-            if neg {
-                f = -f;
-            }
-            let bits = f.bits;
-            Value::ByVal(PrimVal::Bytes(bits))
+            parse_float(n, fty, neg)?
         }
         LitKind::FloatUnsuffixed(n) => {
             let fty = match ty.sty {
                 ty::TyFloat(fty) => fty,
                 _ => bug!()
             };
-            let n = n.as_str();
-            let mut f = parse_float(&n, fty)?;
-            if neg {
-                f = -f;
-            }
-            let bits = f.bits;
-            Value::ByVal(PrimVal::Bytes(bits))
+            parse_float(n, fty, neg)?
         }
         LitKind::Bool(b) => Value::ByVal(PrimVal::Bytes(b as u128)),
         LitKind::Char(c) => Value::ByVal(PrimVal::Bytes(c as u128)),
@@ -1175,7 +1161,36 @@ enum Int {
     Ok(ConstVal::Value(lit))
 }
 
-fn parse_float<'tcx>(num: &str, fty: ast::FloatTy)
-                     -> Result<ConstFloat, ()> {
-    ConstFloat::from_str(num, fty).map_err(|_| ())
+pub fn parse_float(
+    num: Symbol,
+    fty: ast::FloatTy,
+    neg: bool,
+) -> Result<Value, ()> {
+    let num = num.as_str();
+    use rustc_apfloat::ieee::{Single, Double};
+    use rustc_apfloat::Float;
+    let bits = match fty {
+        ast::FloatTy::F32 => {
+            num.parse::<f32>().map_err(|_| ())?;
+            let mut f = num.parse::<Single>().unwrap_or_else(|e| {
+                panic!("apfloat::ieee::Single failed to parse `{}`: {:?}", num, e)
+            });
+            if neg {
+                f = -f;
+            }
+            f.to_bits()
+        }
+        ast::FloatTy::F64 => {
+            num.parse::<f64>().map_err(|_| ())?;
+            let mut f = num.parse::<Double>().unwrap_or_else(|e| {
+                panic!("apfloat::ieee::Single failed to parse `{}`: {:?}", num, e)
+            });
+            if neg {
+                f = -f;
+            }
+            f.to_bits()
+        }
+    };
+
+    Ok(Value::ByVal(PrimVal::Bytes(bits)))
 }
index e654142d2164c346d64655ff3e8dbb759abefd27..002b5eb187db31ce36c2467687574938bb39b7d2 100644 (file)
@@ -2,10 +2,9 @@
 use rustc::ty::layout::LayoutOf;
 use syntax::ast::{FloatTy, IntTy, UintTy};
 
-use rustc_const_math::ConstFloat;
+use rustc_apfloat::ieee::{Single, Double};
 use super::{EvalContext, Machine};
 use rustc::mir::interpret::{PrimVal, EvalResult, MemoryPointer, PointerArithmetic};
-use rustc_apfloat::ieee::{Single, Double};
 use rustc_apfloat::Float;
 
 impl<'a, 'mir, 'tcx, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M> {
@@ -50,8 +49,10 @@ fn cast_from_int(
                 Ok(PrimVal::Bytes(v))
             }
 
-            TyFloat(fty) if signed => Ok(PrimVal::Bytes(ConstFloat::from_i128(v as i128, fty).bits)),
-            TyFloat(fty) => Ok(PrimVal::Bytes(ConstFloat::from_u128(v, fty).bits)),
+            TyFloat(FloatTy::F32) if signed => Ok(PrimVal::Bytes(Single::from_i128(v as i128).value.to_bits())),
+            TyFloat(FloatTy::F64) if signed => Ok(PrimVal::Bytes(Double::from_i128(v as i128).value.to_bits())),
+            TyFloat(FloatTy::F32) => Ok(PrimVal::Bytes(Single::from_u128(v).value.to_bits())),
+            TyFloat(FloatTy::F64) => Ok(PrimVal::Bytes(Double::from_u128(v).value.to_bits())),
 
             TyChar if v as u8 as u128 == v => Ok(PrimVal::Bytes(v)),
             TyChar => err!(InvalidChar(v)),
index f6e9994b5da3f9f885bb59f9852ecb47087a810b..bea29b6926aa63c1b48b1c6a5266a75b809885d7 100644 (file)
@@ -513,7 +513,7 @@ pub(super) fn eval_rvalue_into_place(
                     // it emits in debug mode) is performance, but it doesn't cost us any performance in miri.
                     // If, however, the compiler ever starts transforming unchecked intrinsics into unchecked binops,
                     // we have to go back to just ignoring the overflow here.
-                    return err!(OverflowingMath);
+                    return err!(Overflow(bin_op));
                 }
             }
 
@@ -917,8 +917,8 @@ pub fn read_discriminant_value(
                 niche_start,
                 ..
             } => {
-                let variants_start = niche_variants.start as u128;
-                let variants_end = niche_variants.end as u128;
+                let variants_start = *niche_variants.start() as u128;
+                let variants_end = *niche_variants.end() as u128;
                 match raw_discr {
                     PrimVal::Ptr(_) => {
                         assert!(niche_start == 0);
@@ -984,7 +984,7 @@ pub fn write_discriminant_value(
                 if variant_index != dataful_variant {
                     let (niche_dest, niche) =
                         self.place_field(dest, mir::Field::new(0), layout)?;
-                    let niche_value = ((variant_index - niche_variants.start) as u128)
+                    let niche_value = ((variant_index - niche_variants.start()) as u128)
                         .wrapping_add(niche_start);
                     self.write_primval(niche_dest, PrimVal::Bytes(niche_value), niche.ty)?;
                 }
@@ -1340,9 +1340,7 @@ pub fn try_read_value(&self, ptr: Pointer, ptr_align: Align, ty: Ty<'tcx>) -> Ev
         use syntax::ast::FloatTy;
 
         let layout = self.layout_of(ty)?;
-        // do the strongest layout check of the two
-        let align = layout.align.max(ptr_align);
-        self.memory.check_align(ptr, align)?;
+        self.memory.check_align(ptr, ptr_align)?;
 
         if layout.size.bytes() == 0 {
             return Ok(Some(Value::ByVal(PrimVal::Undef)));
index dfc0c4a824a84293d1d63fd32a60840f356d4380..ef6deab04775049ac2dc23fd1c3fd4ee8f32121d 100644 (file)
@@ -1,9 +1,10 @@
 use rustc::mir;
 use rustc::ty::{self, Ty};
-use rustc_const_math::ConstFloat;
 use syntax::ast::FloatTy;
 use std::cmp::Ordering;
 use rustc::ty::layout::LayoutOf;
+use rustc_apfloat::ieee::{Double, Single};
+use rustc_apfloat::Float;
 
 use super::{EvalContext, Place, Machine, ValTy};
 
@@ -125,31 +126,6 @@ pub fn binary_op(
             return err!(Unimplemented(msg));
         }
 
-        let float_op = |op, l, r, ty| {
-            let l = ConstFloat {
-                bits: l,
-                ty,
-            };
-            let r = ConstFloat {
-                bits: r,
-                ty,
-            };
-            match op {
-                Eq => PrimVal::from_bool(l.try_cmp(r).unwrap() == Ordering::Equal),
-                Ne => PrimVal::from_bool(l.try_cmp(r).unwrap() != Ordering::Equal),
-                Lt => PrimVal::from_bool(l.try_cmp(r).unwrap() == Ordering::Less),
-                Le => PrimVal::from_bool(l.try_cmp(r).unwrap() != Ordering::Greater),
-                Gt => PrimVal::from_bool(l.try_cmp(r).unwrap() == Ordering::Greater),
-                Ge => PrimVal::from_bool(l.try_cmp(r).unwrap() != Ordering::Less),
-                Add => PrimVal::Bytes((l + r).unwrap().bits),
-                Sub => PrimVal::Bytes((l - r).unwrap().bits),
-                Mul => PrimVal::Bytes((l * r).unwrap().bits),
-                Div => PrimVal::Bytes((l / r).unwrap().bits),
-                Rem => PrimVal::Bytes((l % r).unwrap().bits),
-                _ => bug!("invalid float op: `{:?}`", op),
-            }
-        };
-
         if left_layout.abi.is_signed() {
             let op: Option<fn(&i128, &i128) -> bool> = match bin_op {
                 Lt => Some(i128::lt),
@@ -164,7 +140,8 @@ pub fn binary_op(
                 return Ok((PrimVal::from_bool(op(&l, &r)), false));
             }
             let op: Option<fn(i128, i128) -> (i128, bool)> = match bin_op {
-                Rem | Div if r == 0 => return Ok((PrimVal::Bytes(l), true)),
+                Div if r == 0 => return err!(DivisionByZero),
+                Rem if r == 0 => return err!(RemainderByZero),
                 Div => Some(i128::overflowing_div),
                 Rem => Some(i128::overflowing_rem),
                 Add => Some(i128::overflowing_add),
@@ -199,7 +176,31 @@ pub fn binary_op(
         }
 
         if let ty::TyFloat(fty) = left_ty.sty {
-            return Ok((float_op(bin_op, l, r, fty), false));
+            macro_rules! float_math {
+                ($ty:path) => {{
+                    let l = <$ty>::from_bits(l);
+                    let r = <$ty>::from_bits(r);
+                    let val = match bin_op {
+                        Eq => PrimVal::from_bool(l.partial_cmp(&r).unwrap_or(Ordering::Greater) == Ordering::Equal),
+                        Ne => PrimVal::from_bool(l.partial_cmp(&r).unwrap_or(Ordering::Greater) != Ordering::Equal),
+                        Lt => PrimVal::from_bool(l.partial_cmp(&r).unwrap_or(Ordering::Greater) == Ordering::Less),
+                        Le => PrimVal::from_bool(l.partial_cmp(&r).unwrap_or(Ordering::Greater) != Ordering::Greater),
+                        Gt => PrimVal::from_bool(l.partial_cmp(&r).unwrap_or(Ordering::Greater) == Ordering::Greater),
+                        Ge => PrimVal::from_bool(l.partial_cmp(&r).unwrap_or(Ordering::Greater) != Ordering::Less),
+                        Add => PrimVal::Bytes((l + r).value.to_bits()),
+                        Sub => PrimVal::Bytes((l - r).value.to_bits()),
+                        Mul => PrimVal::Bytes((l * r).value.to_bits()),
+                        Div => PrimVal::Bytes((l / r).value.to_bits()),
+                        Rem => PrimVal::Bytes((l % r).value.to_bits()),
+                        _ => bug!("invalid float op: `{:?}`", bin_op),
+                    };
+                    return Ok((val, false));
+                }};
+            }
+            match fty {
+                FloatTy::F32 => float_math!(Single),
+                FloatTy::F64 => float_math!(Double),
+            }
         }
 
         // only ints left
@@ -221,7 +222,8 @@ pub fn binary_op(
                     Add => u128::overflowing_add,
                     Sub => u128::overflowing_sub,
                     Mul => u128::overflowing_mul,
-                    Rem | Div if r == 0 => return Ok((PrimVal::Bytes(l), true)),
+                    Div if r == 0 => return err!(DivisionByZero),
+                    Rem if r == 0 => return err!(RemainderByZero),
                     Div => u128::overflowing_div,
                     Rem => u128::overflowing_rem,
                     _ => bug!(),
@@ -269,7 +271,7 @@ pub fn unary_op(
             (Neg, ty::TyFloat(FloatTy::F32)) => Single::to_bits(-Single::from_bits(bytes)),
             (Neg, ty::TyFloat(FloatTy::F64)) => Double::to_bits(-Double::from_bits(bytes)),
 
-            (Neg, _) if bytes == (1 << (size - 1)) => return err!(OverflowingMath),
+            (Neg, _) if bytes == (1 << (size - 1)) => return err!(OverflowNeg),
             (Neg, _) => (-(bytes as i128)) as u128,
         };
 
index aa80ee7af18fc306129d0df96b0f170b0c9547b4..0e0d91f472472d2583db5ea058e7ccfbbd132a8c 100644 (file)
@@ -148,23 +148,24 @@ pub(super) fn eval_terminator(
                 if expected == cond_val {
                     self.goto_block(target);
                 } else {
-                    use rustc::mir::AssertMessage::*;
+                    use rustc::mir::interpret::EvalErrorKind::*;
                     return match *msg {
                         BoundsCheck { ref len, ref index } => {
-                            let span = terminator.source_info.span;
                             let len = self.eval_operand_to_primval(len)
                                 .expect("can't eval len")
                                 .to_u64()?;
                             let index = self.eval_operand_to_primval(index)
                                 .expect("can't eval index")
                                 .to_u64()?;
-                            err!(ArrayIndexOutOfBounds(span, len, index))
-                        }
-                        Math(ref err) => {
-                            err!(Math(terminator.source_info.span, err.clone()))
+                            err!(BoundsCheck { len, index })
                         }
+                        Overflow(op) => Err(Overflow(op).into()),
+                        OverflowNeg => Err(OverflowNeg.into()),
+                        DivisionByZero => Err(DivisionByZero.into()),
+                        RemainderByZero => Err(RemainderByZero.into()),
                         GeneratorResumedAfterReturn |
                         GeneratorResumedAfterPanic => unimplemented!(),
+                        _ => bug!(),
                     };
                 }
             }
index 75b7a10097df4e0b5ac9f544b33134f067227b90..95cf3b8ddc6ceace3095a749d965e07a3b36344e 100644 (file)
@@ -31,7 +31,7 @@
 #![feature(range_contains)]
 #![feature(rustc_diagnostic_macros)]
 #![feature(nonzero)]
-#![feature(inclusive_range_fields)]
+#![feature(inclusive_range_methods)]
 #![feature(crate_visibility_modifier)]
 #![feature(never_type)]
 #![cfg_attr(stage0, feature(try_trait))]
@@ -50,8 +50,6 @@
 extern crate syntax;
 extern crate syntax_pos;
 extern crate rustc_target;
-extern crate rustc_const_math;
-extern crate core; // for NonZero
 extern crate log_settings;
 extern crate rustc_apfloat;
 extern crate byteorder;
index 47b2f430bc70e2b3c35c44ef75dacaa95d62ec7c..e1db216b6bbbcfad1b1d15a9a696d79cc3325674 100644 (file)
@@ -328,7 +328,7 @@ fn const_prop(
                         } else {
                             if overflow {
                                 use rustc::mir::interpret::EvalErrorKind;
-                                let mut err = EvalErrorKind::OverflowingMath.into();
+                                let mut err = EvalErrorKind::Overflow(op).into();
                                 ecx.report(&mut err, false, Some(span));
                                 return None;
                             }
@@ -478,12 +478,12 @@ fn visit_terminator_kind(
                         .hir
                         .as_local_node_id(self.source.def_id)
                         .expect("some part of a failing const eval must be local");
-                    use rustc::mir::AssertMessage::*;
+                    use rustc::mir::interpret::EvalErrorKind::*;
                     let msg = match msg {
-                        // Need proper const propagator for these
-                        GeneratorResumedAfterReturn |
-                        GeneratorResumedAfterPanic => return,
-                        Math(ref err) => err.description().to_owned(),
+                        Overflow(_) |
+                        OverflowNeg |
+                        DivisionByZero |
+                        RemainderByZero => msg.description().to_owned(),
                         BoundsCheck { ref len, ref index } => {
                             let len = self.eval_operand(len).expect("len must be const");
                             let len = match len.0 {
@@ -504,6 +504,8 @@ fn visit_terminator_kind(
                                 index,
                             )
                         },
+                        // Need proper const propagator for these
+                        _ => return,
                     };
                     self.tcx.lint_node(
                         ::rustc::lint::builtin::CONST_ERR,
index 95fe99a1bec9f6998fe210e03b92b12d7f37fca6..fba60c7e8dc275db03a1e7adff5c86091239f710 100644 (file)
@@ -29,7 +29,6 @@
 //! (non-mutating) use of `SRC`. These restrictions are conservative and may be relaxed in the
 //! future.
 
-use rustc::hir;
 use rustc::mir::{Constant, Local, LocalKind, Location, Place, Mir, Operand, Rvalue, StatementKind};
 use rustc::mir::visit::MutVisitor;
 use rustc::ty::TyCtxt;
 impl MirPass for CopyPropagation {
     fn run_pass<'a, 'tcx>(&self,
                           tcx: TyCtxt<'a, 'tcx, 'tcx>,
-                          source: MirSource,
+                          _source: MirSource,
                           mir: &mut Mir<'tcx>) {
-        // Don't run on constant MIR, because trans might not be able to
-        // evaluate the modified MIR.
-        // FIXME(eddyb) Remove check after miri is merged.
-        let id = tcx.hir.as_local_node_id(source.def_id).unwrap();
-        match (tcx.hir.body_owner_kind(id), source.promoted) {
-            (_, Some(_)) |
-            (hir::BodyOwnerKind::Const, _) |
-            (hir::BodyOwnerKind::Static(_), _) => return,
-
-            (hir::BodyOwnerKind::Fn, _) => {
-                if tcx.is_const_fn(source.def_id) {
-                    // Don't run on const functions, as, again, trans might not be able to evaluate
-                    // the optimized IR.
-                    return
-                }
-            }
-        }
-
         // We only run when the MIR optimization level is > 1.
         // This avoids a slow pass, and messing up debug info.
         if tcx.sess.opts.debugging_opts.mir_opt_level <= 1 {
index 503354ebc4ffd0e064c5f6926086cb8ffc880a7c..8b2b9ef7e814d3c3ecb1381f6117b0d7edf5c89a 100644 (file)
@@ -8,7 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use rustc::hir;
 use rustc::ty::TyCtxt;
 use rustc::mir::*;
 use rustc_data_structures::indexed_vec::Idx;
 impl MirPass for Deaggregator {
     fn run_pass<'a, 'tcx>(&self,
                           tcx: TyCtxt<'a, 'tcx, 'tcx>,
-                          source: MirSource,
+                          _source: MirSource,
                           mir: &mut Mir<'tcx>) {
-        // Don't run on constant MIR, because trans might not be able to
-        // evaluate the modified MIR.
-        // FIXME(eddyb) Remove check after miri is merged.
-        let id = tcx.hir.as_local_node_id(source.def_id).unwrap();
-        match (tcx.hir.body_owner_kind(id), source.promoted) {
-            (_, Some(_)) |
-            (hir::BodyOwnerKind::Const, _) |
-            (hir::BodyOwnerKind::Static(_), _) => return,
-
-            (hir::BodyOwnerKind::Fn, _) => {
-                if tcx.is_const_fn(source.def_id) {
-                    // Don't run on const functions, as, again, trans might not be able to evaluate
-                    // the optimized IR.
-                    return
-                }
-            }
-        }
-
         let (basic_blocks, local_decls) = mir.basic_blocks_and_local_decls_mut();
         let local_decls = &*local_decls;
         for bb in basic_blocks {
index f63a5ef301a6815bd1769c64c779a9e37eeea8db..8b771fcf4936b22cb3e463fbdcb88b4c93ea7c68 100644 (file)
@@ -15,7 +15,6 @@
 use dataflow::{drop_flag_effects_for_location, on_lookup_result_bits};
 use dataflow::MoveDataParamEnv;
 use dataflow::{self, do_dataflow, DebugFormatted};
-use rustc::hir;
 use rustc::ty::{self, TyCtxt};
 use rustc::mir::*;
 use rustc::middle::const_val::ConstVal;
@@ -42,14 +41,7 @@ fn run_pass<'a, 'tcx>(&self,
     {
         debug!("elaborate_drops({:?} @ {:?})", src, mir.span);
 
-        // Don't run on constant MIR, because trans might not be able to
-        // evaluate the modified MIR.
-        // FIXME(eddyb) Remove check after miri is merged.
         let id = tcx.hir.as_local_node_id(src.def_id).unwrap();
-        match (tcx.hir.body_owner_kind(id), src.promoted) {
-            (hir::BodyOwnerKind::Fn, None) => {},
-            _ => return
-        }
         let param_env = tcx.param_env(src.def_id).with_reveal_all();
         let move_data = MoveData::gather_moves(mir, tcx).unwrap();
         let elaborate_patch = {
index 0ff735694338808f6af2b7007c2589426432b53e..36735586e81175f950deb1e646fcce86d02655c4 100644 (file)
@@ -738,12 +738,17 @@ fn create_generator_resume_function<'a, 'tcx>(
 
     let mut cases = create_cases(mir, &transform, |point| Some(point.resume));
 
+    use rustc::mir::interpret::EvalErrorKind::{
+        GeneratorResumedAfterPanic,
+        GeneratorResumedAfterReturn,
+    };
+
     // Jump to the entry point on the 0 state
     cases.insert(0, (0, BasicBlock::new(0)));
     // Panic when resumed on the returned (1) state
-    cases.insert(1, (1, insert_panic_block(tcx, mir, AssertMessage::GeneratorResumedAfterReturn)));
+    cases.insert(1, (1, insert_panic_block(tcx, mir, GeneratorResumedAfterReturn)));
     // Panic when resumed on the poisoned (2) state
-    cases.insert(2, (2, insert_panic_block(tcx, mir, AssertMessage::GeneratorResumedAfterPanic)));
+    cases.insert(2, (2, insert_panic_block(tcx, mir, GeneratorResumedAfterPanic)));
 
     insert_switch(tcx, mir, cases, &transform, TerminatorKind::Unreachable);
 
index 2e2f84941462826346cce5ece5b4220a3d9e6eef..ee6d42b1fe542fec83a961b49d02279fc2d840e4 100644 (file)
@@ -330,7 +330,7 @@ fn should_inline(&self,
             }
 
             if !is_drop {
-                for &succ in &term.successors()[..] {
+                for &succ in term.successors() {
                     work_list.push(succ);
                 }
             }
index 6d365012525f612833d4c47454071059d9fc1bfb..bcc8fef18f013362135bb6b2162a00907215609d 100644 (file)
@@ -78,7 +78,7 @@ fn is_nop_landing_pad(&self, bb: BasicBlock, mir: &Mir, nop_landing_pads: &BitVe
             TerminatorKind::SwitchInt { .. } |
             TerminatorKind::FalseEdges { .. } |
             TerminatorKind::FalseUnwind { .. } => {
-                terminator.successors().iter().all(|succ| {
+                terminator.successors().all(|succ| {
                     nop_landing_pads.contains(succ.index())
                 })
             },
index 2c6ed1f19b7fded5e96e3d3538d10bb0961598fb..691fdd130e551f611237970ec47cca9976d00545 100644 (file)
@@ -91,7 +91,7 @@ pub fn new(mir: &'a mut Mir<'tcx>) -> Self {
 
         for (_, data) in traversal::preorder(mir) {
             if let Some(ref term) = data.terminator {
-                for &tgt in term.successors().iter() {
+                for &tgt in term.successors() {
                     pred_count[tgt] += 1;
                 }
             }
@@ -219,10 +219,10 @@ fn simplify_branch(&mut self, terminator: &mut Terminator<'tcx>) -> bool {
         };
 
         let first_succ = {
-            let successors = terminator.successors();
-            if let Some(&first_succ) = terminator.successors().get(0) {
-                if successors.iter().all(|s| *s == first_succ) {
-                    self.pred_count[first_succ] -= (successors.len()-1) as u32;
+            if let Some(&first_succ) = terminator.successors().nth(0) {
+                if terminator.successors().all(|s| *s == first_succ) {
+                    let count = terminator.successors().count();
+                    self.pred_count[first_succ] -= (count - 1) as u32;
                     first_succ
                 } else {
                     return false
index 85b66c29be1ad99721c08302ca4c6325996b64c4..22e2b1b0b09c9945d6a313d9f7f764502e9f3472 100644 (file)
@@ -125,7 +125,7 @@ fn write_edges<W: Write>(source: BasicBlock, mir: &Mir, w: &mut W) -> io::Result
     let terminator = mir[source].terminator();
     let labels = terminator.kind.fmt_successor_labels();
 
-    for (&target, label) in terminator.successors().iter().zip(labels) {
+    for (&target, label) in terminator.successors().zip(labels) {
         writeln!(w, r#"    {} -> {} [label="{}"];"#, node(source), node(target), label)?;
     }
 
index 42ddabddd2dcd8e5dcec6d311fd8d339b578dbed..cfb1a2cd28bcc1a115322cc3555a5632edcf915f 100644 (file)
@@ -138,7 +138,7 @@ pub fn liveness_of_locals<'tcx>(mir: &Mir<'tcx>, mode: LivenessMode) -> Liveness
         for b in mir.basic_blocks().indices().rev() {
             // outs[b] = ∪ {ins of successors}
             bits.clear();
-            for &successor in mir.basic_blocks()[b].terminator().successors().into_iter() {
+            for &successor in mir.basic_blocks()[b].terminator().successors() {
                 bits.union(&ins[successor]);
             }
             outs[b].clone_from(&bits);
index 4bab24ae1392c1198fc1c8dba27ce64607ebfea6..2babb93eedbcfb68732f7b1c821bb6a1bdf15a49 100644 (file)
@@ -12,7 +12,6 @@ crate-type = ["dylib"]
 log = "0.4"
 rustc = { path = "../librustc" }
 rustc_mir = { path = "../librustc_mir"}
-rustc_const_math = { path = "../librustc_const_math" }
 rustc_data_structures = { path = "../librustc_data_structures" }
 syntax = { path = "../libsyntax" }
 syntax_pos = { path = "../libsyntax_pos" }
index e65c9de8df1eaf1dbf3277cde693fcf5e5ca79ee..b6b5edc094003c2215a26cf031804c650bf865d5 100644 (file)
@@ -23,7 +23,6 @@
 #[macro_use]
 extern crate rustc;
 extern crate rustc_mir;
-extern crate rustc_const_math;
 extern crate rustc_data_structures;
 
 #[macro_use]
index a4e056c6b589ee3841d7779acb05186745337a44..45c6e89321d044934c0073ba092fbf951406e9ae 100644 (file)
@@ -18,6 +18,7 @@
 use rustc::mir::{Mir, Operand, ProjectionElem};
 use rustc::mir::{Rvalue, SourceInfo, Statement, StatementKind};
 use rustc::mir::{Terminator, TerminatorKind, VisibilityScope, VisibilityScopeData};
+use rustc::mir::interpret::EvalErrorKind;
 use rustc::mir::visit as mir_visit;
 use rustc::ty::{self, ClosureSubsts, TyCtxt};
 use rustc::util::nodemap::{FxHashMap};
@@ -133,14 +134,18 @@ fn visit_assert_message(&mut self,
                             location: Location) {
         self.record("AssertMessage", msg);
         self.record(match *msg {
-            AssertMessage::BoundsCheck { .. } => "AssertMessage::BoundsCheck",
-            AssertMessage::Math(..) => "AssertMessage::Math",
-            AssertMessage::GeneratorResumedAfterReturn => {
+            EvalErrorKind::BoundsCheck { .. } => "AssertMessage::BoundsCheck",
+            EvalErrorKind::Overflow(..) => "AssertMessage::Overflow",
+            EvalErrorKind::OverflowNeg => "AssertMessage::OverflowNeg",
+            EvalErrorKind::DivisionByZero => "AssertMessage::DivisionByZero",
+            EvalErrorKind::RemainderByZero => "AssertMessage::RemainderByZero",
+            EvalErrorKind::GeneratorResumedAfterReturn => {
                 "AssertMessage::GeneratorResumedAfterReturn"
             }
-            AssertMessage::GeneratorResumedAfterPanic => {
+            EvalErrorKind::GeneratorResumedAfterPanic => {
                 "AssertMessage::GeneratorResumedAfterPanic"
             }
+            _ => bug!(),
         }, msg);
         self.super_assert_message(msg, location);
     }
index 14ceb5f59a3ec60b429bbb9e529bd2aa5bb6ccc7..ef5cc95828372f46f5499c65913324a001a3b11f 100644 (file)
@@ -17,7 +17,7 @@
 use resolve_imports::ImportDirective;
 use resolve_imports::ImportDirectiveSubclass::{self, GlobImport, SingleImport};
 use {Module, ModuleData, ModuleKind, NameBinding, NameBindingKind, ToNameBinding};
-use {Resolver, ResolverArenas};
+use {PerNS, Resolver, ResolverArenas};
 use Namespace::{self, TypeNS, ValueNS, MacroNS};
 use {resolve_error, resolve_struct_error, ResolutionError};
 
@@ -71,7 +71,6 @@ fn to_name_binding(self, arenas: &'a ResolverArenas<'a>) -> &'a NameBinding<'a>
 struct LegacyMacroImports {
     import_all: Option<Span>,
     imports: Vec<(Name, Span)>,
-    reexports: Vec<(Name, Span)>,
 }
 
 impl<'a> Resolver<'a> {
@@ -175,7 +174,11 @@ fn build_reduced_graph_for_use_tree(&mut self,
                 let subclass = SingleImport {
                     target: ident,
                     source,
-                    result: self.per_ns(|_, _| Cell::new(Err(Undetermined))),
+                    result: PerNS {
+                        type_ns: Cell::new(Err(Undetermined)),
+                        value_ns: Cell::new(Err(Undetermined)),
+                        macro_ns: Cell::new(Err(Undetermined)),
+                    },
                     type_ns_only,
                 };
                 self.add_import_directive(
@@ -621,7 +624,7 @@ fn process_legacy_macro_imports(&mut self, item: &Item, module: Module<'a>, expa
         let legacy_imports = self.legacy_macro_imports(&item.attrs);
         let mut used = legacy_imports != LegacyMacroImports::default();
 
-        // `#[macro_use]` and `#[macro_reexport]` are only allowed at the crate root.
+        // `#[macro_use]` is only allowed at the crate root.
         if self.current_module.parent.is_some() && used {
             span_err!(self.session, item.span, E0468,
                       "an `extern crate` loading macros must be at the crate root");
@@ -669,17 +672,6 @@ fn process_legacy_macro_imports(&mut self, item: &Item, module: Module<'a>, expa
                 }
             }
         }
-        for (name, span) in legacy_imports.reexports {
-            self.cstore.export_macros_untracked(module.def_id().unwrap().krate);
-            let ident = Ident::with_empty_ctxt(name);
-            let result = self.resolve_ident_in_module(module, ident, MacroNS, false, false, span);
-            if let Ok(binding) = result {
-                let (def, vis) = (binding.def(), binding.vis);
-                self.macro_exports.push(Export { ident, def, vis, span, is_import: true });
-            } else {
-                span_err!(self.session, span, E0470, "re-exported macro not found");
-            }
-        }
         used
     }
 
@@ -714,28 +706,13 @@ fn legacy_macro_imports(&mut self, attrs: &[ast::Attribute]) -> LegacyMacroImpor
                 match attr.meta_item_list() {
                     Some(names) => for attr in names {
                         if let Some(word) = attr.word() {
-                            imports.imports.push((word.ident.name, attr.span()));
+                            imports.imports.push((word.name(), attr.span()));
                         } else {
                             span_err!(self.session, attr.span(), E0466, "bad macro import");
                         }
                     },
                     None => imports.import_all = Some(attr.span),
                 }
-            } else if attr.check_name("macro_reexport") {
-                let bad_macro_reexport = |this: &mut Self, span| {
-                    span_err!(this.session, span, E0467, "bad macro re-export");
-                };
-                if let Some(names) = attr.meta_item_list() {
-                    for attr in names {
-                        if let Some(word) = attr.word() {
-                            imports.reexports.push((word.ident.name, attr.span()));
-                        } else {
-                            bad_macro_reexport(self, attr.span());
-                        }
-                    }
-                } else {
-                    bad_macro_reexport(self, attr.span());
-                }
             }
         }
         imports
index a0fc5533f8e5445ce7923538da20163bd9126f58..232a32deb864ea456b32657417a03bfe29512f06 100644 (file)
@@ -1395,35 +1395,6 @@ macro_rules! get_pimientos {
 arguments.
 "##,
 
-E0467: r##"
-Macro re-export declarations were empty or malformed.
-
-Erroneous code examples:
-
-```compile_fail,E0467
-#[macro_reexport]                    // error: no macros listed for export
-extern crate core as macros_for_good;
-
-#[macro_reexport(fun_macro = "foo")] // error: not a macro identifier
-extern crate core as other_macros_for_good;
-```
-
-This is a syntax error at the level of attribute declarations.
-
-Currently, `macro_reexport` requires at least one macro name to be listed.
-Unlike `macro_use`, listing no names does not re-export all macros from the
-given crate.
-
-Decide which macros you would like to export and list them properly.
-
-These are proper re-export declarations:
-
-```ignore (cannot-doctest-multicrate-project)
-#[macro_reexport(some_macro, another_macro)]
-extern crate macros_for_good;
-```
-"##,
-
 E0468: r##"
 A non-root module attempts to import macros from another crate.
 
@@ -1496,48 +1467,6 @@ macro_rules! drink {
 ```
 "##,
 
-E0470: r##"
-A macro listed for re-export was not found.
-
-Erroneous code example:
-
-```compile_fail,E0470
-#[macro_reexport(drink, be_merry)]
-extern crate alloc;
-
-fn main() {
-    // ...
-}
-```
-
-Either the listed macro is not contained in the imported crate, or it is not
-exported from the given crate.
-
-This could be caused by a typo. Did you misspell the macro's name?
-
-Double-check the names of the macros listed for re-export, and that the crate
-in question exports them.
-
-A working version:
-
-```ignore (cannot-doctest-multicrate-project)
-// In some_crate crate:
-#[macro_export]
-macro_rules! eat {
-    ...
-}
-
-#[macro_export]
-macro_rules! drink {
-    ...
-}
-
-// In your_crate:
-#[macro_reexport(eat, drink)]
-extern crate some_crate;
-```
-"##,
-
 E0530: r##"
 A binding shadowed something it shouldn't.
 
@@ -1715,6 +1644,8 @@ fn main() {
 //  E0421, merged into 531
     E0531, // unresolved pattern path kind `name`
 //  E0427, merged into 530
+//  E0467, removed
+//  E0470, removed
     E0573,
     E0574,
     E0575,
index 127331152c155a1612e2ad6215ac06a85a48242c..d4b212a15d82f9ba637f3337f9431303448e3a42 100644 (file)
@@ -700,7 +700,7 @@ pub enum Namespace {
 pub struct PerNS<T> {
     value_ns: T,
     type_ns: T,
-    macro_ns: Option<T>,
+    macro_ns: T,
 }
 
 impl<T> ::std::ops::Index<Namespace> for PerNS<T> {
@@ -709,7 +709,7 @@ fn index(&self, ns: Namespace) -> &T {
         match ns {
             ValueNS => &self.value_ns,
             TypeNS => &self.type_ns,
-            MacroNS => self.macro_ns.as_ref().unwrap(),
+            MacroNS => &self.macro_ns,
         }
     }
 }
@@ -719,7 +719,7 @@ fn index_mut(&mut self, ns: Namespace) -> &mut T {
         match ns {
             ValueNS => &mut self.value_ns,
             TypeNS => &mut self.type_ns,
-            MacroNS => self.macro_ns.as_mut().unwrap(),
+            MacroNS => &mut self.macro_ns,
         }
     }
 }
@@ -1407,6 +1407,7 @@ pub struct Resolver<'a> {
     graph_root: Module<'a>,
 
     prelude: Option<Module<'a>>,
+    extern_prelude: FxHashSet<Name>,
 
     /// n.b. This is used only for better diagnostics, not name resolution itself.
     has_self: FxHashSet<DefId>,
@@ -1715,6 +1716,7 @@ pub fn new(session: &'a Session,
             // AST.
             graph_root,
             prelude: None,
+            extern_prelude: session.opts.externs.iter().map(|kv| Symbol::intern(kv.0)).collect(),
 
             has_self: FxHashSet(),
             field_names: FxHashMap(),
@@ -1726,7 +1728,7 @@ pub fn new(session: &'a Session,
             ribs: PerNS {
                 value_ns: vec![Rib::new(ModuleRibKind(graph_root))],
                 type_ns: vec![Rib::new(ModuleRibKind(graph_root))],
-                macro_ns: Some(vec![Rib::new(ModuleRibKind(graph_root))]),
+                macro_ns: vec![Rib::new(ModuleRibKind(graph_root))],
             },
             label_ribs: Vec::new(),
 
@@ -1806,14 +1808,11 @@ pub fn arenas() -> ResolverArenas<'a> {
     }
 
     /// Runs the function on each namespace.
-    fn per_ns<T, F: FnMut(&mut Self, Namespace) -> T>(&mut self, mut f: F) -> PerNS<T> {
-        PerNS {
-            type_ns: f(self, TypeNS),
-            value_ns: f(self, ValueNS),
-            macro_ns: match self.use_extern_macros {
-                true => Some(f(self, MacroNS)),
-                false => None,
-            },
+    fn per_ns<F: FnMut(&mut Self, Namespace)>(&mut self, mut f: F) {
+        f(self, TypeNS);
+        f(self, ValueNS);
+        if self.use_extern_macros {
+            f(self, MacroNS);
         }
     }
 
@@ -1970,13 +1969,32 @@ fn resolve_ident_in_lexical_scope(&mut self,
             }
         }
 
-        match self.prelude {
-            Some(prelude) if !module.no_implicit_prelude => {
-                self.resolve_ident_in_module_unadjusted(prelude, ident, ns, false, false, path_span)
-                    .ok().map(LexicalScopeBinding::Item)
+        if !module.no_implicit_prelude {
+            // `record_used` means that we don't try to load crates during speculative resolution
+            if record_used && ns == TypeNS && self.extern_prelude.contains(&ident.name) {
+                if !self.session.features_untracked().extern_prelude {
+                    feature_err(&self.session.parse_sess, "extern_prelude",
+                                ident.span, GateIssue::Language,
+                                "access to extern crates through prelude is experimental").emit();
+                }
+
+                let crate_id = self.crate_loader.process_path_extern(ident.name, ident.span);
+                let crate_root = self.get_module(DefId { krate: crate_id, index: CRATE_DEF_INDEX });
+                self.populate_module_if_necessary(crate_root);
+
+                let binding = (crate_root, ty::Visibility::Public,
+                               ident.span, Mark::root()).to_name_binding(self.arenas);
+                return Some(LexicalScopeBinding::Item(binding));
+            }
+            if let Some(prelude) = self.prelude {
+                if let Ok(binding) = self.resolve_ident_in_module_unadjusted(prelude, ident, ns,
+                                                                        false, false, path_span) {
+                    return Some(LexicalScopeBinding::Item(binding));
+                }
             }
-            _ => None,
         }
+
+        None
     }
 
     fn hygienic_lexical_parent(&mut self, mut module: Module<'a>, span: &mut Span)
@@ -3587,8 +3605,9 @@ fn lookup_typo_candidate<FilterFn>(&mut self,
                         // We can see through blocks
                     } else {
                         // Items from the prelude
-                        if let Some(prelude) = self.prelude {
-                            if !module.no_implicit_prelude {
+                        if !module.no_implicit_prelude {
+                            names.extend(self.extern_prelude.iter().cloned());
+                            if let Some(prelude) = self.prelude {
                                 add_module_candidates(prelude, &mut names);
                             }
                         }
index 3d20f922ac03db4a3fe0a577d5dc5ee7a0832e26..4afc621ad8b3e2751c8d6cccd2daac8ef9c2e51b 100644 (file)
@@ -209,7 +209,7 @@ fn resolve_imports(&mut self) {
     fn find_legacy_attr_invoc(&mut self, attrs: &mut Vec<ast::Attribute>, allow_derive: bool)
                               -> Option<ast::Attribute> {
         for i in 0..attrs.len() {
-            let name = unwrap_or!(attrs[i].name(), continue);
+            let name = attrs[i].name();
 
             if self.session.plugin_attributes.borrow().iter()
                     .any(|&(ref attr_nm, _)| name == &**attr_nm) {
@@ -231,7 +231,7 @@ fn find_legacy_attr_invoc(&mut self, attrs: &mut Vec<ast::Attribute>, allow_deri
 
         // Check for legacy derives
         for i in 0..attrs.len() {
-            let name = unwrap_or!(attrs[i].name(), continue);
+            let name = attrs[i].name();
 
             if name == "derive" {
                 let result = attrs[i].parse_list(&self.session.parse_sess, |parser| {
index e2a7f5668d251b535cdf50f152441328a2b16b4f..17aa510b565e90805ea2ae54cd31d8b14f80f2ba 100644 (file)
@@ -33,7 +33,7 @@
 use syntax_pos::Span;
 
 use std::cell::{Cell, RefCell};
-use std::mem;
+use std::{mem, ptr};
 
 /// Contains data for specific types of import directives.
 #[derive(Clone, Debug)]
@@ -89,6 +89,8 @@ enum SingleImports<'a> {
     None,
     /// Only the given single import can define the name in the namespace.
     MaybeOne(&'a ImportDirective<'a>),
+    /// Only one of these two single imports can define the name in the namespace.
+    MaybeTwo(&'a ImportDirective<'a>, &'a ImportDirective<'a>),
     /// At least one single import will define the name in the namespace.
     AtLeastOne,
 }
@@ -101,21 +103,28 @@ fn default() -> Self {
 }
 
 impl<'a> SingleImports<'a> {
-    fn add_directive(&mut self, directive: &'a ImportDirective<'a>) {
+    fn add_directive(&mut self, directive: &'a ImportDirective<'a>, use_extern_macros: bool) {
         match *self {
             SingleImports::None => *self = SingleImports::MaybeOne(directive),
-            // If two single imports can define the name in the namespace, we can assume that at
-            // least one of them will define it since otherwise both would have to define only one
-            // namespace, leading to a duplicate error.
-            SingleImports::MaybeOne(_) => *self = SingleImports::AtLeastOne,
+            SingleImports::MaybeOne(directive_one) => *self = if use_extern_macros {
+                SingleImports::MaybeTwo(directive_one, directive)
+            } else {
+                SingleImports::AtLeastOne
+            },
+            // If three single imports can define the name in the namespace, we can assume that at
+            // least one of them will define it since otherwise we'd get duplicate errors in one of
+            // other namespaces.
+            SingleImports::MaybeTwo(..) => *self = SingleImports::AtLeastOne,
             SingleImports::AtLeastOne => {}
         };
     }
 
-    fn directive_failed(&mut self) {
+    fn directive_failed(&mut self, dir: &'a ImportDirective<'a>) {
         match *self {
             SingleImports::None => unreachable!(),
             SingleImports::MaybeOne(_) => *self = SingleImports::None,
+            SingleImports::MaybeTwo(dir1, dir2) =>
+                *self = SingleImports::MaybeOne(if ptr::eq(dir1, dir) { dir1 } else { dir2 }),
             SingleImports::AtLeastOne => {}
         }
     }
@@ -199,23 +208,50 @@ pub fn resolve_ident_in_module_unadjusted(&mut self,
         }
 
         // Check if a single import can still define the name.
+        let resolve_single_import = |this: &mut Self, directive: &'a ImportDirective<'a>| {
+            let module = match directive.imported_module.get() {
+                Some(module) => module,
+                None => return false,
+            };
+            let ident = match directive.subclass {
+                SingleImport { source, .. } => source,
+                _ => unreachable!(),
+            };
+            match this.resolve_ident_in_module(module, ident, ns, false, false, path_span) {
+                Err(Determined) => {}
+                _ => return false,
+            }
+            true
+        };
         match resolution.single_imports {
             SingleImports::AtLeastOne => return Err(Undetermined),
-            SingleImports::MaybeOne(directive) if self.is_accessible(directive.vis.get()) => {
-                let module = match directive.imported_module.get() {
-                    Some(module) => module,
-                    None => return Err(Undetermined),
-                };
-                let ident = match directive.subclass {
-                    SingleImport { source, .. } => source,
-                    _ => unreachable!(),
-                };
-                match self.resolve_ident_in_module(module, ident, ns, false, false, path_span) {
-                    Err(Determined) => {}
-                    _ => return Err(Undetermined),
+            SingleImports::MaybeOne(directive) => {
+                let accessible = self.is_accessible(directive.vis.get());
+                if accessible {
+                    if !resolve_single_import(self, directive) {
+                        return Err(Undetermined)
+                    }
+                }
+            }
+            SingleImports::MaybeTwo(directive1, directive2) => {
+                let accessible1 = self.is_accessible(directive1.vis.get());
+                let accessible2 = self.is_accessible(directive2.vis.get());
+                if accessible1 && accessible2 {
+                    if !resolve_single_import(self, directive1) &&
+                       !resolve_single_import(self, directive2) {
+                        return Err(Undetermined)
+                    }
+                } else if accessible1 {
+                    if !resolve_single_import(self, directive1) {
+                        return Err(Undetermined)
+                    }
+                } else {
+                    if !resolve_single_import(self, directive2) {
+                        return Err(Undetermined)
+                    }
                 }
             }
-            SingleImports::MaybeOne(_) | SingleImports::None => {},
+            SingleImports::None => {},
         }
 
         let no_unresolved_invocations =
@@ -281,7 +317,7 @@ pub fn add_import_directive(&mut self,
             SingleImport { target, .. } => {
                 self.per_ns(|this, ns| {
                     let mut resolution = this.resolution(current_module, target, ns).borrow_mut();
-                    resolution.single_imports.add_directive(directive);
+                    resolution.single_imports.add_directive(directive, this.use_extern_macros);
                 });
             }
             // We don't add prelude imports to the globs since they only affect lexical scopes,
@@ -575,7 +611,7 @@ fn resolve_import(&mut self, directive: &'b ImportDirective<'b>) -> bool {
                 Err(Undetermined) => indeterminate = true,
                 Err(Determined) => {
                     this.update_resolution(parent, target, ns, |_, resolution| {
-                        resolution.single_imports.directive_failed()
+                        resolution.single_imports.directive_failed(directive)
                     });
                 }
                 Ok(binding) if !binding.is_importable() => {
index 346e5667a7babbd3613d320c51e5009c62cbb77f..fd1f779f9ecc06168ee635e11907d2b576ed2dda 100644 (file)
@@ -326,9 +326,9 @@ fn add_assign(&mut self, other: Size) {
 }
 
 /// Alignment of a type in bytes, both ABI-mandated and preferred.
-/// Each field is a power of two, giving the alignment a maximum value of
-/// 2<sup>(2<sup>8</sup> - 1)</sup>, which is limited by LLVM to a i32,
-/// with a maximum capacity of 2<sup>31</sup> - 1 or 2147483647.
+/// Each field is a power of two, giving the alignment a maximum value
+/// of 2<sup>(2<sup>8</sup> - 1)</sup>, which is limited by LLVM to a
+/// maximum capacity of 2<sup>29</sup> or 536870912.
 #[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, RustcEncodable, RustcDecodable)]
 pub struct Align {
     abi_pow2: u8,
@@ -356,7 +356,7 @@ pub fn from_bytes(abi: u64, pref: u64) -> Result<Align, String> {
             }
             if bytes != 1 {
                 Err(format!("`{}` is not a power of 2", align))
-            } else if pow > 30 {
+            } else if pow > 29 {
                 Err(format!("`{}` is too large", align))
             } else {
                 Ok(pow)
@@ -555,8 +555,8 @@ pub fn valid_range_exclusive<C: HasDataLayout>(&self, cx: C) -> Range<u128> {
         let bits = self.value.size(cx).bits();
         assert!(bits <= 128);
         let mask = !0u128 >> (128 - bits);
-        let start = self.valid_range.start;
-        let end = self.valid_range.end;
+        let start = *self.valid_range.start();
+        let end = *self.valid_range.end();
         assert_eq!(start, start & mask);
         assert_eq!(end, end & mask);
         start..(end.wrapping_add(1) & mask)
index 927d5c7e15a20c5f30684311fbd24450411977a2..45f2ee13bbdc94e29f5e5922564f24314351d1ff 100644 (file)
@@ -29,7 +29,7 @@
 #![feature(const_fn)]
 #![feature(fs_read_write)]
 #![feature(inclusive_range)]
-#![feature(inclusive_range_fields)]
+#![feature(inclusive_range_methods)]
 #![feature(slice_patterns)]
 
 #[macro_use]
index acbbab313fe593da6b77d0b164ad07cad2944348..46bb01e7c420dfe1f92a90dd8cdeb94022d45509 100644 (file)
@@ -98,6 +98,7 @@ pub fn opts(arch: Arch) -> Result<TargetOptions, String> {
         executables: true,
         pre_link_args,
         has_elf_tls: false,
+        eliminate_frame_pointer: false,
         // The following line is a workaround for jemalloc 4.5 being broken on
         // ios. jemalloc 5.0 is supposed to fix this.
         // see https://github.com/rust-lang/rust/issues/45262
index 06ea1e4649b4240a5f7ff02cad19c9ac7075a170..d17789dfcc07feb929e520e26038d99774a56668 100644 (file)
@@ -16,6 +16,7 @@ pub fn target() -> TargetResult {
     base.max_atomic_width = Some(64);
     base.pre_link_args.insert(LinkerFlavor::Gcc, vec!["-m32".to_string()]);
     base.stack_probes = true;
+    base.eliminate_frame_pointer = false;
 
     Ok(Target {
         llvm_target: "i686-apple-darwin".to_string(),
index 5f4daf0d568f82c397f3c8aaaa4f63fc3d52472b..ba31ce2692fbcabe38a67fcd0b3f3821d102d5e8 100644 (file)
@@ -193,14 +193,38 @@ fn dtorck_constraint_for_ty<'a, 'gcx, 'tcx>(
             .map(|ty| dtorck_constraint_for_ty(tcx, span, for_ty, depth + 1, ty))
             .collect(),
 
-        ty::TyGenerator(def_id, substs, _) => {
-            // Note that the interior types are ignored here.
-            // Any type reachable inside the interior must also be reachable
-            // through the upvars.
-            substs
-                .upvar_tys(def_id, tcx)
-                .map(|ty| dtorck_constraint_for_ty(tcx, span, for_ty, depth + 1, ty))
-                .collect()
+        ty::TyGenerator(def_id, substs, _interior) => {
+            // rust-lang/rust#49918: types can be constructed, stored
+            // in the interior, and sit idle when generator yields
+            // (and is subsequently dropped).
+            //
+            // It would be nice to descend into interior of a
+            // generator to determine what effects dropping it might
+            // have (by looking at any drop effects associated with
+            // its interior).
+            //
+            // However, the interior's representation uses things like
+            // TyGeneratorWitness that explicitly assume they are not
+            // traversed in such a manner. So instead, we will
+            // simplify things for now by treating all generators as
+            // if they were like trait objects, where its upvars must
+            // all be alive for the generator's (potential)
+            // destructor.
+            //
+            // In particular, skipping over `_interior` is safe
+            // because any side-effects from dropping `_interior` can
+            // only take place through references with lifetimes
+            // derived from lifetimes attached to the upvars, and we
+            // *do* incorporate the upvars here.
+
+            let constraint = DtorckConstraint {
+                outlives: substs.upvar_tys(def_id, tcx).map(|t| t.into()).collect(),
+                dtorck_types: vec![],
+                overflows: vec![],
+            };
+            debug!("dtorck_constraint: generator {:?} => {:?}", def_id, constraint);
+
+            Ok(constraint)
         }
 
         ty::TyAdt(def, substs) => {
index 32432d6cc835de89d17b6441fa935e3ac9795df2..a4dd02e97b233573d417e789950265498e4b4634 100644 (file)
@@ -21,7 +21,6 @@ rustc-demangle = "0.1.4"
 rustc_allocator = { path = "../librustc_allocator" }
 rustc_apfloat = { path = "../librustc_apfloat" }
 rustc_target = { path = "../librustc_target" }
-rustc_const_math = { path = "../librustc_const_math" }
 rustc_data_structures = { path = "../librustc_data_structures" }
 rustc_errors = { path = "../librustc_errors" }
 rustc_incremental = { path = "../librustc_incremental" }
index 1d0d7ec601f1f96a9ad9fc12db4f2c14f6b7d481..1838dae049ad7e1a18cb205ed7ce6648900e4ae0 100644 (file)
@@ -388,8 +388,8 @@ fn unadjusted(cx: &CodegenCx<'a, 'tcx>,
                 return;
             }
 
-            if scalar.valid_range.start < scalar.valid_range.end {
-                if scalar.valid_range.start > 0 {
+            if scalar.valid_range.start() < scalar.valid_range.end() {
+                if *scalar.valid_range.start() > 0 {
                     attrs.set(ArgAttribute::NonNull);
                 }
             }
index f455c19cc0bbef36b947226ff48e4cbd8e9c272f..5baed57092d0f3c243605d666bce3a650281dbf6 100644 (file)
@@ -69,8 +69,6 @@ pub fn naked(val: ValueRef, is_naked: bool) {
 }
 
 pub fn set_frame_pointer_elimination(cx: &CodegenCx, llfn: ValueRef) {
-    // FIXME: #11906: Omitting frame pointers breaks retrieving the value of a
-    // parameter.
     if cx.sess().must_not_eliminate_frame_pointers() {
         llvm::AddFunctionAttrStringValue(
             llfn, llvm::AttributePlace::Function,
index 123b9cf7931a58a1aae89fd4e0d3fdc454105e44..2fc6c9d4433016f74613225759412724916744cd 100644 (file)
@@ -1236,7 +1236,7 @@ fn compute_field_path<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>,
                                    self.layout,
                                    self.layout.fields.offset(0),
                                    self.layout.field(cx, 0).size);
-                name.push_str(&adt.variants[niche_variants.start].name.as_str());
+                name.push_str(&adt.variants[*niche_variants.start()].name.as_str());
 
                 // Create the (singleton) list of descriptions of union members.
                 vec![
index 193db15303f97251d2813c2f5d48a48a82490348..30676b91620a62c27e7d60e03bbcfcd6f7a114f3 100644 (file)
@@ -271,7 +271,7 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>,
         }
         None => {}
     };
-    if sig.output().is_never() {
+    if cx.layout_of(sig.output()).abi == ty::layout::Abi::Uninhabited {
         flags = flags | DIFlags::FlagNoReturn;
     }
 
index bbe4e18b18cb1fd9ab3d175ad838341d36107df4..97721ffbf06854e627550e92b1351a21bd3bd12a 100644 (file)
@@ -23,6 +23,7 @@
 use llvm::{self, ValueRef};
 use llvm::AttributePlace::Function;
 use rustc::ty::{self, Ty};
+use rustc::ty::layout::{self, LayoutOf};
 use rustc::session::config::Sanitizer;
 use rustc_target::spec::PanicStrategy;
 use abi::{Abi, FnType, FnTypeExt};
@@ -133,8 +134,7 @@ pub fn declare_fn<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, name: &str,
     let fty = FnType::new(cx, sig, &[]);
     let llfn = declare_raw_fn(cx, name, fty.llvm_cconv(), fty.llvm_type(cx));
 
-    // FIXME(canndrew): This is_never should really be an is_uninhabited
-    if sig.output().is_never() {
+    if cx.layout_of(sig.output()).abi == layout::Abi::Uninhabited {
         llvm::Attribute::NoReturn.apply_llfn(Function, llfn);
     }
 
index 96a10e8b99d32272c48fa189fa0bc207becc2f8f..7a152d6ded4c56ecc957f4d6ce7c40d5a1a31c31 100644 (file)
@@ -29,7 +29,7 @@
 #![feature(rustc_diagnostic_macros)]
 #![feature(slice_sort_by_cached_key)]
 #![feature(optin_builtin_traits)]
-#![feature(inclusive_range_fields)]
+#![feature(inclusive_range_methods)]
 
 use rustc::dep_graph::WorkProduct;
 use syntax_pos::symbol::Symbol;
@@ -43,7 +43,6 @@
 extern crate rustc_allocator;
 extern crate rustc_apfloat;
 extern crate rustc_target;
-extern crate rustc_const_math;
 #[macro_use] extern crate rustc_data_structures;
 extern crate rustc_demangle;
 extern crate rustc_incremental;
index 0fe7163da7a02d2457b1b37d1f3cb3feb433def2..9e5298eb736a33e18c7d97710f1739fa3b925ebc 100644 (file)
@@ -322,7 +322,7 @@ fn propagate<'tcx>(result: &mut IndexVec<mir::BasicBlock, CleanupKind>,
             debug!("cleanup_kinds: {:?}/{:?}/{:?} propagating funclet {:?}",
                    bb, data, result[bb], funclet);
 
-            for &succ in data.terminator().successors().iter() {
+            for &succ in data.terminator().successors() {
                 let kind = result[succ];
                 debug!("cleanup_kinds: propagating {:?} to {:?}/{:?}",
                        funclet, succ, kind);
index e5fdc26eeaf0d335ae8bb860b9b587ae2cf76001..b666c2b211525713e762126a5a437160a7ca787b 100644 (file)
@@ -13,6 +13,7 @@
 use rustc::ty::{self, Ty, TypeFoldable};
 use rustc::ty::layout::{self, LayoutOf};
 use rustc::mir;
+use rustc::mir::interpret::EvalErrorKind;
 use abi::{Abi, ArgType, ArgTypeExt, FnType, FnTypeExt, LlvmType, PassMode};
 use base;
 use callee;
@@ -311,10 +312,7 @@ fn trans_terminator(&mut self,
                 // checked operation, just a comparison with the minimum
                 // value, so we have to check for the assert message.
                 if !bx.cx.check_overflow {
-                    use rustc_const_math::ConstMathErr::Overflow;
-                    use rustc_const_math::Op::Neg;
-
-                    if let mir::AssertMessage::Math(Overflow(Neg)) = *msg {
+                    if let mir::interpret::EvalErrorKind::OverflowNeg = *msg {
                         const_cond = Some(expected);
                     }
                 }
@@ -354,7 +352,7 @@ fn trans_terminator(&mut self,
 
                 // Put together the arguments to the panic entry point.
                 let (lang_item, args) = match *msg {
-                    mir::AssertMessage::BoundsCheck { ref len, ref index } => {
+                    EvalErrorKind::BoundsCheck { ref len, ref index } => {
                         let len = self.trans_operand(&mut bx, len).immediate();
                         let index = self.trans_operand(&mut bx, index).immediate();
 
@@ -366,26 +364,8 @@ fn trans_terminator(&mut self,
                         (lang_items::PanicBoundsCheckFnLangItem,
                          vec![file_line_col, index, len])
                     }
-                    mir::AssertMessage::Math(ref err) => {
-                        let msg_str = Symbol::intern(err.description()).as_str();
-                        let msg_str = C_str_slice(bx.cx, msg_str);
-                        let msg_file_line_col = C_struct(bx.cx,
-                                                     &[msg_str, filename, line, col],
-                                                     false);
-                        let msg_file_line_col = consts::addr_of(bx.cx,
-                                                                msg_file_line_col,
-                                                                align,
-                                                                "panic_loc");
-                        (lang_items::PanicFnLangItem,
-                         vec![msg_file_line_col])
-                    }
-                    mir::AssertMessage::GeneratorResumedAfterReturn |
-                    mir::AssertMessage::GeneratorResumedAfterPanic => {
-                        let str = if let mir::AssertMessage::GeneratorResumedAfterReturn = *msg {
-                            "generator resumed after completion"
-                        } else {
-                            "generator resumed after panicking"
-                        };
+                    _ => {
+                        let str = msg.description();
                         let msg_str = Symbol::intern(str).as_str();
                         let msg_str = C_str_slice(bx.cx, msg_str);
                         let msg_file_line_col = C_struct(bx.cx,
index 8532c0b149dedcb67fdf4745d527161821b54547..79859aee64d874dfddbbb6333e6521d65bf6eaf7 100644 (file)
@@ -99,7 +99,7 @@ pub fn load(&self, bx: &Builder<'a, 'tcx>) -> OperandRef<'tcx> {
                         bx.range_metadata(load, range);
                     }
                 }
-                layout::Pointer if vr.start < vr.end && !vr.contains(&0) => {
+                layout::Pointer if vr.start() < vr.end() && !vr.contains(&0) => {
                     bx.nonnull_metadata(load);
                 }
                 _ => {}
@@ -287,7 +287,7 @@ pub fn trans_get_discr(self, bx: &Builder<'a, 'tcx>, cast_to: Ty<'tcx>) -> Value
                 ..
             } => {
                 let niche_llty = discr.layout.immediate_llvm_type(bx.cx);
-                if niche_variants.start == niche_variants.end {
+                if niche_variants.start() == niche_variants.end() {
                     // FIXME(eddyb) Check the actual primitive type here.
                     let niche_llval = if niche_start == 0 {
                         // HACK(eddyb) Using `C_null` as it works on all types.
@@ -296,13 +296,13 @@ pub fn trans_get_discr(self, bx: &Builder<'a, 'tcx>, cast_to: Ty<'tcx>) -> Value
                         C_uint_big(niche_llty, niche_start)
                     };
                     bx.select(bx.icmp(llvm::IntEQ, lldiscr, niche_llval),
-                        C_uint(cast_to, niche_variants.start as u64),
+                        C_uint(cast_to, *niche_variants.start() as u64),
                         C_uint(cast_to, dataful_variant as u64))
                 } else {
                     // Rebase from niche values to discriminant values.
-                    let delta = niche_start.wrapping_sub(niche_variants.start as u128);
+                    let delta = niche_start.wrapping_sub(*niche_variants.start() as u128);
                     let lldiscr = bx.sub(lldiscr, C_uint_big(niche_llty, delta));
-                    let lldiscr_max = C_uint(niche_llty, niche_variants.end as u64);
+                    let lldiscr_max = C_uint(niche_llty, *niche_variants.end() as u64);
                     bx.select(bx.icmp(llvm::IntULE, lldiscr, lldiscr_max),
                         bx.intcast(lldiscr, cast_to, false),
                         C_uint(cast_to, dataful_variant as u64))
@@ -352,7 +352,7 @@ pub fn trans_set_discr(&self, bx: &Builder<'a, 'tcx>, variant_index: usize) {
 
                     let niche = self.project_field(bx, 0);
                     let niche_llty = niche.layout.immediate_llvm_type(bx.cx);
-                    let niche_value = ((variant_index - niche_variants.start) as u128)
+                    let niche_value = ((variant_index - *niche_variants.start()) as u128)
                         .wrapping_add(niche_start);
                     // FIXME(eddyb) Check the actual primitive type here.
                     let niche_llval = if niche_value == 0 {
index 79e906ca975fbbc8e06ee46561fd61d4f2487c3e..0cd823391b9b66ed4dd6872afb2f56d6ce51f0bc 100644 (file)
@@ -15,7 +15,6 @@
 use rustc::mir;
 use rustc::middle::lang_items::ExchangeMallocFnLangItem;
 use rustc_apfloat::{ieee, Float, Status, Round};
-use rustc_const_math::MAX_F32_PLUS_HALF_ULP;
 use std::{u128, i128};
 
 use base;
@@ -301,7 +300,7 @@ pub fn trans_rvalue_operand(&mut self,
                             if let layout::Int(_, s) = scalar.value {
                                 signed = s;
 
-                                if scalar.valid_range.end > scalar.valid_range.start {
+                                if scalar.valid_range.end() > scalar.valid_range.start() {
                                     // We want `table[e as usize]` to not
                                     // have bound checks, and this is the most
                                     // convenient place to put the `assume`.
@@ -309,7 +308,7 @@ pub fn trans_rvalue_operand(&mut self,
                                     base::call_assume(&bx, bx.icmp(
                                         llvm::IntULE,
                                         llval,
-                                        C_uint_big(ll_t_in, scalar.valid_range.end)
+                                        C_uint_big(ll_t_in, *scalar.valid_range.end())
                                     ));
                                 }
                             }
@@ -805,6 +804,10 @@ fn cast_int_to_float(bx: &Builder,
     if is_u128_to_f32 {
         // All inputs greater or equal to (f32::MAX + 0.5 ULP) are rounded to infinity,
         // and for everything else LLVM's uitofp works just fine.
+        use rustc_apfloat::ieee::Single;
+        use rustc_apfloat::Float;
+        const MAX_F32_PLUS_HALF_ULP: u128 = ((1 << (Single::PRECISION + 1)) - 1)
+                                            << (Single::MAX_EXP - Single::PRECISION as i16);
         let max = C_uint_big(int_ty, MAX_F32_PLUS_HALF_ULP);
         let overflow = bx.icmp(llvm::IntUGE, x, max);
         let infinity_bits = C_u32(bx.cx, ieee::Single::INFINITY.to_bits() as u32);
index 70c13e9b7d637a6599e613a0e84c246954d40018..c426533779c9be18721ec458e7114feca16e048f 100644 (file)
@@ -15,7 +15,6 @@ syntax = { path = "../libsyntax" }
 arena = { path = "../libarena" }
 fmt_macros = { path = "../libfmt_macros" }
 rustc = { path = "../librustc" }
-rustc_const_math = { path = "../librustc_const_math" }
 rustc_data_structures = { path = "../librustc_data_structures" }
 rustc_platform_intrinsics = { path = "../librustc_platform_intrinsics" }
 rustc_target = { path = "../librustc_target" }
index 476ae6809737a33eeaa05c4713ed63491052b405..907c80f0daf5ef8a0c8864ef0559ad32813ab503 100644 (file)
@@ -1485,7 +1485,10 @@ fn to_unadjusted_pick(&self) -> Pick<'tcx> {
                     // inference variables or other artifacts. This
                     // means they are safe to put into the
                     // `WhereClausePick`.
-                    assert!(!trait_ref.skip_binder().substs.needs_infer());
+                    assert!(
+                        !trait_ref.skip_binder().substs.needs_infer()
+                            && !trait_ref.skip_binder().substs.has_skol()
+                    );
 
                     WhereClausePick(trait_ref.clone())
                 }
index 6e0d7dd8508775719988da59e7af640fbdb57bac..802e5375b6b2836ef295def6efa5bbf33df1fb8e 100644 (file)
@@ -107,7 +107,7 @@ fn tcx(&self) -> TyCtxt<'cx, 'gcx, 'tcx> {
 
     fn write_ty_to_tables(&mut self, hir_id: hir::HirId, ty: Ty<'gcx>) {
         debug!("write_ty_to_tables({:?}, {:?})", hir_id, ty);
-        assert!(!ty.needs_infer());
+        assert!(!ty.needs_infer() && !ty.has_skol());
         self.tables.node_types_mut().insert(hir_id, ty);
     }
 
@@ -431,7 +431,7 @@ fn visit_node_id(&mut self, span: Span, hir_id: hir::HirId) {
         if let Some(substs) = self.fcx.tables.borrow().node_substs_opt(hir_id) {
             let substs = self.resolve(&substs, &span);
             debug!("write_substs_to_tcx({:?}, {:?})", hir_id, substs);
-            assert!(!substs.needs_infer());
+            assert!(!substs.needs_infer() && !substs.has_skol());
             self.tables.node_substs_mut().insert(hir_id, substs);
         }
     }
index 958960d3a36fd3660850b5d24cdcb72199f844eb..350b53a406bc885268e54a37783b1c381fa79ce5 100644 (file)
@@ -92,7 +92,6 @@
 extern crate arena;
 #[macro_use] extern crate rustc;
 extern crate rustc_platform_intrinsics as intrinsics;
-extern crate rustc_const_math;
 extern crate rustc_data_structures;
 extern crate rustc_errors as errors;
 extern crate rustc_target;
index 7f89b3e6b3a2aad64c6f3a343f8b8e6bfc2d2532..d5e0f95ddf4356ac3396314dc6614889c9095418 100644 (file)
@@ -67,7 +67,7 @@ fn parse_nested(nested_cfg: &NestedMetaItem) -> Result<Cfg, InvalidCfgError> {
     /// If the content is not properly formatted, it will return an error indicating what and where
     /// the error is.
     pub fn parse(cfg: &MetaItem) -> Result<Cfg, InvalidCfgError> {
-        let name = cfg.ident.name;
+        let name = cfg.name();
         match cfg.node {
             MetaItemKind::Word => Ok(Cfg::Cfg(name, None)),
             MetaItemKind::NameValue(ref lit) => match lit.node {
@@ -436,6 +436,42 @@ fn name_value_cfg(name: &str, value: &str) -> Cfg {
         Cfg::Cfg(Symbol::intern(name), Some(Symbol::intern(value)))
     }
 
+    fn dummy_meta_item_word(name: &str) -> MetaItem {
+        MetaItem {
+            ident: Path::from_ident(Ident::from_str(name)),
+            node: MetaItemKind::Word,
+            span: DUMMY_SP,
+        }
+    }
+
+    macro_rules! dummy_meta_item_list {
+        ($name:ident, [$($list:ident),* $(,)*]) => {
+            MetaItem {
+                ident: Path::from_ident(Ident::from_str(stringify!($name))),
+                node: MetaItemKind::List(vec![
+                    $(
+                        dummy_spanned(NestedMetaItemKind::MetaItem(
+                            dummy_meta_item_word(stringify!($list)),
+                        )),
+                    )*
+                ]),
+                span: DUMMY_SP,
+            }
+        };
+
+        ($name:ident, [$($list:expr),* $(,)*]) => {
+            MetaItem {
+                ident: Path::from_ident(Ident::from_str(stringify!($name))),
+                node: MetaItemKind::List(vec![
+                    $(
+                        dummy_spanned(NestedMetaItemKind::MetaItem($list)),
+                    )*
+                ]),
+                span: DUMMY_SP,
+            }
+        };
+    }
+
     #[test]
     fn test_cfg_not() {
         with_globals(|| {
@@ -561,15 +597,11 @@ fn test_cfg_or() {
     #[test]
     fn test_parse_ok() {
         with_globals(|| {
-            let mi = MetaItem {
-                ident: Ident::from_str("all"),
-                node: MetaItemKind::Word,
-                span: DUMMY_SP,
-            };
+            let mi = dummy_meta_item_word("all");
             assert_eq!(Cfg::parse(&mi), Ok(word_cfg("all")));
 
             let mi = MetaItem {
-                ident: Ident::from_str("all"),
+                ident: Path::from_ident(Ident::from_str("all")),
                 node: MetaItemKind::NameValue(dummy_spanned(LitKind::Str(
                     Symbol::intern("done"),
                     StrStyle::Cooked,
@@ -578,111 +610,24 @@ fn test_parse_ok() {
             };
             assert_eq!(Cfg::parse(&mi), Ok(name_value_cfg("all", "done")));
 
-            let mi = MetaItem {
-                ident: Ident::from_str("all"),
-                node: MetaItemKind::List(vec![
-                    dummy_spanned(NestedMetaItemKind::MetaItem(MetaItem {
-                        ident: Ident::from_str("a"),
-                        node: MetaItemKind::Word,
-                        span: DUMMY_SP,
-                    })),
-                    dummy_spanned(NestedMetaItemKind::MetaItem(MetaItem {
-                        ident: Ident::from_str("b"),
-                        node: MetaItemKind::Word,
-                        span: DUMMY_SP,
-                    })),
-                ]),
-                span: DUMMY_SP,
-            };
+            let mi = dummy_meta_item_list!(all, [a, b]);
             assert_eq!(Cfg::parse(&mi), Ok(word_cfg("a") & word_cfg("b")));
 
-            let mi = MetaItem {
-                ident: Ident::from_str("any"),
-                node: MetaItemKind::List(vec![
-                    dummy_spanned(NestedMetaItemKind::MetaItem(MetaItem {
-                        ident: Ident::from_str("a"),
-                        node: MetaItemKind::Word,
-                        span: DUMMY_SP,
-                    })),
-                    dummy_spanned(NestedMetaItemKind::MetaItem(MetaItem {
-                        ident: Ident::from_str("b"),
-                        node: MetaItemKind::Word,
-                        span: DUMMY_SP,
-                    })),
-                ]),
-                span: DUMMY_SP,
-            };
+            let mi = dummy_meta_item_list!(any, [a, b]);
             assert_eq!(Cfg::parse(&mi), Ok(word_cfg("a") | word_cfg("b")));
 
-            let mi = MetaItem {
-                ident: Ident::from_str("not"),
-                node: MetaItemKind::List(vec![
-                    dummy_spanned(NestedMetaItemKind::MetaItem(MetaItem {
-                        ident: Ident::from_str("a"),
-                        node: MetaItemKind::Word,
-                        span: DUMMY_SP,
-                    })),
-                ]),
-                span: DUMMY_SP,
-            };
+            let mi = dummy_meta_item_list!(not, [a]);
             assert_eq!(Cfg::parse(&mi), Ok(!word_cfg("a")));
 
-            let mi = MetaItem {
-                ident: Ident::from_str("not"),
-                node: MetaItemKind::List(vec![
-                    dummy_spanned(NestedMetaItemKind::MetaItem(MetaItem {
-                        ident: Ident::from_str("any"),
-                        node: MetaItemKind::List(vec![
-                            dummy_spanned(NestedMetaItemKind::MetaItem(MetaItem {
-                                ident: Ident::from_str("a"),
-                                node: MetaItemKind::Word,
-                                span: DUMMY_SP,
-                            })),
-                            dummy_spanned(NestedMetaItemKind::MetaItem(MetaItem {
-                                ident: Ident::from_str("all"),
-                                node: MetaItemKind::List(vec![
-                                    dummy_spanned(NestedMetaItemKind::MetaItem(MetaItem {
-                                        ident: Ident::from_str("b"),
-                                        node: MetaItemKind::Word,
-                                        span: DUMMY_SP,
-                                    })),
-                                    dummy_spanned(NestedMetaItemKind::MetaItem(MetaItem {
-                                        ident: Ident::from_str("c"),
-                                        node: MetaItemKind::Word,
-                                        span: DUMMY_SP,
-                                    })),
-                                ]),
-                                span: DUMMY_SP,
-                            })),
-                        ]),
-                        span: DUMMY_SP,
-                    })),
+            let mi = dummy_meta_item_list!(not, [
+                dummy_meta_item_list!(any, [
+                    dummy_meta_item_word("a"),
+                    dummy_meta_item_list!(all, [b, c]),
                 ]),
-                span: DUMMY_SP,
-            };
+            ]);
             assert_eq!(Cfg::parse(&mi), Ok(!(word_cfg("a") | (word_cfg("b") & word_cfg("c")))));
 
-            let mi = MetaItem {
-                ident: Ident::from_str("all"),
-                node: MetaItemKind::List(vec![
-                    dummy_spanned(NestedMetaItemKind::MetaItem(MetaItem {
-                        ident: Ident::from_str("a"),
-                        node: MetaItemKind::Word,
-                        span: DUMMY_SP,
-                    })),
-                    dummy_spanned(NestedMetaItemKind::MetaItem(MetaItem {
-                        ident: Ident::from_str("b"),
-                        node: MetaItemKind::Word,
-                        span: DUMMY_SP,
-                    })),
-                    dummy_spanned(NestedMetaItemKind::MetaItem(MetaItem {
-                        ident: Ident::from_str("c"),
-                        node: MetaItemKind::Word,
-                        span: DUMMY_SP,
-                    })),
-                ]),
-                span: DUMMY_SP,
-            };
+            let mi = dummy_meta_item_list!(all, [a, b, c]);
             assert_eq!(Cfg::parse(&mi), Ok(word_cfg("a") & word_cfg("b") & word_cfg("c")));
         })
     }
@@ -691,97 +636,36 @@ fn test_parse_ok() {
     fn test_parse_err() {
         with_globals(|| {
             let mi = MetaItem {
-                ident: Ident::from_str("foo"),
+                ident: Path::from_ident(Ident::from_str("foo")),
                 node: MetaItemKind::NameValue(dummy_spanned(LitKind::Bool(false))),
                 span: DUMMY_SP,
             };
             assert!(Cfg::parse(&mi).is_err());
 
-            let mi = MetaItem {
-                ident: Ident::from_str("not"),
-                node: MetaItemKind::List(vec![
-                    dummy_spanned(NestedMetaItemKind::MetaItem(MetaItem {
-                        ident: Ident::from_str("a"),
-                        node: MetaItemKind::Word,
-                        span: DUMMY_SP,
-                    })),
-                    dummy_spanned(NestedMetaItemKind::MetaItem(MetaItem {
-                        ident: Ident::from_str("b"),
-                        node: MetaItemKind::Word,
-                        span: DUMMY_SP,
-                    })),
-                ]),
-                span: DUMMY_SP,
-            };
+            let mi = dummy_meta_item_list!(not, [a, b]);
             assert!(Cfg::parse(&mi).is_err());
 
-            let mi = MetaItem {
-                ident: Ident::from_str("not"),
-                node: MetaItemKind::List(vec![]),
-                span: DUMMY_SP,
-            };
+            let mi = dummy_meta_item_list!(not, []);
             assert!(Cfg::parse(&mi).is_err());
 
-            let mi = MetaItem {
-                ident: Ident::from_str("foo"),
-                node: MetaItemKind::List(vec![
-                    dummy_spanned(NestedMetaItemKind::MetaItem(MetaItem {
-                        ident: Ident::from_str("a"),
-                        node: MetaItemKind::Word,
-                        span: DUMMY_SP,
-                    })),
-                ]),
-                span: DUMMY_SP,
-            };
+            let mi = dummy_meta_item_list!(foo, []);
             assert!(Cfg::parse(&mi).is_err());
 
-            let mi = MetaItem {
-                ident: Ident::from_str("all"),
-                node: MetaItemKind::List(vec![
-                    dummy_spanned(NestedMetaItemKind::MetaItem(MetaItem {
-                        ident: Ident::from_str("foo"),
-                        node: MetaItemKind::List(vec![]),
-                        span: DUMMY_SP,
-                    })),
-                    dummy_spanned(NestedMetaItemKind::MetaItem(MetaItem {
-                        ident: Ident::from_str("b"),
-                        node: MetaItemKind::Word,
-                        span: DUMMY_SP,
-                    })),
-                ]),
-                span: DUMMY_SP,
-            };
+            let mi = dummy_meta_item_list!(all, [
+                dummy_meta_item_list!(foo, []),
+                dummy_meta_item_word("b"),
+            ]);
             assert!(Cfg::parse(&mi).is_err());
 
-            let mi = MetaItem {
-                ident: Ident::from_str("any"),
-                node: MetaItemKind::List(vec![
-                    dummy_spanned(NestedMetaItemKind::MetaItem(MetaItem {
-                        ident: Ident::from_str("a"),
-                        node: MetaItemKind::Word,
-                        span: DUMMY_SP,
-                    })),
-                    dummy_spanned(NestedMetaItemKind::MetaItem(MetaItem {
-                        ident: Ident::from_str("foo"),
-                        node: MetaItemKind::List(vec![]),
-                        span: DUMMY_SP,
-                    })),
-                ]),
-                span: DUMMY_SP,
-            };
+            let mi = dummy_meta_item_list!(any, [
+                dummy_meta_item_word("a"),
+                dummy_meta_item_list!(foo, []),
+            ]);
             assert!(Cfg::parse(&mi).is_err());
 
-            let mi = MetaItem {
-                ident: Ident::from_str("not"),
-                node: MetaItemKind::List(vec![
-                    dummy_spanned(NestedMetaItemKind::MetaItem(MetaItem {
-                        ident: Ident::from_str("foo"),
-                        node: MetaItemKind::List(vec![]),
-                        span: DUMMY_SP,
-                    })),
-                ]),
-                span: DUMMY_SP,
-            };
+            let mi = dummy_meta_item_list!(not, [
+                dummy_meta_item_list!(foo, []),
+            ]);
             assert!(Cfg::parse(&mi).is_err());
         })
     }
index bd64ac67ac93eaa789529951a941ef05ad1580ea..d124a17b421d140bcedc53f65b99a53e830ef5d0 100644 (file)
@@ -3661,7 +3661,7 @@ fn clean(&self, cx: &DocContext) -> Vec<Item> {
         // #[doc(no_inline)] attribute is present.
         // Don't inline doc(hidden) imports so they can be stripped at a later stage.
         let denied = self.vis != hir::Public || self.attrs.iter().any(|a| {
-            a.name().unwrap() == "doc" && match a.meta_item_list() {
+            a.name() == "doc" && match a.meta_item_list() {
                 Some(l) => attr::list_contains_name(&l, "no_inline") ||
                            attr::list_contains_name(&l, "hidden"),
                 None => false,
index 4e9781cc56080c3972e87a93d91f346b1ea5e0ce..21de2db1dfe74fd7bf1930e06b38b3e20589b31b 100644 (file)
@@ -1427,7 +1427,7 @@ fn add_aliases(&mut self, item: &clean::Item) {
         }
         if let Some(ref item_name) = item.name {
             let path = self.paths.get(&item.def_id)
-                                 .map(|p| p.0.join("::").to_string())
+                                 .map(|p| p.0[..p.0.len() - 1].join("::"))
                                  .unwrap_or("std".to_owned());
             for alias in item.attrs.lists("doc")
                                    .filter(|a| a.check_name("alias"))
@@ -3284,7 +3284,7 @@ fn item_enum(w: &mut fmt::Formatter, cx: &Context, it: &clean::Item,
 }
 
 fn render_attribute(attr: &ast::MetaItem) -> Option<String> {
-    let name = attr.ident.name;
+    let name = attr.name();
 
     if attr.is_word() {
         Some(format!("{}", name))
@@ -3319,7 +3319,7 @@ fn render_attributes(w: &mut fmt::Formatter, it: &clean::Item) -> fmt::Result {
     let mut attrs = String::new();
 
     for attr in &it.attrs.other_attrs {
-        let name = attr.name().unwrap();
+        let name = attr.name();
         if !ATTRIBUTE_WHITELIST.contains(&&*name.as_str()) {
             continue;
         }
index bcad2eb19f57496aa401e6e81044d7fb0a4b4330..6d80145b29c7c271a70a5b42166fd6231890de3b 100644 (file)
         if (e.parentNode.id === "main") {
             var otherMessage;
             if (hasClass(e, "type-decl")) {
-                otherMessage = '&nbsp;Show&nbsp;type&nbsp;declaration';
+                otherMessage = '&nbsp;Show&nbsp;declaration';
             }
             e.parentNode.insertBefore(createToggle(otherMessage), e);
             if (otherMessage && getCurrentValue('rustdoc-item-declarations') !== "false") {
index 8efb51bccd80529d909975bff4ef9a0e8fca6e2c..059d41698953d2a4fcb85e36b1e45fd7e264ffa8 100644 (file)
@@ -31,7 +31,6 @@
 extern crate env_logger;
 extern crate rustc;
 extern crate rustc_data_structures;
-extern crate rustc_const_math;
 extern crate rustc_trans_utils;
 extern crate rustc_driver;
 extern crate rustc_resolve;
index 967c50e62db5dde41a6ad138fba57742a2362b6e..6db02cc6cc105b7301d725aeef69535ff3ff4465 100644 (file)
@@ -49,7 +49,6 @@ pub struct RustdocVisitor<'a, 'tcx: 'a, 'rcx: 'a> {
     inlining: bool,
     /// Is the current module and all of its parents public?
     inside_public_path: bool,
-    reexported_macros: FxHashSet<DefId>,
     exact_paths: Option<FxHashMap<DefId, Vec<String>>>,
 }
 
@@ -66,7 +65,6 @@ pub fn new(cstore: &'a CrateStore,
             view_item_stack: stack,
             inlining: false,
             inside_public_path: true,
-            reexported_macros: FxHashSet(),
             exact_paths: Some(FxHashMap()),
             cstore,
         }
@@ -221,7 +219,7 @@ pub fn visit_mod_contents(&mut self, span: Span, attrs: hir::HirVec<ast::Attribu
         if let Some(exports) = self.cx.tcx.module_exports(def_id) {
             for export in exports.iter().filter(|e| e.vis == Visibility::Public) {
                 if let Def::Macro(def_id, ..) = export.def {
-                    if def_id.krate == LOCAL_CRATE || self.reexported_macros.contains(&def_id) {
+                    if def_id.krate == LOCAL_CRATE {
                         continue // These are `krate.exported_macros`, handled in `self.visit()`.
                     }
 
@@ -298,17 +296,6 @@ fn inherits_doc_hidden(cx: &core::DocContext, mut node: ast::NodeId) -> bool {
         let is_no_inline = use_attrs.lists("doc").has_word("no_inline") ||
                            use_attrs.lists("doc").has_word("hidden");
 
-        // Memoize the non-inlined `pub use`'d macros so we don't push an extra
-        // declaration in `visit_mod_contents()`
-        if !def_did.is_local() {
-            if let Def::Macro(did, _) = def {
-                if please_inline { return true }
-                debug!("memoizing non-inlined macro export: {:?}", def);
-                self.reexported_macros.insert(did);
-                return false;
-            }
-        }
-
         // For cross-crate impl inlining we need to know whether items are
         // reachable in documentation - a previously nonreachable item can be
         // made reachable by cross-crate inlining which we're checking here.
index 8164f52d3c34d570b202f75d36d9fe64340a6ae8..7c358aafa9ba2c2be230b068e80a02406f1be065 100644 (file)
@@ -988,6 +988,7 @@ pub unsafe fn from_bytes_with_nul_unchecked(bytes: &[u8]) -> &CStr {
     /// behavior when `ptr` is used inside the `unsafe` block:
     ///
     /// ```no_run
+    /// # #![allow(unused_must_use)]
     /// use std::ffi::{CString};
     ///
     /// let ptr = CString::new("Hello").unwrap().as_ptr();
@@ -1003,6 +1004,7 @@ pub unsafe fn from_bytes_with_nul_unchecked(bytes: &[u8]) -> &CStr {
     /// To fix the problem, bind the `CString` to a local variable:
     ///
     /// ```no_run
+    /// # #![allow(unused_must_use)]
     /// use std::ffi::{CString};
     ///
     /// let hello = CString::new("Hello").unwrap();
index 419921931350906e5c9223ace3e19de4d80a63c0..fc05833e28503f7eeede377f3e40601cde3a40a9 100644 (file)
 #![feature(libc)]
 #![feature(link_args)]
 #![feature(linkage)]
-#![feature(macro_reexport)]
 #![feature(macro_vis_matcher)]
 #![feature(needs_panic_runtime)]
 #![feature(never_type)]
 #![feature(unboxed_closures)]
 #![feature(untagged_unions)]
 #![feature(unwind_attributes)]
+#![feature(use_extern_macros)]
 #![feature(vec_push_all)]
 #![feature(doc_cfg)]
 #![feature(doc_masked)]
 #[cfg(test)] extern crate test;
 #[cfg(test)] extern crate rand;
 
-// We want to re-export a few macros from core but libcore has already been
-// imported by the compiler (via our #[no_std] attribute) In this case we just
-// add a new crate name so we can attach the re-exports to it.
-#[macro_reexport(assert_eq, assert_ne, debug_assert, debug_assert_eq,
-                 debug_assert_ne, unreachable, unimplemented, write, writeln, try)]
-extern crate core as __core;
+// Re-export a few macros from core
+#[stable(feature = "rust1", since = "1.0.0")]
+pub use core::{assert_eq, assert_ne, debug_assert, debug_assert_eq, debug_assert_ne};
+#[stable(feature = "rust1", since = "1.0.0")]
+pub use core::{unreachable, unimplemented, write, writeln, try};
 
+#[allow(unused_imports)] // macros from `alloc` are not used on all platforms
 #[macro_use]
-#[macro_reexport(vec, format)]
 extern crate alloc as alloc_crate;
 extern crate alloc_system;
 #[doc(masked)]
 #[stable(feature = "rust1", since = "1.0.0")]
 pub use alloc_crate::fmt;
 #[stable(feature = "rust1", since = "1.0.0")]
+pub use alloc_crate::format;
+#[stable(feature = "rust1", since = "1.0.0")]
 pub use alloc_crate::slice;
 #[stable(feature = "rust1", since = "1.0.0")]
 pub use alloc_crate::str;
index 6902ec82047d73094259a93eccd16f401cebe179..d1274a4090087b61351444b37d2dc510aeb75ec6 100644 (file)
@@ -450,8 +450,8 @@ macro_rules! option_env {
     #[unstable(feature = "concat_idents_macro", issue = "29599")]
     #[macro_export]
     macro_rules! concat_idents {
-        ($($e:ident),*) => ({ /* compiler built-in */ });
-        ($($e:ident,)*) => ({ /* compiler built-in */ });
+        ($($e:ident),+) => ({ /* compiler built-in */ });
+        ($($e:ident,)+) => ({ /* compiler built-in */ });
     }
 
     /// Concatenates literals into a static string slice.
index 955a6af1ae67eaac5a78975499cf329658003667..696711a70d4f6408cc773abf87d04ed932e64b02 100644 (file)
@@ -87,7 +87,6 @@
 use iter::{self, FusedIterator};
 use ops::{self, Deref};
 use rc::Rc;
-use str::FromStr;
 use sync::Arc;
 
 use ffi::{OsStr, OsString};
@@ -1441,32 +1440,6 @@ fn from(s: String) -> PathBuf {
     }
 }
 
-/// Error returned from [`PathBuf::from_str`][`from_str`].
-///
-/// Note that parsing a path will never fail. This error is just a placeholder
-/// for implementing `FromStr` for `PathBuf`.
-///
-/// [`from_str`]: struct.PathBuf.html#method.from_str
-#[derive(Debug, Clone, PartialEq, Eq)]
-#[stable(feature = "path_from_str", since = "1.26.0")]
-pub enum ParsePathError {}
-
-#[stable(feature = "path_from_str", since = "1.26.0")]
-impl fmt::Display for ParsePathError {
-    fn fmt(&self, _: &mut fmt::Formatter) -> fmt::Result {
-        match *self {}
-    }
-}
-
-#[stable(feature = "path_from_str", since = "1.26.0")]
-impl FromStr for PathBuf {
-    type Err = ParsePathError;
-
-    fn from_str(s: &str) -> Result<Self, Self::Err> {
-        Ok(PathBuf::from(s))
-    }
-}
-
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<P: AsRef<Path>> iter::FromIterator<P> for PathBuf {
     fn from_iter<I: IntoIterator<Item = P>>(iter: I) -> PathBuf {
index a9f3cea243f366c61e0abf759c474c95a00581ae..9310dad9172a9f816436039b0d6bb4e15d836dc6 100644 (file)
@@ -518,6 +518,7 @@ fn stress() {
         }
     }
 
+    #[allow(unused_must_use)]
     #[test]
     fn cloning() {
         let (tx1, rx1) = channel::<i32>();
@@ -540,6 +541,7 @@ fn cloning() {
         tx3.send(()).unwrap();
     }
 
+    #[allow(unused_must_use)]
     #[test]
     fn cloning2() {
         let (tx1, rx1) = channel::<i32>();
index b590a4a628608f790a6fec280301027ef33d2140..f8cd6103bdfa110e4e421ba0e5c129b1b2f4115c 100644 (file)
@@ -474,10 +474,10 @@ pub enum NestedMetaItemKind {
 
 /// A spanned compile-time attribute item.
 ///
-/// E.g. `#[test]`, `#[derive(..)]` or `#[feature = "foo"]`
+/// E.g. `#[test]`, `#[derive(..)]`, `#[rustfmt::skip]` or `#[feature = "foo"]`
 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
 pub struct MetaItem {
-    pub ident: Ident,
+    pub ident: Path,
     pub node: MetaItemKind,
     pub span: Span,
 }
index f0557277267a519a5f10d5f2415a549e3e8e608f..ace9904e0c021e57b39ff6005883d6afbaa80d19 100644 (file)
 pub use self::IntType::*;
 
 use ast;
-use ast::{AttrId, Attribute, Name, Ident};
+use ast::{AttrId, Attribute, Name, Ident, Path, PathSegment};
 use ast::{MetaItem, MetaItemKind, NestedMetaItem, NestedMetaItemKind};
 use ast::{Lit, LitKind, Expr, ExprKind, Item, Local, Stmt, StmtKind};
-use codemap::{Spanned, respan, dummy_spanned};
+use codemap::{BytePos, Spanned, respan, dummy_spanned};
 use syntax_pos::Span;
 use errors::Handler;
 use feature_gate::{Features, GatedCfg};
@@ -107,6 +107,14 @@ pub fn is_known(attr: &Attribute) -> bool {
     })
 }
 
+const RUST_KNOWN_TOOL: &[&str] = &["clippy", "rustfmt"];
+
+pub fn is_known_tool(attr: &Attribute) -> bool {
+    let tool_name =
+        attr.path.segments.iter().next().expect("empty path in attribute").ident.name;
+    RUST_KNOWN_TOOL.contains(&tool_name.as_str().as_ref())
+}
+
 impl NestedMetaItem {
     /// Returns the MetaItem if self is a NestedMetaItemKind::MetaItem.
     pub fn meta_item(&self) -> Option<&MetaItem> {
@@ -137,7 +145,7 @@ pub fn check_name(&self, name: &str) -> bool {
     /// Returns the name of the meta item, e.g. `foo` in `#[foo]`,
     /// `#[foo="bar"]` and `#[foo(bar)]`, if self is a MetaItem
     pub fn name(&self) -> Option<Name> {
-        self.meta_item().and_then(|meta_item| Some(meta_item.ident.name))
+        self.meta_item().and_then(|meta_item| Some(meta_item.name()))
     }
 
     /// Gets the string value if self is a MetaItem and the MetaItem is a
@@ -154,7 +162,7 @@ pub fn name_value_literal(&self) -> Option<(Name, &Lit)> {
                     if meta_item_list.len() == 1 {
                         let nested_item = &meta_item_list[0];
                         if nested_item.is_literal() {
-                            Some((meta_item.ident.name, nested_item.literal().unwrap()))
+                            Some((meta_item.name(), nested_item.literal().unwrap()))
                         } else {
                             None
                         }
@@ -204,6 +212,10 @@ pub fn is_meta_item_list(&self) -> bool {
     }
 }
 
+fn name_from_path(path: &Path) -> Name {
+    path.segments.last().expect("empty path in attribute").ident.name
+}
+
 impl Attribute {
     pub fn check_name(&self, name: &str) -> bool {
         let matches = self.path == name;
@@ -213,11 +225,10 @@ pub fn check_name(&self, name: &str) -> bool {
         matches
     }
 
-    pub fn name(&self) -> Option<Name> {
-        match self.path.segments.len() {
-            1 => Some(self.path.segments[0].ident.name),
-            _ => None,
-        }
+    /// Returns the **last** segment of the name of this attribute.
+    /// E.g. `foo` for `#[foo]`, `skip` for `#[rustfmt::skip]`.
+    pub fn name(&self) -> Name {
+        name_from_path(&self.path)
     }
 
     pub fn value_str(&self) -> Option<Symbol> {
@@ -247,9 +258,17 @@ pub fn is_meta_item_list(&self) -> bool {
     pub fn is_value_str(&self) -> bool {
         self.value_str().is_some()
     }
+
+    pub fn is_scoped(&self) -> bool {
+        self.path.segments.len() > 1
+    }
 }
 
 impl MetaItem {
+    pub fn name(&self) -> Name {
+        name_from_path(&self.ident)
+    }
+
     pub fn value_str(&self) -> Option<Symbol> {
         match self.node {
             MetaItemKind::NameValue(ref v) => {
@@ -279,7 +298,7 @@ pub fn is_word(&self) -> bool {
     pub fn span(&self) -> Span { self.span }
 
     pub fn check_name(&self, name: &str) -> bool {
-        self.ident.name == name
+        self.name() == name
     }
 
     pub fn is_value_str(&self) -> bool {
@@ -296,10 +315,7 @@ impl Attribute {
     pub fn meta(&self) -> Option<MetaItem> {
         let mut tokens = self.tokens.trees().peekable();
         Some(MetaItem {
-            ident: match self.path.segments.len() {
-                1 => self.path.segments[0].ident,
-                _ => return None,
-            },
+            ident: self.path.clone(),
             node: if let Some(node) = MetaItemKind::from_tokens(&mut tokens) {
                 if tokens.peek().is_some() {
                     return None;
@@ -344,12 +360,8 @@ pub fn parse_list<'a, T, F>(&self, sess: &'a ParseSess, mut f: F) -> PResult<'a,
     }
 
     pub fn parse_meta<'a>(&self, sess: &'a ParseSess) -> PResult<'a, MetaItem> {
-        if self.path.segments.len() > 1 {
-            sess.span_diagnostic.span_err(self.path.span, "expected ident, found path");
-        }
-
         Ok(MetaItem {
-            ident: self.path.segments.last().unwrap().ident,
+            ident: self.path.clone(),
             node: self.parse(sess, |parser| parser.parse_meta_item_kind())?,
             span: self.span,
         })
@@ -387,16 +399,17 @@ pub fn mk_name_value_item_str(ident: Ident, value: Spanned<Symbol>) -> MetaItem
 }
 
 pub fn mk_name_value_item(span: Span, ident: Ident, value: ast::Lit) -> MetaItem {
-    MetaItem { ident, span, node: MetaItemKind::NameValue(value) }
+    MetaItem { ident: Path::from_ident(ident), span, node: MetaItemKind::NameValue(value) }
 }
 
 pub fn mk_list_item(span: Span, ident: Ident, items: Vec<NestedMetaItem>) -> MetaItem {
-    MetaItem { ident, span, node: MetaItemKind::List(items) }
+    MetaItem { ident: Path::from_ident(ident), span, node: MetaItemKind::List(items) }
 }
 
 pub fn mk_word_item(ident: Ident) -> MetaItem {
-    MetaItem { ident, span: ident.span, node: MetaItemKind::Word }
+    MetaItem { ident: Path::from_ident(ident), span: ident.span, node: MetaItemKind::Word }
 }
+
 pub fn mk_nested_word_item(ident: Ident) -> NestedMetaItem {
     respan(ident.span, NestedMetaItemKind::MetaItem(mk_word_item(ident)))
 }
@@ -422,7 +435,7 @@ pub fn mk_spanned_attr_inner(sp: Span, id: AttrId, item: MetaItem) -> Attribute
     Attribute {
         id,
         style: ast::AttrStyle::Inner,
-        path: ast::Path::from_ident(item.ident),
+        path: item.ident,
         tokens: item.node.tokens(item.span),
         is_sugared_doc: false,
         span: sp,
@@ -440,7 +453,7 @@ pub fn mk_spanned_attr_outer(sp: Span, id: AttrId, item: MetaItem) -> Attribute
     Attribute {
         id,
         style: ast::AttrStyle::Outer,
-        path: ast::Path::from_ident(item.ident),
+        path: item.ident,
         tokens: item.node.tokens(item.span),
         is_sugared_doc: false,
         span: sp,
@@ -453,7 +466,7 @@ pub fn mk_sugared_doc_attr(id: AttrId, text: Symbol, span: Span) -> Attribute {
     Attribute {
         id,
         style,
-        path: ast::Path::from_ident(Ident::from_str("doc").with_span_pos(span)),
+        path: Path::from_ident(Ident::from_str("doc").with_span_pos(span)),
         tokens: MetaItemKind::NameValue(lit).tokens(span),
         is_sugared_doc: true,
         span,
@@ -489,7 +502,7 @@ pub fn contains_feature_attr(attrs: &[Attribute], feature_name: &str) -> bool {
         item.check_name("feature") &&
         item.meta_item_list().map(|list| {
             list.iter().any(|mi| {
-                mi.word().map(|w| w.ident.name == feature_name)
+                mi.word().map(|w| w.name() == feature_name)
                          .unwrap_or(false)
             })
         }).unwrap_or(false)
@@ -562,7 +575,7 @@ pub fn cfg_matches(cfg: &ast::MetaItem, sess: &ParseSess, features: Option<&Feat
         if let (Some(feats), Some(gated_cfg)) = (features, GatedCfg::gate(cfg)) {
             gated_cfg.check_and_emit(sess, feats);
         }
-        sess.config.contains(&(cfg.ident.name, cfg.value_str()))
+        sess.config.contains(&(cfg.name(), cfg.value_str()))
     })
 }
 
@@ -583,7 +596,7 @@ pub fn eval_condition<F>(cfg: &ast::MetaItem, sess: &ParseSess, eval: &mut F)
 
             // The unwraps below may look dangerous, but we've already asserted
             // that they won't fail with the loop above.
-            match &*cfg.ident.name.as_str() {
+            match &*cfg.name().as_str() {
                 "any" => mis.iter().any(|mi| {
                     eval_condition(mi.meta_item().unwrap(), sess, eval)
                 }),
@@ -676,7 +689,7 @@ fn find_stability_generic<'a, I>(diagnostic: &Handler,
             let meta = meta.as_ref().unwrap();
             let get = |meta: &MetaItem, item: &mut Option<Symbol>| {
                 if item.is_some() {
-                    handle_errors(diagnostic, meta.span, AttrError::MultipleItem(meta.ident.name));
+                    handle_errors(diagnostic, meta.span, AttrError::MultipleItem(meta.name()));
                     return false
                 }
                 if let Some(v) = meta.value_str() {
@@ -695,14 +708,14 @@ macro_rules! get_meta {
                     )+
                     for meta in metas {
                         if let Some(mi) = meta.meta_item() {
-                            match &*mi.ident.name.as_str() {
+                            match &*mi.name().as_str() {
                                 $(
                                     stringify!($name)
                                         => if !get(mi, &mut $name) { continue 'outer },
                                 )+
                                 _ => {
                                     handle_errors(diagnostic, mi.span,
-                                                  AttrError::UnknownMetaItem(mi.ident.name));
+                                                  AttrError::UnknownMetaItem(mi.name()));
                                     continue 'outer
                                 }
                             }
@@ -714,7 +727,7 @@ macro_rules! get_meta {
                 }
             }
 
-            match &*meta.ident.name.as_str() {
+            match &*meta.name().as_str() {
                 "rustc_deprecated" => {
                     if rustc_depr.is_some() {
                         span_err!(diagnostic, item_sp, E0540,
@@ -769,13 +782,13 @@ macro_rules! get_meta {
                     let mut issue = None;
                     for meta in metas {
                         if let Some(mi) = meta.meta_item() {
-                            match &*mi.ident.name.as_str() {
+                            match &*mi.name().as_str() {
                                 "feature" => if !get(mi, &mut feature) { continue 'outer },
                                 "reason" => if !get(mi, &mut reason) { continue 'outer },
                                 "issue" => if !get(mi, &mut issue) { continue 'outer },
                                 _ => {
                                     handle_errors(diagnostic, meta.span,
-                                                  AttrError::UnknownMetaItem(mi.ident.name));
+                                                  AttrError::UnknownMetaItem(mi.name()));
                                     continue 'outer
                                 }
                             }
@@ -825,12 +838,12 @@ macro_rules! get_meta {
                     let mut since = None;
                     for meta in metas {
                         if let NestedMetaItemKind::MetaItem(ref mi) = meta.node {
-                            match &*mi.ident.name.as_str() {
+                            match &*mi.name().as_str() {
                                 "feature" => if !get(mi, &mut feature) { continue 'outer },
                                 "since" => if !get(mi, &mut since) { continue 'outer },
                                 _ => {
                                     handle_errors(diagnostic, meta.span,
-                                                  AttrError::UnknownMetaItem(mi.ident.name));
+                                                  AttrError::UnknownMetaItem(mi.name()));
                                     continue 'outer
                                 }
                             }
@@ -917,7 +930,7 @@ fn find_deprecation_generic<'a, I>(diagnostic: &Handler,
         depr = if let Some(metas) = attr.meta_item_list() {
             let get = |meta: &MetaItem, item: &mut Option<Symbol>| {
                 if item.is_some() {
-                    handle_errors(diagnostic, meta.span, AttrError::MultipleItem(meta.ident.name));
+                    handle_errors(diagnostic, meta.span, AttrError::MultipleItem(meta.name()));
                     return false
                 }
                 if let Some(v) = meta.value_str() {
@@ -933,12 +946,12 @@ fn find_deprecation_generic<'a, I>(diagnostic: &Handler,
             let mut note = None;
             for meta in metas {
                 if let NestedMetaItemKind::MetaItem(ref mi) = meta.node {
-                    match &*mi.ident.name.as_str() {
+                    match &*mi.name().as_str() {
                         "since" => if !get(mi, &mut since) { continue 'outer },
                         "note" => if !get(mi, &mut note) { continue 'outer },
                         _ => {
                             handle_errors(diagnostic, meta.span,
-                                          AttrError::UnknownMetaItem(mi.ident.name));
+                                          AttrError::UnknownMetaItem(mi.name()));
                             continue 'outer
                         }
                     }
@@ -990,7 +1003,7 @@ pub fn find_repr_attrs(diagnostic: &Handler, attr: &Attribute) -> Vec<ReprAttr>
 
                 let mut recognised = false;
                 if let Some(mi) = item.word() {
-                    let word = &*mi.ident.name.as_str();
+                    let word = &*mi.name().as_str();
                     let hint = match word {
                         "C" => Some(ReprC),
                         "packed" => Some(ReprPacked(1)),
@@ -1012,11 +1025,11 @@ pub fn find_repr_attrs(diagnostic: &Handler, attr: &Attribute) -> Vec<ReprAttr>
                     let parse_alignment = |node: &ast::LitKind| -> Result<u32, &'static str> {
                         if let ast::LitKind::Int(literal, ast::LitIntType::Unsuffixed) = node {
                             if literal.is_power_of_two() {
-                                // rustc::ty::layout::Align restricts align to <= 2147483647
-                                if *literal <= 2147483647 {
+                                // rustc::ty::layout::Align restricts align to <= 2^29
+                                if *literal <= 1 << 29 {
                                     Ok(*literal as u32)
                                 } else {
-                                    Err("larger than 2147483647")
+                                    Err("larger than 2^29")
                                 }
                             } else {
                                 Err("not a power of two")
@@ -1047,7 +1060,7 @@ pub fn find_repr_attrs(diagnostic: &Handler, attr: &Attribute) -> Vec<ReprAttr>
                     }
                 } else {
                     if let Some(meta_item) = item.meta_item() {
-                        if meta_item.ident.name == "align" {
+                        if meta_item.name() == "align" {
                             if let MetaItemKind::NameValue(ref value) = meta_item.node {
                                 recognised = true;
                                 let mut err = struct_span_err!(diagnostic, item.span, E0693,
@@ -1127,18 +1140,56 @@ pub fn is_signed(self) -> bool {
 
 impl MetaItem {
     fn tokens(&self) -> TokenStream {
-        let ident = TokenTree::Token(self.span, Token::from_ast_ident(self.ident));
-        TokenStream::concat(vec![ident.into(), self.node.tokens(self.span)])
+        let mut idents = vec![];
+        let mut last_pos = BytePos(0 as u32);
+        for (i, segment) in self.ident.segments.iter().enumerate() {
+            let is_first = i == 0;
+            if !is_first {
+                let mod_sep_span = Span::new(last_pos,
+                                             segment.ident.span.lo(),
+                                             segment.ident.span.ctxt());
+                idents.push(TokenTree::Token(mod_sep_span, Token::ModSep).into());
+            }
+            idents.push(TokenTree::Token(segment.ident.span,
+                                         Token::from_ast_ident(segment.ident)).into());
+            last_pos = segment.ident.span.hi();
+        }
+        idents.push(self.node.tokens(self.span));
+        TokenStream::concat(idents)
     }
 
     fn from_tokens<I>(tokens: &mut iter::Peekable<I>) -> Option<MetaItem>
         where I: Iterator<Item = TokenTree>,
     {
-        let (span, ident) = match tokens.next() {
-            Some(TokenTree::Token(span, Token::Ident(ident, _))) => (span, ident),
+        // FIXME: Share code with `parse_path`.
+        let ident = match tokens.next() {
+            Some(TokenTree::Token(span, Token::Ident(ident, _))) => {
+                if let Some(TokenTree::Token(_, Token::ModSep)) = tokens.peek() {
+                    let mut segments = vec![PathSegment::from_ident(ident.with_span_pos(span))];
+                    tokens.next();
+                    loop {
+                        if let Some(TokenTree::Token(span,
+                                                     Token::Ident(ident, _))) = tokens.next() {
+                            segments.push(PathSegment::from_ident(ident.with_span_pos(span)));
+                        } else {
+                            return None;
+                        }
+                        if let Some(TokenTree::Token(_, Token::ModSep)) = tokens.peek() {
+                            tokens.next();
+                        } else {
+                            break;
+                        }
+                    }
+                    let span = span.with_hi(segments.last().unwrap().ident.span.hi());
+                    Path { span, segments }
+                } else {
+                    Path::from_ident(ident.with_span_pos(span))
+                }
+            }
             Some(TokenTree::Token(_, Token::Interpolated(ref nt))) => match nt.0 {
-                token::Nonterminal::NtIdent(ident, _) => (ident.span, ident),
+                token::Nonterminal::NtIdent(ident, _) => Path::from_ident(ident),
                 token::Nonterminal::NtMeta(ref meta) => return Some(meta.clone()),
+                token::Nonterminal::NtPath(ref path) => path.clone(),
                 _ => return None,
             },
             _ => return None,
@@ -1147,10 +1198,11 @@ fn from_tokens<I>(tokens: &mut iter::Peekable<I>) -> Option<MetaItem>
         let node = MetaItemKind::from_tokens(tokens)?;
         let hi = match node {
             MetaItemKind::NameValue(ref lit) => lit.span.hi(),
-            MetaItemKind::List(..) => list_closing_paren_pos.unwrap_or(span.hi()),
-            _ => span.hi(),
+            MetaItemKind::List(..) => list_closing_paren_pos.unwrap_or(ident.span.hi()),
+            _ => ident.span.hi(),
         };
-        Some(MetaItem { ident, node, span: span.with_hi(hi) })
+        let span = ident.span.with_hi(hi);
+        Some(MetaItem { ident, node, span })
     }
 }
 
@@ -1252,10 +1304,7 @@ fn token(&self) -> Token {
 
         match *self {
             LitKind::Str(string, ast::StrStyle::Cooked) => {
-                let mut escaped = String::new();
-                for ch in string.as_str().chars() {
-                    escaped.extend(ch.escape_unicode());
-                }
+                let escaped = string.as_str().escape_default();
                 Token::Literal(token::Lit::Str_(Symbol::intern(&escaped)), None)
             }
             LitKind::Str(string, ast::StrStyle::Raw(n)) => {
index c9cac1b11427ad5eb01ecdaef9720b93a06d5045..5f940437ab3fbc37395fc0d007be2defdc9afaa9 100644 (file)
@@ -244,6 +244,18 @@ fn main() {
 ```
 "##,
 
+E0589: r##"
+The value of `N` that was specified for `repr(align(N))` was not a power
+of two, or was greater than 2^29.
+
+```compile_fail,E0589
+#[repr(align(15))] // error: invalid `repr(align)` attribute: not a power of two
+enum Foo {
+    Bar(u64),
+}
+```
+"##,
+
 E0658: r##"
 An unstable feature was used.
 
@@ -321,8 +333,8 @@ fn main() {}
     E0555, // malformed feature attribute, expected #![feature(...)]
     E0556, // malformed feature, expected just one word
     E0584, // file for module `..` found at both .. and ..
-    E0589, // invalid `repr(align)` attribute
     E0629, // missing 'feature' (rustc_const_unstable)
     E0630, // rustc_const_unstable attribute must be paired with stable/unstable attribute
     E0693, // incorrect `repr(align)` attribute format
+    E0694, // an unknown tool name found in scoped attributes
 }
index 2f3b35c33f3ec33557d48dc426c17d600da8f6f6..584b9455a93ada1e39174e6ed92c7ae2ab2eaf50 100644 (file)
@@ -810,7 +810,7 @@ fn expand_derive_invoc(&mut self,
                 invoc.expansion_data.mark.set_expn_info(expn_info);
                 let span = span.with_ctxt(self.cx.backtrace());
                 let dummy = ast::MetaItem { // FIXME(jseyfried) avoid this
-                    ident: keywords::Invalid.ident(),
+                    ident: Path::from_ident(keywords::Invalid.ident()),
                     span: DUMMY_SP,
                     node: ast::MetaItemKind::Word,
                 };
@@ -1017,7 +1017,7 @@ fn configure<T: HasAttrs>(&mut self, node: T) -> Option<T> {
     fn check_attributes(&mut self, attrs: &[ast::Attribute]) {
         let features = self.cx.ecfg.features.unwrap();
         for attr in attrs.iter() {
-            feature_gate::check_attribute(attr, self.cx.parse_sess, features);
+            self.check_attribute_inner(attr, features);
 
             // macros are expanded before any lint passes so this warning has to be hardcoded
             if attr.path == "derive" {
@@ -1030,6 +1030,10 @@ fn check_attributes(&mut self, attrs: &[ast::Attribute]) {
 
     fn check_attribute(&mut self, at: &ast::Attribute) {
         let features = self.cx.ecfg.features.unwrap();
+        self.check_attribute_inner(at, features);
+    }
+
+    fn check_attribute_inner(&mut self, at: &ast::Attribute, features: &Features) {
         feature_gate::check_attribute(at, self.cx.parse_sess, features);
     }
 }
index d9c3deb30da30a8b6107bbafb181e7e6c90adf84..71634ada89458012b70f6b307c5f7dca3bf33ddc 100644 (file)
@@ -835,7 +835,13 @@ fn parse_nt<'a>(p: &mut Parser<'a>, sp: Span, name: &str) -> Nonterminal {
         "path" => token::NtPath(panictry!(p.parse_path_common(PathStyle::Type, false))),
         "meta" => token::NtMeta(panictry!(p.parse_meta_item())),
         "vis" => token::NtVis(panictry!(p.parse_visibility(true))),
-        "lifetime" => token::NtLifetime(p.expect_lifetime().ident),
+        "lifetime" => if p.check_lifetime() {
+            token::NtLifetime(p.expect_lifetime().ident)
+        } else {
+            let token_str = pprust::token_to_string(&p.token);
+            p.fatal(&format!("expected a lifetime, found `{}`", &token_str)).emit();
+            FatalError.raise();
+        }
         // this is not supposed to happen, since it has been checked
         // when compiling the macro.
         _ => p.span_bug(sp, "invalid fragment specifier"),
index a4a83712a083a730029d66aacb1542a13db6d45d..d8db76a95ff38ef1fde952f99658dd42e6d2d7b9 100644 (file)
@@ -90,24 +90,24 @@ pub fn walk_feature_fields<F>(&self, mut f: F)
         }
     };
 
-    ($((removed, $feature: ident, $ver: expr, $issue: expr, None),)+) => {
+    ($((removed, $feature: ident, $ver: expr, $issue: expr, None, $reason: expr),)+) => {
         /// Represents unstable features which have since been removed (it was once Active)
-        const REMOVED_FEATURES: &'static [(&'static str, &'static str, Option<u32>)] = &[
-            $((stringify!($feature), $ver, $issue)),+
+        const REMOVED_FEATURES: &[(&str, &str, Option<u32>, Option<&str>)] = &[
+            $((stringify!($feature), $ver, $issue, $reason)),+
         ];
     };
 
     ($((stable_removed, $feature: ident, $ver: expr, $issue: expr, None),)+) => {
         /// Represents stable features which have since been removed (it was once Accepted)
-        const STABLE_REMOVED_FEATURES: &'static [(&'static str, &'static str, Option<u32>)] = &[
-            $((stringify!($feature), $ver, $issue)),+
+        const STABLE_REMOVED_FEATURES: &[(&str, &str, Option<u32>, Option<&str>)] = &[
+            $((stringify!($feature), $ver, $issue, None)),+
         ];
     };
 
     ($((accepted, $feature: ident, $ver: expr, $issue: expr, None),)+) => {
         /// Those language feature has since been Accepted (it was once Active)
-        const ACCEPTED_FEATURES: &'static [(&'static str, &'static str, Option<u32>)] = &[
-            $((stringify!($feature), $ver, $issue)),+
+        const ACCEPTED_FEATURES: &[(&str, &str, Option<u32>, Option<&str>)] = &[
+            $((stringify!($feature), $ver, $issue, None)),+
         ];
     }
 }
@@ -162,9 +162,6 @@ pub fn walk_feature_fields<F>(&self, mut f: F)
     // OIBIT specific features
     (active, optin_builtin_traits, "1.0.0", Some(13231), None),
 
-    // macro re-export needs more discussion and stabilization
-    (active, macro_reexport, "1.0.0", Some(29638), None),
-
     // Allows use of #[staged_api]
     // rustc internal
     (active, staged_api, "1.0.0", None, None),
@@ -369,9 +366,6 @@ pub fn walk_feature_fields<F>(&self, mut f: F)
     // #[doc(include="some-file")]
     (active, external_doc, "1.22.0", Some(44732), None),
 
-    // allow `#[must_use]` on functions and comparison operators (RFC 1940)
-    (active, fn_must_use, "1.21.0", Some(43302), None),
-
     // Future-proofing enums/structs with #[non_exhaustive] attribute (RFC 2008)
     (active, non_exhaustive, "1.22.0", Some(44109), None),
 
@@ -394,7 +388,7 @@ pub fn walk_feature_fields<F>(&self, mut f: F)
     (active, generic_associated_types, "1.23.0", Some(44265), None),
 
     // Resolve absolute paths as paths from other crates
-    (active, extern_absolute_paths, "1.24.0", Some(44660), None),
+    (active, extern_absolute_paths, "1.24.0", Some(44660), Some(Edition::Edition2018)),
 
     // `foo.rs` as an alternative to `foo/mod.rs`
     (active, non_modrs_mods, "1.24.0", Some(44660), Some(Edition::Edition2018)),
@@ -463,30 +457,38 @@ pub fn walk_feature_fields<F>(&self, mut f: F)
 
     // #[doc(alias = "...")]
     (active, doc_alias, "1.27.0", Some(50146), None),
+
+    // Access to crate names passed via `--extern` through prelude
+    (active, extern_prelude, "1.27.0", Some(44660), Some(Edition::Edition2018)),
+
+    // Scoped attributes
+    (active, tool_attributes, "1.25.0", Some(44690), None),
 );
 
 declare_features! (
-    (removed, import_shadowing, "1.0.0", None, None),
-    (removed, managed_boxes, "1.0.0", None, None),
+    (removed, import_shadowing, "1.0.0", None, None, None),
+    (removed, managed_boxes, "1.0.0", None, None, None),
     // Allows use of unary negate on unsigned integers, e.g. -e for e: u8
-    (removed, negate_unsigned, "1.0.0", Some(29645), None),
-    (removed, reflect, "1.0.0", Some(27749), None),
+    (removed, negate_unsigned, "1.0.0", Some(29645), None, None),
+    (removed, reflect, "1.0.0", Some(27749), None, None),
     // A way to temporarily opt out of opt in copy. This will *never* be accepted.
-    (removed, opt_out_copy, "1.0.0", None, None),
-    (removed, quad_precision_float, "1.0.0", None, None),
-    (removed, struct_inherit, "1.0.0", None, None),
-    (removed, test_removed_feature, "1.0.0", None, None),
-    (removed, visible_private_types, "1.0.0", None, None),
-    (removed, unsafe_no_drop_flag, "1.0.0", None, None),
+    (removed, opt_out_copy, "1.0.0", None, None, None),
+    (removed, quad_precision_float, "1.0.0", None, None, None),
+    (removed, struct_inherit, "1.0.0", None, None, None),
+    (removed, test_removed_feature, "1.0.0", None, None, None),
+    (removed, visible_private_types, "1.0.0", None, None, None),
+    (removed, unsafe_no_drop_flag, "1.0.0", None, None, None),
     // Allows using items which are missing stability attributes
     // rustc internal
-    (removed, unmarked_api, "1.0.0", None, None),
-    (removed, pushpop_unsafe, "1.2.0", None, None),
-    (removed, allocator, "1.0.0", None, None),
-    // Allows the `#[simd]` attribute -- removed in favor of `#[repr(simd)]`
-    (removed, simd, "1.0.0", Some(27731), None),
-    // Merged into `slice_patterns`
-    (removed, advanced_slice_patterns, "1.0.0", Some(23121), None),
+    (removed, unmarked_api, "1.0.0", None, None, None),
+    (removed, pushpop_unsafe, "1.2.0", None, None, None),
+    (removed, allocator, "1.0.0", None, None, None),
+    (removed, simd, "1.0.0", Some(27731), None,
+     Some("removed in favor of `#[repr(simd)]`")),
+    (removed, advanced_slice_patterns, "1.0.0", Some(23121), None,
+     Some("merged into `#![feature(slice_patterns)]`")),
+    (removed, macro_reexport, "1.0.0", Some(29638), None,
+     Some("subsumed by `#![feature(use_extern_macros)]` and `pub use`")),
 );
 
 declare_features! (
@@ -591,6 +593,8 @@ pub fn walk_feature_fields<F>(&self, mut f: F)
     (accepted, target_feature, "1.27.0", None, None),
     // Trait object syntax with `dyn` prefix
     (accepted, dyn_trait, "1.27.0", Some(44662), None),
+    // allow `#[must_use]` on functions; and, must-use operators (RFC 1940)
+    (accepted, fn_must_use, "1.27.0", Some(43302), None),
 );
 
 // If you change this, please modify src/doc/unstable-book as well. You must
@@ -674,7 +678,6 @@ pub fn is_builtin_attr(attr: &ast::Attribute) -> bool {
     ("forbid", Normal, Ungated),
     ("deny", Normal, Ungated),
 
-    ("macro_reexport", Normal, Ungated),
     ("macro_use", Normal, Ungated),
     ("macro_export", Normal, Ungated),
     ("plugin_registrar", Normal, Ungated),
@@ -1079,7 +1082,7 @@ pub struct GatedCfg {
 
 impl GatedCfg {
     pub fn gate(cfg: &ast::MetaItem) -> Option<GatedCfg> {
-        let name = cfg.ident.name.as_str();
+        let name = cfg.name().as_str();
         GATED_CFGS.iter()
                   .position(|info| info.0 == name)
                   .map(|idx| {
@@ -1132,7 +1135,7 @@ macro_rules! gate_feature {
 impl<'a> Context<'a> {
     fn check_attribute(&self, attr: &ast::Attribute, is_macro: bool) {
         debug!("check_attribute(attr = {:?})", attr);
-        let name = unwrap_or!(attr.name(), return).as_str();
+        let name = attr.name().as_str();
         for &(n, ty, ref gateage) in BUILTIN_ATTRIBUTES {
             if name == n {
                 if let Gated(_, name, desc, ref has_feature) = *gateage {
@@ -1172,12 +1175,28 @@ fn check_attribute(&self, attr: &ast::Attribute, is_macro: bool) {
             // before the plugin attributes are registered
             // so we skip this then
             if !is_macro {
-                gate_feature!(self, custom_attribute, attr.span,
-                              &format!("The attribute `{}` is currently \
-                                        unknown to the compiler and \
-                                        may have meaning \
-                                        added to it in the future",
-                                       attr.path));
+                if attr.is_scoped() {
+                    gate_feature!(self, tool_attributes, attr.span,
+                                  &format!("scoped attribute `{}` is experimental", attr.path));
+                    if attr::is_known_tool(attr) {
+                        attr::mark_used(attr);
+                    } else {
+                        span_err!(
+                            self.parse_sess.span_diagnostic,
+                            attr.span,
+                            E0694,
+                            "an unknown tool name found in scoped attribute: `{}`.",
+                            attr.path
+                        );
+                    }
+                } else {
+                    gate_feature!(self, custom_attribute, attr.span,
+                                  &format!("The attribute `{}` is currently \
+                                            unknown to the compiler and \
+                                            may have meaning \
+                                            added to it in the future",
+                                           attr.path));
+                }
             }
         }
     }
@@ -1203,7 +1222,7 @@ fn find_lang_feature_issue(feature: &str) -> Option<u32> {
         let found = ACCEPTED_FEATURES.iter().chain(REMOVED_FEATURES).chain(STABLE_REMOVED_FEATURES)
             .find(|t| t.0 == feature);
         match found {
-            Some(&(_, _, issue)) => issue,
+            Some(&(_, _, issue, _)) => issue,
             None => panic!("Feature `{}` is not declared anywhere", feature),
         }
     }
@@ -1517,11 +1536,6 @@ fn visit_item(&mut self, i: &'a ast::Item) {
                     gate_feature_post!(&self, underscore_imports, i.span,
                                        "renaming extern crates with `_` is unstable");
                 }
-                if let Some(attr) = attr::find_by_name(&i.attrs[..], "macro_reexport") {
-                    gate_feature_post!(&self, macro_reexport, attr.span,
-                                       "macros re-exports are experimental \
-                                        and possibly buggy");
-                }
             }
 
             ast::ItemKind::ForeignMod(ref foreign_module) => {
@@ -1545,11 +1559,6 @@ fn visit_item(&mut self, i: &'a ast::Item) {
                                         function may change over time, for now \
                                         a top-level `fn main()` is required");
                 }
-                if let Some(attr) = attr::find_by_name(&i.attrs[..], "must_use") {
-                    gate_feature_post!(&self, fn_must_use, attr.span,
-                                       "`#[must_use]` on functions is experimental",
-                                       GateStrength::Soft);
-                }
             }
 
             ast::ItemKind::Struct(..) => {
@@ -1581,7 +1590,7 @@ fn visit_item(&mut self, i: &'a ast::Item) {
                                    "trait aliases are not yet fully implemented");
             }
 
-            ast::ItemKind::Impl(_, polarity, defaultness, _, _, _, ref impl_items) => {
+            ast::ItemKind::Impl(_, polarity, defaultness, _, _, _, _) => {
                 if polarity == ast::ImplPolarity::Negative {
                     gate_feature_post!(&self, optin_builtin_traits,
                                        i.span,
@@ -1594,16 +1603,6 @@ fn visit_item(&mut self, i: &'a ast::Item) {
                                        i.span,
                                        "specialization is unstable");
                 }
-
-                for impl_item in impl_items {
-                    if let ast::ImplItemKind::Method(..) = impl_item.node {
-                        if let Some(attr) = attr::find_by_name(&impl_item.attrs[..], "must_use") {
-                            gate_feature_post!(&self, fn_must_use, attr.span,
-                                               "`#[must_use]` on methods is experimental",
-                                               GateStrength::Soft);
-                        }
-                    }
-                }
             }
 
             ast::ItemKind::Trait(ast::IsAuto::Yes, ..) => {
@@ -1837,8 +1836,12 @@ fn visit_vis(&mut self, vis: &'a ast::Visibility) {
 
 pub fn get_features(span_handler: &Handler, krate_attrs: &[ast::Attribute],
                     crate_edition: Edition) -> Features {
-    fn feature_removed(span_handler: &Handler, span: Span) {
-        span_err!(span_handler, span, E0557, "feature has been removed");
+    fn feature_removed(span_handler: &Handler, span: Span, reason: Option<&str>) {
+        let mut err = struct_span_err!(span_handler, span, E0557, "feature has been removed");
+        if let Some(reason) = reason {
+            err.span_note(span, reason);
+        }
+        err.emit();
     }
 
     let mut features = Features::new();
@@ -1859,7 +1862,7 @@ fn feature_removed(span_handler: &Handler, span: Span) {
                 for mi in list {
 
                     let name = if let Some(word) = mi.word() {
-                        word.ident.name
+                        word.name()
                     } else {
                         span_err!(span_handler, mi.span, E0556,
                                   "malformed feature, expected just one word");
@@ -1871,19 +1874,19 @@ fn feature_removed(span_handler: &Handler, span: Span) {
                         set(&mut features, mi.span);
                         feature_checker.collect(&features, mi.span);
                     }
-                    else if let Some(&(_, _, _)) = REMOVED_FEATURES.iter()
-                            .find(|& &(n, _, _)| name == n)
+                    else if let Some(&(.., reason)) = REMOVED_FEATURES.iter()
+                            .find(|& &(n, ..)| name == n)
                         .or_else(|| STABLE_REMOVED_FEATURES.iter()
-                            .find(|& &(n, _, _)| name == n)) {
-                        feature_removed(span_handler, mi.span);
+                            .find(|& &(n, ..)| name == n)) {
+                        feature_removed(span_handler, mi.span, reason);
                     }
-                    else if let Some(&(_, _, _)) = ACCEPTED_FEATURES.iter()
-                        .find(|& &(n, _, _)| name == n) {
+                    else if let Some(&(..)) = ACCEPTED_FEATURES.iter()
+                        .find(|& &(n, ..)| name == n) {
                         features.declared_stable_lang_features.push((name, mi.span));
                     } else if let Some(&edition) = ALL_EDITIONS.iter()
                                                               .find(|e| name == e.feature_name()) {
                         if edition <= crate_edition {
-                            feature_removed(span_handler, mi.span);
+                            feature_removed(span_handler, mi.span, None);
                         } else {
                             for &(.., f_edition, set) in ACTIVE_FEATURES.iter() {
                                 if let Some(f_edition) = f_edition {
index 870ce1926ade43995c4da7a627b03c43f799a58d..f148aaf7267eec9dc581fdfc025d8f2884df44b6 100644 (file)
@@ -25,6 +25,7 @@
 #![feature(non_exhaustive)]
 #![feature(const_atomic_usize_new)]
 #![feature(rustc_attrs)]
+#![feature(str_escape)]
 
 #![recursion_limit="256"]
 
index 90f08ab1468e212ca37cce4df7ae0f7bf6e669c0..cceed589212561c06d0482a79b7f011222956156 100644 (file)
@@ -149,7 +149,7 @@ pub fn parse_path_and_tokens(&mut self) -> PResult<'a, (ast::Path, TokenStream)>
         };
         Ok(if let Some(meta) = meta {
             self.bump();
-            (ast::Path::from_ident(meta.ident), meta.node.tokens(meta.span))
+            (meta.ident, meta.node.tokens(meta.span))
         } else {
             (self.parse_path(PathStyle::Mod)?, self.parse_tokens())
         })
@@ -225,9 +225,10 @@ pub fn parse_meta_item(&mut self) -> PResult<'a, ast::MetaItem> {
         }
 
         let lo = self.span;
-        let ident = self.parse_ident()?;
+        let ident = self.parse_path(PathStyle::Mod)?;
         let node = self.parse_meta_item_kind()?;
-        Ok(ast::MetaItem { ident, node: node, span: lo.to(self.prev_span) })
+        let span = lo.to(self.prev_span);
+        Ok(ast::MetaItem { ident, node, span })
     }
 
     pub fn parse_meta_item_kind(&mut self) -> PResult<'a, ast::MetaItemKind> {
index ff09c6aa2f006c9f7f23eb197ddd012e65927c72..f252020bc31698836dc454794a6a8588288a8327 100644 (file)
@@ -298,14 +298,10 @@ pub fn char_lit(lit: &str, diag: Option<(Span, &Handler)>) -> (char, isize) {
     }
 }
 
-pub fn escape_default(s: &str) -> String {
-    s.chars().map(char::escape_default).flat_map(|x| x).collect()
-}
-
 /// Parse a string representing a string literal into its final form. Does
 /// unescaping.
 pub fn str_lit(lit: &str, diag: Option<(Span, &Handler)>) -> String {
-    debug!("parse_str_lit: given {}", escape_default(lit));
+    debug!("str_lit: given {}", lit.escape_default());
     let mut res = String::with_capacity(lit.len());
 
     let error = |i| format!("lexer should have rejected {} at {}", lit, i);
@@ -374,7 +370,7 @@ fn eat<'a>(it: &mut iter::Peekable<str::CharIndices<'a>>) {
 /// Parse a string representing a raw string literal into its final form. The
 /// only operation this does is convert embedded CRLF into a single LF.
 pub fn raw_str_lit(lit: &str) -> String {
-    debug!("raw_str_lit: given {}", escape_default(lit));
+    debug!("raw_str_lit: given {}", lit.escape_default());
     let mut res = String::with_capacity(lit.len());
 
     let mut chars = lit.chars().peekable();
index 324cadc84e862722281a3a07950a19206f7eb410..bf4a68679df55aacb3637bcaf8b7c5cab1bb5882 100644 (file)
@@ -1958,16 +1958,16 @@ pub fn parse_path_allowing_meta(&mut self, style: PathStyle) -> PResult<'a, ast:
         let meta_ident = match self.token {
             token::Interpolated(ref nt) => match nt.0 {
                 token::NtMeta(ref meta) => match meta.node {
-                    ast::MetaItemKind::Word => Some(meta.ident),
+                    ast::MetaItemKind::Word => Some(meta.ident.clone()),
                     _ => None,
                 },
                 _ => None,
             },
             _ => None,
         };
-        if let Some(ident) = meta_ident {
+        if let Some(path) = meta_ident {
             self.bump();
-            return Ok(ast::Path::from_ident(ident));
+            return Ok(path);
         }
         self.parse_path(style)
     }
@@ -2042,7 +2042,7 @@ fn parse_path_segment(&mut self, style: PathStyle, enable_warning: bool)
         })
     }
 
-    fn check_lifetime(&mut self) -> bool {
+    pub fn check_lifetime(&mut self) -> bool {
         self.expected_tokens.push(TokenType::Lifetime);
         self.token.is_lifetime()
     }
index 5c4bf47a6db435db4aea40cbe348becf76900618..e7bd369053cf9c98aed73e40fdfd3e7b2f961686 100644 (file)
@@ -247,12 +247,14 @@ pub fn mk_printer<'a>(out: Box<io::Write+'a>, linewidth: usize) -> Printer<'a> {
     debug!("mk_printer {}", linewidth);
     Printer {
         out,
-        buf_len: n,
+        buf_max_len: n,
         margin: linewidth as isize,
         space: linewidth as isize,
         left: 0,
         right: 0,
-        buf: vec![BufEntry { token: Token::Eof, size: 0 }; n],
+        // Initialize a single entry; advance_right() will extend it on demand
+        // up to `buf_max_len` elements.
+        buf: vec![BufEntry::default()],
         left_total: 0,
         right_total: 0,
         scan_stack: VecDeque::new(),
@@ -263,7 +265,7 @@ pub fn mk_printer<'a>(out: Box<io::Write+'a>, linewidth: usize) -> Printer<'a> {
 
 pub struct Printer<'a> {
     out: Box<io::Write+'a>,
-    buf_len: usize,
+    buf_max_len: usize,
     /// Width of lines we're constrained to
     margin: isize,
     /// Number of spaces left on line
@@ -297,6 +299,12 @@ struct BufEntry {
     size: isize,
 }
 
+impl Default for BufEntry {
+    fn default() -> Self {
+        BufEntry { token: Token::Eof, size: 0 }
+    }
+}
+
 impl<'a> Printer<'a> {
     pub fn last_token(&mut self) -> Token {
         self.buf[self.right].token.clone()
@@ -322,7 +330,9 @@ pub fn pretty_print(&mut self, token: Token) -> io::Result<()> {
                 self.right_total = 1;
                 self.left = 0;
                 self.right = 0;
-            } else { self.advance_right(); }
+            } else {
+                self.advance_right();
+            }
             debug!("pp Begin({})/buffer Vec<{},{}>",
                    b.offset, self.left, self.right);
             self.buf[self.right] = BufEntry { token: token, size: -self.right_total };
@@ -349,7 +359,9 @@ pub fn pretty_print(&mut self, token: Token) -> io::Result<()> {
                 self.right_total = 1;
                 self.left = 0;
                 self.right = 0;
-            } else { self.advance_right(); }
+            } else {
+                self.advance_right();
+            }
             debug!("pp Break({})/buffer Vec<{},{}>",
                    b.offset, self.left, self.right);
             self.check_stack(0);
@@ -408,7 +420,11 @@ pub fn scan_pop_bottom(&mut self) -> usize {
     }
     pub fn advance_right(&mut self) {
         self.right += 1;
-        self.right %= self.buf_len;
+        self.right %= self.buf_max_len;
+        // Extend the buf if necessary.
+        if self.right == self.buf.len() {
+            self.buf.push(BufEntry::default());
+        }
         assert_ne!(self.right, self.left);
     }
     pub fn advance_left(&mut self) -> io::Result<()> {
@@ -438,7 +454,7 @@ pub fn advance_left(&mut self) -> io::Result<()> {
             }
 
             self.left += 1;
-            self.left %= self.buf_len;
+            self.left %= self.buf_max_len;
 
             left_size = self.buf[self.left].size;
         }
index 88860df10e2c3766fb60755d96fff84838671154..d8228e2b28be71ac39ed3dfdeb54ab0aef50805f 100644 (file)
@@ -656,7 +656,7 @@ fn print_string(&mut self, st: &str,
                     style: ast::StrStyle) -> io::Result<()> {
         let st = match style {
             ast::StrStyle::Cooked => {
-                (format!("\"{}\"", parse::escape_default(st)))
+                (format!("\"{}\"", st.escape_default()))
             }
             ast::StrStyle::Raw(n) => {
                 (format!("r{delim}\"{string}\"{delim}",
@@ -714,6 +714,22 @@ fn print_either_attributes(&mut self,
         Ok(())
     }
 
+    fn print_attribute_path(&mut self, path: &ast::Path) -> io::Result<()> {
+        for (i, segment) in path.segments.iter().enumerate() {
+            if i > 0 {
+                self.writer().word("::")?
+            }
+            if segment.ident.name != keywords::CrateRoot.name() &&
+               segment.ident.name != keywords::DollarCrate.name()
+            {
+                self.writer().word(&segment.ident.name.as_str())?;
+            } else if segment.ident.name == keywords::DollarCrate.name() {
+                self.print_dollar_crate(segment.ident.span.ctxt())?;
+            }
+        }
+        Ok(())
+    }
+
     fn print_attribute(&mut self, attr: &ast::Attribute) -> io::Result<()> {
         self.print_attribute_inline(attr, false)
     }
@@ -735,17 +751,7 @@ fn print_attribute_inline(&mut self, attr: &ast::Attribute,
             if let Some(mi) = attr.meta() {
                 self.print_meta_item(&mi)?
             } else {
-                for (i, segment) in attr.path.segments.iter().enumerate() {
-                    if i > 0 {
-                        self.writer().word("::")?
-                    }
-                    if segment.ident.name != keywords::CrateRoot.name() &&
-                       segment.ident.name != keywords::DollarCrate.name() {
-                        self.writer().word(&segment.ident.name.as_str())?;
-                    } else if segment.ident.name == keywords::DollarCrate.name() {
-                        self.print_dollar_crate(segment.ident.span.ctxt())?;
-                    }
-                }
+                self.print_attribute_path(&attr.path)?;
                 self.writer().space()?;
                 self.print_tts(attr.tokens.clone())?;
             }
@@ -767,16 +773,15 @@ fn print_meta_list_item(&mut self, item: &ast::NestedMetaItem) -> io::Result<()>
     fn print_meta_item(&mut self, item: &ast::MetaItem) -> io::Result<()> {
         self.ibox(INDENT_UNIT)?;
         match item.node {
-            ast::MetaItemKind::Word => {
-                self.writer().word(&item.ident.name.as_str())?;
-            }
+            ast::MetaItemKind::Word => self.print_attribute_path(&item.ident)?,
             ast::MetaItemKind::NameValue(ref value) => {
-                self.word_space(&item.ident.name.as_str())?;
+                self.print_attribute_path(&item.ident)?;
+                self.writer().space()?;
                 self.word_space("=")?;
                 self.print_literal(value)?;
             }
             ast::MetaItemKind::List(ref items) => {
-                self.writer().word(&item.ident.name.as_str())?;
+                self.print_attribute_path(&item.ident)?;
                 self.popen()?;
                 self.commasep(Consistent,
                               &items[..],
index 544b1410d3d912135d8550c01d5345635ebb40d6..b8345e7cf40c109431a740ab8aea7b19efb46a24 100644 (file)
@@ -31,6 +31,11 @@ pub fn expand_syntax_ext<'cx>(cx: &'cx mut ExtCtxt,
         return base::DummyResult::expr(sp);
     }
 
+    if tts.is_empty() {
+        cx.span_err(sp, "concat_idents! takes 1 or more arguments.");
+        return DummyResult::expr(sp);
+    }
+
     let mut res_str = String::new();
     for (i, e) in tts.iter().enumerate() {
         if i & 1 == 1 {
index 5fd5e29948852589b585a25df482ee72b82509a6..76da1746a0397a100b4901f9e55d4dcd0b997800 100644 (file)
 
 impl<'a> Visitor<'a> for MarkAttrs<'a> {
     fn visit_attribute(&mut self, attr: &Attribute) {
-        if let Some(name) = attr.name() {
-            if self.0.contains(&name) {
-                mark_used(attr);
-                mark_known(attr);
-            }
+        if self.0.contains(&attr.name()) {
+            mark_used(attr);
+            mark_known(attr);
         }
     }
 
index becd70149fd1e96b3964623b459c3b8fb3f96264..80f65957c39a2e3935c41ef99b961c2c083e50bd 100644 (file)
@@ -472,7 +472,7 @@ pub fn expand_ext(self,
                 attrs.extend(item.attrs
                     .iter()
                     .filter(|a| {
-                        a.name().is_some() && match &*a.name().unwrap().as_str() {
+                        match &*a.name().as_str() {
                             "allow" | "warn" | "deny" | "forbid" | "stable" | "unstable" => true,
                             _ => false,
                         }
index 8d37b4aa3968f5c84deaa5cd3383eb13ba21e4d2..8b4a3ea26a1ef7dca52f5a179e2f0110c7ea5f3f 100644 (file)
@@ -1150,13 +1150,17 @@ pub trait Pos {
 // have been unsuccessful
 
 impl Pos for BytePos {
+    #[inline(always)]
     fn from_usize(n: usize) -> BytePos { BytePos(n as u32) }
+
+    #[inline(always)]
     fn to_usize(&self) -> usize { let BytePos(n) = *self; n as usize }
 }
 
 impl Add for BytePos {
     type Output = BytePos;
 
+    #[inline(always)]
     fn add(self, rhs: BytePos) -> BytePos {
         BytePos((self.to_usize() + rhs.to_usize()) as u32)
     }
@@ -1165,6 +1169,7 @@ fn add(self, rhs: BytePos) -> BytePos {
 impl Sub for BytePos {
     type Output = BytePos;
 
+    #[inline(always)]
     fn sub(self, rhs: BytePos) -> BytePos {
         BytePos((self.to_usize() - rhs.to_usize()) as u32)
     }
@@ -1183,13 +1188,17 @@ fn decode<D: Decoder>(d: &mut D) -> Result<BytePos, D::Error> {
 }
 
 impl Pos for CharPos {
+    #[inline(always)]
     fn from_usize(n: usize) -> CharPos { CharPos(n) }
+
+    #[inline(always)]
     fn to_usize(&self) -> usize { let CharPos(n) = *self; n }
 }
 
 impl Add for CharPos {
     type Output = CharPos;
 
+    #[inline(always)]
     fn add(self, rhs: CharPos) -> CharPos {
         CharPos(self.to_usize() + rhs.to_usize())
     }
@@ -1198,6 +1207,7 @@ fn add(self, rhs: CharPos) -> CharPos {
 impl Sub for CharPos {
     type Output = CharPos;
 
+    #[inline(always)]
     fn sub(self, rhs: CharPos) -> CharPos {
         CharPos(self.to_usize() - rhs.to_usize())
     }
diff --git a/src/test/codegen/force-frame-pointers.rs b/src/test/codegen/force-frame-pointers.rs
new file mode 100644 (file)
index 0000000..f70e366
--- /dev/null
@@ -0,0 +1,16 @@
+// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+//
+// compile-flags: -C no-prepopulate-passes -C force-frame-pointers=y
+
+#![crate_type="lib"]
+
+// CHECK: attributes #{{.*}} "no-frame-pointer-elim"="true"
+pub fn foo() {}
index 24a5a4e44cb297a6463b06310c50703e41da9e79..7239223ca2019d032b2faa749bdf851f61843a72 100644 (file)
@@ -8,17 +8,27 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// compile-flags: -g -C no-prepopulate-passes
 // ignore-tidy-linelength
 // min-llvm-version 4.0
 
-// compile-flags: -g -C no-prepopulate-passes
-
-// CHECK: {{.*}}DISubprogram{{.*}}name: "foo"{{.*}}DIFlagNoReturn
+#![crate_type = "lib"]
 
-fn foo() -> ! {
+#[no_mangle]
+pub fn foo() -> ! {
+// CHECK: @foo() unnamed_addr #0
     loop {}
 }
 
-pub fn main() {
-    foo();
+pub enum EmptyEnum {}
+
+#[no_mangle]
+pub fn bar() -> EmptyEnum {
+// CHECK: @bar() unnamed_addr #0
+    loop {}
 }
+
+// CHECK: attributes #0 = {{{.*}} noreturn {{.*}}}
+
+// CHECK: DISubprogram(name: "foo", {{.*}} DIFlagNoReturn
+// CHECK: DISubprogram(name: "bar", {{.*}} DIFlagNoReturn
index 040f0b661be14fab1b21698a682b0e837f29dad7..fb0f9105b0d8a949cf2501a33bafd242c95fe443 100644 (file)
@@ -117,7 +117,7 @@ fn expand_duplicate(cx: &mut ExtCtxt,
     let copy_name = match mi.node {
         ast::MetaItemKind::List(ref xs) => {
             if let Some(word) = xs[0].word() {
-                word.ident
+                word.ident.segments.last().unwrap().ident
             } else {
                 cx.span_err(mi.span, "Expected word");
                 return;
diff --git a/src/test/compile-fail-fulldeps/gated-macro-reexports.rs b/src/test/compile-fail-fulldeps/gated-macro-reexports.rs
deleted file mode 100644 (file)
index 8b448e4..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// Test that macro re-exports item are gated by `macro_reexport` feature gate.
-
-// aux-build:macro_reexport_1.rs
-// gate-test-macro_reexport
-
-#![crate_type = "dylib"]
-
-#[macro_reexport(reexported)]
-//~^ ERROR macros re-exports are experimental and possibly buggy
-#[macro_use] #[no_link]
-extern crate macro_reexport_1;
diff --git a/src/test/compile-fail/auxiliary/macro_non_reexport_2.rs b/src/test/compile-fail/auxiliary/macro_non_reexport_2.rs
deleted file mode 100644 (file)
index 910fcd2..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-#![crate_type = "dylib"]
-
-// Since we load a serialized macro with all its attributes, accidentally
-// re-exporting a `#[macro_export] macro_rules!` is something of a concern!
-//
-// We avoid it at the moment only because of the order in which we do things.
-
-#[macro_use] #[no_link]
-extern crate macro_reexport_1;
diff --git a/src/test/compile-fail/auxiliary/macro_reexport_1.rs b/src/test/compile-fail/auxiliary/macro_reexport_1.rs
deleted file mode 100644 (file)
index aaeccc6..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-#![crate_type = "dylib"]
-#[macro_export]
-macro_rules! reexported {
-    () => ( 3 )
-}
diff --git a/src/test/compile-fail/feature-gate-tool_attributes.rs b/src/test/compile-fail/feature-gate-tool_attributes.rs
new file mode 100644 (file)
index 0000000..5a7536c
--- /dev/null
@@ -0,0 +1,15 @@
+// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+fn main() {
+    #[rustfmt::skip] //~ ERROR scoped attribute `rustfmt::skip` is experimental
+    let x =
+        3;
+}
diff --git a/src/test/compile-fail/macro-no-implicit-reexport.rs b/src/test/compile-fail/macro-no-implicit-reexport.rs
deleted file mode 100644 (file)
index 07467e0..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// aux-build:macro_reexport_1.rs
-// aux-build:macro_non_reexport_2.rs
-
-#[macro_use] #[no_link]
-extern crate macro_non_reexport_2;
-
-fn main() {
-    assert_eq!(reexported!(), 3);
-    //~^ ERROR cannot find macro `reexported!` in this scope
-}
diff --git a/src/test/compile-fail/macro-non-lifetime.rs b/src/test/compile-fail/macro-non-lifetime.rs
new file mode 100644 (file)
index 0000000..a2706e8
--- /dev/null
@@ -0,0 +1,20 @@
+// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// Test for issue #50381: non-lifetime passed to :lifetime.
+
+#![feature(macro_lifetime_matcher)]
+
+macro_rules! m { ($x:lifetime) => { } }
+
+fn main() {
+    m!(a);
+    //~^ ERROR expected a lifetime, found `a`
+}
diff --git a/src/test/compile-fail/macro-reexport-malformed-1.rs b/src/test/compile-fail/macro-reexport-malformed-1.rs
deleted file mode 100644 (file)
index 36a6fce..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
-// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-#![no_std]
-#![feature(macro_reexport)]
-
-#[allow(unused_extern_crates)]
-#[macro_reexport]  //~ ERROR bad macro re-export
-extern crate std;
diff --git a/src/test/compile-fail/macro-reexport-malformed-2.rs b/src/test/compile-fail/macro-reexport-malformed-2.rs
deleted file mode 100644 (file)
index 5f741d0..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
-// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-#![no_std]
-#![feature(macro_reexport)]
-
-#[allow(unused_extern_crates)]
-#[macro_reexport="foo"]  //~ ERROR bad macro re-export
-extern crate std;
diff --git a/src/test/compile-fail/macro-reexport-malformed-3.rs b/src/test/compile-fail/macro-reexport-malformed-3.rs
deleted file mode 100644 (file)
index 1a7e3b9..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
-// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-#![no_std]
-#![feature(macro_reexport)]
-
-#[allow(unused_extern_crates)]
-#[macro_reexport(foo="bar")]  //~ ERROR bad macro re-export
-extern crate std;
diff --git a/src/test/compile-fail/macro-reexport-not-locally-visible.rs b/src/test/compile-fail/macro-reexport-not-locally-visible.rs
deleted file mode 100644 (file)
index 54a74b0..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// aux-build:macro_reexport_1.rs
-
-#![feature(macro_reexport)]
-
-#[macro_reexport(reexported)]
-#[no_link]
-extern crate macro_reexport_1;
-
-fn main() {
-    assert_eq!(reexported!(), 3);
-    //~^ ERROR cannot find macro
-}
diff --git a/src/test/compile-fail/macro-reexport-undef.rs b/src/test/compile-fail/macro-reexport-undef.rs
deleted file mode 100644 (file)
index 50ac89e..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// aux-build:two_macros.rs
-
-#![feature(macro_reexport)]
-
-#[macro_use(macro_two)]
-#[macro_reexport(no_way)] //~ ERROR re-exported macro not found
-extern crate two_macros;
-
-pub fn main() {
-    macro_two!();
-}
index 7c8eb6a2de93aaf71d26e30076906020769cd9a6..9b0408de2a4fc8628fc4e9e8e78691debeedf08a 100644 (file)
 #[repr(align(15))] //~ ERROR: invalid `repr(align)` attribute: not a power of two
 struct B(i32);
 
-#[repr(align(4294967296))] //~ ERROR: invalid `repr(align)` attribute: larger than 2147483647
+#[repr(align(4294967296))] //~ ERROR: invalid `repr(align)` attribute: larger than 2^29
 struct C(i32);
 
+#[repr(align(536870912))] // ok: this is the largest accepted alignment
+struct D(i32);
+
 fn main() {}
diff --git a/src/test/compile-fail/unknown-tool-name.rs b/src/test/compile-fail/unknown-tool-name.rs
new file mode 100644 (file)
index 0000000..c2192a2
--- /dev/null
@@ -0,0 +1,16 @@
+// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![feature(tool_attributes)]
+
+#![foo::bar] //~ ERROR an unknown tool name found in scoped attribute: `foo::bar`. [E0694]
+
+#[foo::bar] //~ ERROR an unknown tool name found in scoped attribute: `foo::bar`. [E0694]
+fn main() {}
diff --git a/src/test/compile-fail/unknown_tool_attributes-1.rs b/src/test/compile-fail/unknown_tool_attributes-1.rs
new file mode 100644 (file)
index 0000000..ba38c29
--- /dev/null
@@ -0,0 +1,18 @@
+// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// Make sure that 'custom_attributes' feature does not allow scoped attributes.
+
+#![feature(custom_attributes)]
+
+#[foo::bar]
+//~^ ERROR scoped attribute `foo::bar` is experimental (see issue #44690) [E0658]
+//~^^ ERROR an unknown tool name found in scoped attribute: `foo::bar`. [E0694]
+fn main() {}
diff --git a/src/test/run-make-fulldeps/extern-prelude/Makefile b/src/test/run-make-fulldeps/extern-prelude/Makefile
new file mode 100644 (file)
index 0000000..aa8158c
--- /dev/null
@@ -0,0 +1,12 @@
+-include ../tools.mk
+
+all:
+       $(RUSTC) ep-lib.rs
+       $(RUSTC) ep-vec.rs
+
+       $(RUSTC) basic.rs --extern ep_lib=$(TMPDIR)/libep_lib.rlib
+       $(RUSTC) shadow-mod.rs --extern ep_lib=$(TMPDIR)/libep_lib.rlib
+       $(RUSTC) shadow-prelude.rs --extern Vec=$(TMPDIR)/libep_vec.rlib
+       $(RUSTC) feature-gate.rs --extern ep_lib=$(TMPDIR)/libep_lib.rlib 2>&1 | $(CGREP) "access to extern crates through prelude is experimental"
+       $(RUSTC) relative-only.rs --extern ep_lib=$(TMPDIR)/libep_lib.rlib 2>&1 | $(CGREP) "unresolved import"
+       $(RUSTC) relative-only.rs --extern ep_lib=$(TMPDIR)/libep_lib.rlib 2>&1 | $(CGREP) "failed to resolve"
diff --git a/src/test/run-make-fulldeps/extern-prelude/basic.rs b/src/test/run-make-fulldeps/extern-prelude/basic.rs
new file mode 100644 (file)
index 0000000..b8d6a77
--- /dev/null
@@ -0,0 +1,16 @@
+// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![feature(extern_prelude)]
+
+fn main() {
+    let s = ep_lib::S; // It works
+    s.external();
+}
diff --git a/src/test/run-make-fulldeps/extern-prelude/ep-lib.rs b/src/test/run-make-fulldeps/extern-prelude/ep-lib.rs
new file mode 100644 (file)
index 0000000..dac0a3c
--- /dev/null
@@ -0,0 +1,17 @@
+// 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_type = "rlib"]
+
+pub struct S;
+
+impl S {
+    pub fn external(&self) {}
+}
diff --git a/src/test/run-make-fulldeps/extern-prelude/ep-vec.rs b/src/test/run-make-fulldeps/extern-prelude/ep-vec.rs
new file mode 100644 (file)
index 0000000..f750a26
--- /dev/null
@@ -0,0 +1,13 @@
+// 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_type = "rlib"]
+
+pub fn new(arg1: f32, arg2: ()) {}
diff --git a/src/test/run-make-fulldeps/extern-prelude/feature-gate.rs b/src/test/run-make-fulldeps/extern-prelude/feature-gate.rs
new file mode 100644 (file)
index 0000000..49763f3
--- /dev/null
@@ -0,0 +1,13 @@
+// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+fn main() {
+    let s = ep_lib::S; // Feature error
+}
diff --git a/src/test/run-make-fulldeps/extern-prelude/relative-only.rs b/src/test/run-make-fulldeps/extern-prelude/relative-only.rs
new file mode 100644 (file)
index 0000000..0cd56b9
--- /dev/null
@@ -0,0 +1,19 @@
+// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// Extern prelude names are not available by absolute paths
+
+#![feature(extern_prelude)]
+
+use ep_lib::S;
+
+fn main() {
+    let s = ::ep_lib::S;
+}
diff --git a/src/test/run-make-fulldeps/extern-prelude/shadow-mod.rs b/src/test/run-make-fulldeps/extern-prelude/shadow-mod.rs
new file mode 100644 (file)
index 0000000..52213c8
--- /dev/null
@@ -0,0 +1,24 @@
+// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// Local module shadows `ep_lib` from extern prelude
+
+mod ep_lib {
+    pub struct S;
+
+    impl S {
+        pub fn internal(&self) {}
+    }
+}
+
+fn main() {
+    let s = ep_lib::S;
+    s.internal(); // OK
+}
diff --git a/src/test/run-make-fulldeps/extern-prelude/shadow-prelude.rs b/src/test/run-make-fulldeps/extern-prelude/shadow-prelude.rs
new file mode 100644 (file)
index 0000000..de1c4d1
--- /dev/null
@@ -0,0 +1,17 @@
+// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// Extern prelude shadows standard library prelude
+
+#![feature(extern_prelude)]
+
+fn main() {
+    let x = Vec::new(0f32, ()); // OK
+}
index 2f80408ac1ce98833c65cefe424f84039810e961..d698af50579ad91de914d062717fb131dd8077c6 100644 (file)
@@ -112,7 +112,7 @@ fn expand_duplicate(cx: &mut ExtCtxt,
     let copy_name = match mi.node {
         ast::MetaItemKind::List(ref xs) => {
             if let Some(word) = xs[0].word() {
-                word.ident
+                word.ident.segments.last().unwrap().ident
             } else {
                 cx.span_err(mi.span, "Expected word");
                 return;
diff --git a/src/test/run-pass-fulldeps/proc-macro/auxiliary/derive-reexport.rs b/src/test/run-pass-fulldeps/proc-macro/auxiliary/derive-reexport.rs
deleted file mode 100644 (file)
index cfaf913..0000000
+++ /dev/null
@@ -1,16 +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.
-
-// ignore-test not a test, auxiliary
-
-#![feature(macro_reexport)]
-
-#[macro_reexport(A)]
-extern crate derive_a;
diff --git a/src/test/run-pass-fulldeps/proc-macro/use-reexport.rs b/src/test/run-pass-fulldeps/proc-macro/use-reexport.rs
deleted file mode 100644 (file)
index 03dfeb1..0000000
+++ /dev/null
@@ -1,21 +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.
-
-// aux-build:derive-a.rs
-// aux-build:derive-reexport.rs
-// ignore-stage1
-
-#[macro_use]
-extern crate derive_reexport;
-
-#[derive(Debug, PartialEq, A, Eq, Copy, Clone)]
-struct A;
-
-fn main() {}
diff --git a/src/test/run-pass/auxiliary/macro_reexport_1.rs b/src/test/run-pass/auxiliary/macro_reexport_1.rs
deleted file mode 100644 (file)
index aaeccc6..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-#![crate_type = "dylib"]
-#[macro_export]
-macro_rules! reexported {
-    () => ( 3 )
-}
diff --git a/src/test/run-pass/auxiliary/macro_reexport_2.rs b/src/test/run-pass/auxiliary/macro_reexport_2.rs
deleted file mode 100644 (file)
index 3918be8..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
-// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-#![crate_type = "dylib"]
-#![feature(macro_reexport)]
-
-#[macro_reexport(reexported)]
-#[macro_use] #[no_link]
-extern crate macro_reexport_1;
diff --git a/src/test/run-pass/auxiliary/macro_reexport_2_no_use.rs b/src/test/run-pass/auxiliary/macro_reexport_2_no_use.rs
deleted file mode 100644 (file)
index 1d3dc26..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
-// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-#![crate_type = "dylib"]
-#![feature(macro_reexport)]
-
-#[macro_reexport(reexported)]
-#[no_link]
-extern crate macro_reexport_1;
index 2b82a8943636e4364b9af550d6d42bc6777af1be..7bcb4e5ec2d2efee06d07c111e393bb31a978854 100644 (file)
@@ -16,6 +16,7 @@
 // "enable" to 0 instead.
 
 // compile-flags:-g -Cllvm-args=-enable-tail-merge=0 -Cllvm-args=-opt-bisect-limit=0
+// compile-flags:-Cforce-frame-pointers=yes
 // ignore-pretty issue #37195
 // ignore-cloudabi spawning processes is not supported
 // ignore-emscripten spawning processes is not supported
diff --git a/src/test/run-pass/extern-prelude-no-speculative.rs b/src/test/run-pass/extern-prelude-no-speculative.rs
new file mode 100644 (file)
index 0000000..ff3aec4
--- /dev/null
@@ -0,0 +1,21 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// compile-flags: --extern LooksLikeExternCrate=/path/to/nowhere
+
+mod m {
+    pub struct LooksLikeExternCrate;
+}
+
+fn main() {
+    // OK, speculative resolution for `unused_qualifications` doesn't try
+    // to resolve this as an extern crate and load that crate
+    let s = m::LooksLikeExternCrate {};
+}
diff --git a/src/test/run-pass/issue-50415.rs b/src/test/run-pass/issue-50415.rs
new file mode 100644 (file)
index 0000000..aa493ce
--- /dev/null
@@ -0,0 +1,27 @@
+// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+fn main() {
+    // -------- Simplified test case --------
+
+    let _ = || 0..=1;
+
+    // -------- Original test case --------
+
+    let full_length = 1024;
+    let range = {
+        // do some stuff, omit here
+        None
+    };
+
+    let range = range.map(|(s, t)| s..=t).unwrap_or(0..=(full_length-1));
+
+    assert_eq!(range, 0..=1023);
+}
diff --git a/src/test/run-pass/macro-reexport-no-intermediate-use.rs b/src/test/run-pass/macro-reexport-no-intermediate-use.rs
deleted file mode 100644 (file)
index de7df1e..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// aux-build:macro_reexport_1.rs
-// aux-build:macro_reexport_2_no_use.rs
-
-#[macro_use] #[no_link]
-extern crate macro_reexport_2_no_use;
-
-fn main() {
-    assert_eq!(reexported!(), 3_usize);
-}
diff --git a/src/test/run-pass/macro-reexport.rs b/src/test/run-pass/macro-reexport.rs
deleted file mode 100644 (file)
index b8926ec..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// aux-build:macro_reexport_1.rs
-// aux-build:macro_reexport_2.rs
-
-#[macro_use] #[no_link]
-extern crate macro_reexport_2;
-
-fn main() {
-    assert_eq!(reexported!(), 3_usize);
-}
diff --git a/src/test/run-pass/repr_c_int_align.rs b/src/test/run-pass/repr_c_int_align.rs
new file mode 100644 (file)
index 0000000..af4eb61
--- /dev/null
@@ -0,0 +1,55 @@
+// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// compile-flags: -O
+
+#![allow(dead_code)]
+
+#[repr(C, u8)]
+enum ReprCu8 {
+    A(u16),
+    B,
+}
+
+#[repr(u8)]
+enum Repru8 {
+    A(u16),
+    B,
+}
+
+#[repr(C)]
+struct ReprC {
+    tag: u8,
+    padding: u8,
+    payload: u16,
+}
+
+fn main() {
+    // Test `repr(C, u8)`.
+    let r1 = ReprC { tag: 0, padding: 0, payload: 0 };
+    let r2 = ReprC { tag: 0, padding: 1, payload: 1 };
+
+    let t1: &ReprCu8 = unsafe { std::mem::transmute(&r1) };
+    let t2: &ReprCu8 = unsafe { std::mem::transmute(&r2) };
+
+    match (t1, t2) {
+        (ReprCu8::A(_), ReprCu8::A(_)) => (),
+        _ => assert!(false)
+    };
+
+    // Test `repr(u8)`.
+    let t1: &Repru8 = unsafe { std::mem::transmute(&r1) };
+    let t2: &Repru8 = unsafe { std::mem::transmute(&r2) };
+
+    match (t1, t2) {
+        (Repru8::A(_), Repru8::A(_)) => (),
+        _ => assert!(false)
+    };
+}
diff --git a/src/test/run-pass/tool_attributes.rs b/src/test/run-pass/tool_attributes.rs
new file mode 100644 (file)
index 0000000..eb13930
--- /dev/null
@@ -0,0 +1,23 @@
+// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// Scoped attributes should not trigger an unused attributes lint.
+
+#![feature(tool_attributes)]
+#![deny(unused_attributes)]
+
+fn main() {
+    #[rustfmt::skip]
+    foo ();
+}
+
+fn foo() {
+    assert!(true);
+}
index f31786df67cc35d39fe22b4f43dc3b2802d36431..0c5ec4fccbcd731abcfd78a3c2233ebb97399082 100644 (file)
@@ -8,11 +8,13 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// ignore-order
+
 const QUERY = '+';
 
 const EXPECTED = {
     'others': [
-        { 'path': 'std::ops::AddAssign', 'name': 'AddAssign' },
-        { 'path': 'std::ops::Add', 'name': 'Add' },
+        { 'path': 'std::ops', 'name': 'AddAssign' },
+        { 'path': 'std::ops', 'name': 'Add' },
     ],
 };
index a0500f24c17ee61454872cd88649595be78403b8..e7aafe3b9e2d158953fe787e58b2dca18f4f8b62 100644 (file)
@@ -8,12 +8,14 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// ignore-order
+
 const QUERY = '[';
 
 const EXPECTED = {
     'others': [
         { 'path': 'std', 'name': 'slice' },
-        { 'path': 'std::ops::IndexMut', 'name': 'IndexMut' },
-        { 'path': 'std::ops::Index', 'name': 'Index' },
+        { 'path': 'std::ops', 'name': 'IndexMut' },
+        { 'path': 'std::ops', 'name': 'Index' },
     ],
 };
index 863437cac91d46340f4b40a2acff9c4d804803be..d7ba1253eabe0ddb377353944d65e89f949ae058 100644 (file)
@@ -13,8 +13,8 @@ const QUERY = 'String';
 const EXPECTED = {
     'others': [
         { 'path': 'std::string', 'name': 'String' },
-        { 'path': 'std::ffi', 'name': 'OsString' },
         { 'path': 'std::ffi', 'name': 'CString' },
+        { 'path': 'std::ffi', 'name': 'OsString' },
     ],
     'in_args': [
         { 'path': 'std::str', 'name': 'eq' },
index 15a774dc9353d57fb905066f3a6f65b73509384f..6078352fc0e0905b84dc8aba7ac0e9169a3caa00 100644 (file)
@@ -66,6 +66,6 @@
 #[doc(no_inline)]
 pub use all_item_types::FOO_CONSTANT;
 
-// @has 'foo/index.html' '//a[@href="../all_item_types/macro.foo_macro.html"]' 'foo_macro'
+// @has 'foo/index.html' '//a[@href="../foo/macro.foo_macro.html"]' 'foo_macro'
 #[doc(no_inline)]
 pub use all_item_types::foo_macro;
index 3f8f6f9544e80d8a4cdba16f6457b3671f8d6900..57d54585d84bc57a0dea284babe9c3e14142b6ad 100644 (file)
 
 // aux-build:pub-use-extern-macros.rs
 
-#![feature(use_extern_macros, macro_reexport)]
+#![feature(use_extern_macros)]
 
-// @has pub_use_extern_macros/macro.foo.html
-// @!has pub_use_extern_macros/index.html 'pub use macros::foo;'
-#[macro_reexport(foo)] extern crate macros;
+extern crate macros;
 
-// @has pub_use_extern_macros/index.html 'pub use macros::bar;'
-// @!has pub_use_extern_macros/macro.bar.html
+// @has pub_use_extern_macros/macro.bar.html
 pub use macros::bar;
 
 // @has pub_use_extern_macros/macro.baz.html
@@ -25,7 +22,7 @@
 #[doc(inline)]
 pub use macros::baz;
 
-// @!has pub_use_extern_macros/macro.quux.html
+// @has pub_use_extern_macros/macro.quux.html
 // @!has pub_use_extern_macros/index.html 'pub use macros::quux;'
 #[doc(hidden)]
 pub use macros::quux;
diff --git a/src/test/ui/const-eval/ice-packed.rs b/src/test/ui/const-eval/ice-packed.rs
new file mode 100644 (file)
index 0000000..1db12a0
--- /dev/null
@@ -0,0 +1,28 @@
+// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// compile-pass
+#[derive(Copy, Clone, PartialEq, Eq)]
+#[repr(packed)]
+pub struct Num(u64);
+
+impl Num {
+    pub const ZERO: Self = Num(0);
+}
+
+pub fn decrement(a: Num) -> Num {
+    match a {
+        Num::ZERO => Num::ZERO,
+        a => Num(a.0 - 1)
+    }
+}
+
+fn main() {
+}
index 793e0a7ace8d882751a5811a13987da82135439b..d16231c72b91a5040cf65ee083332eb9ccc592fe 100644 (file)
@@ -2,7 +2,7 @@ error[E0080]: constant evaluation error
   --> $DIR/index_out_of_bound.rs:11:19
    |
 LL | static FOO: i32 = [][0];
-   |                   ^^^^^ index out of bounds: the len is 0 but the index is 0 at $DIR/index_out_of_bound.rs:11:19: 11:24
+   |                   ^^^^^ index out of bounds: the len is 0 but the index is 0
 
 error: aborting due to previous error
 
index a5db8cc908331c3ea2e01682228a7b7d0245bdfc..7761f192fdb70aa33edd4e4d1f6557bfb6625151 100644 (file)
@@ -2,7 +2,7 @@ warning: constant evaluation error
   --> $DIR/promoted_errors.rs:14:20
    |
 LL |     println!("{}", 0u32 - 1);
-   |                    ^^^^^^^^ attempted to do overflowing math
+   |                    ^^^^^^^^ attempt to subtract with overflow
    |
    = note: #[warn(const_err)] on by default
 
@@ -10,13 +10,13 @@ warning: constant evaluation error
   --> $DIR/promoted_errors.rs:14:20
    |
 LL |     println!("{}", 0u32 - 1);
-   |                    ^^^^^^^^ attempted to do overflowing math
+   |                    ^^^^^^^^ attempt to subtract with overflow
 
 warning: constant evaluation error
   --> $DIR/promoted_errors.rs:17:14
    |
 LL |     let _x = 0u32 - 1;
-   |              ^^^^^^^^ attempted to do overflowing math
+   |              ^^^^^^^^ attempt to subtract with overflow
 
 warning: attempt to divide by zero
   --> $DIR/promoted_errors.rs:19:20
@@ -28,7 +28,7 @@ warning: constant evaluation error
   --> $DIR/promoted_errors.rs:19:20
    |
 LL |     println!("{}", 1/(1-1));
-   |                    ^^^^^^^ attempted to do overflowing math
+   |                    ^^^^^^^ attempt to divide by zero
 
 warning: attempt to divide by zero
   --> $DIR/promoted_errors.rs:22:14
@@ -40,11 +40,11 @@ warning: constant evaluation error
   --> $DIR/promoted_errors.rs:22:14
    |
 LL |     let _x = 1/(1-1);
-   |              ^^^^^^^ attempted to do overflowing math
+   |              ^^^^^^^ attempt to divide by zero
 
 warning: constant evaluation error
   --> $DIR/promoted_errors.rs:25:20
    |
 LL |     println!("{}", 1/(false as u32));
-   |                    ^^^^^^^^^^^^^^^^ attempted to do overflowing math
+   |                    ^^^^^^^^^^^^^^^^ attempt to divide by zero
 
index c8e425711284e529bfc4bb2d4184a677a1344b32..7f3e6eaad9b17963d825d532d470d2a0be4c85bb 100644 (file)
@@ -15,7 +15,6 @@ enum Enum {
     //~| const_err
     //~| const_err
     //~| const_err
-    //~| divide by zero
 }
 
 fn main() {
index 500e0e83a55f2d59ecae0d6ca4e0e435a5a86926..5e401bd6c79da92a3faa90ae0a3630422d832ffe 100644 (file)
@@ -24,7 +24,7 @@ warning: constant evaluation error
   --> $DIR/E0080.rs:14:9
    |
 LL |     Y = (1 / 0) //~ ERROR E0080
-   |         ^^^^^^^ attempted to do overflowing math
+   |         ^^^^^^^ attempt to divide by zero
 
 error[E0080]: constant evaluation error
   --> $DIR/E0080.rs:14:9
diff --git a/src/test/ui/feature-gate-extern_prelude.rs b/src/test/ui/feature-gate-extern_prelude.rs
new file mode 100644 (file)
index 0000000..8d3a303
--- /dev/null
@@ -0,0 +1,11 @@
+// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+can-only-test-this-in-run-make-fulldeps //~ ERROR expected one of `!` or `::`, found `-`
diff --git a/src/test/ui/feature-gate-extern_prelude.stderr b/src/test/ui/feature-gate-extern_prelude.stderr
new file mode 100644 (file)
index 0000000..5abf369
--- /dev/null
@@ -0,0 +1,8 @@
+error: expected one of `!` or `::`, found `-`
+  --> $DIR/feature-gate-extern_prelude.rs:11:4
+   |
+LL | can-only-test-this-in-run-make-fulldeps //~ ERROR expected one of `!` or `::`, found `-`
+   |    ^ expected one of `!` or `::` here
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/feature-gate-fn_must_use-cap-lints-allow.rs b/src/test/ui/feature-gate-fn_must_use-cap-lints-allow.rs
deleted file mode 100644 (file)
index 1c04199..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-// 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.
-
-// compile-flags: --cap-lints allow
-
-// This tests that the fn_must_use feature-gate warning respects the lint
-// cap. (See discussion in Issue #44213.)
-
-#![feature(rustc_attrs)]
-
-#[must_use] // (no feature-gate warning because of the lint cap!)
-fn need_to_use_it() -> bool { true }
-
-#[rustc_error]
-fn main() {} //~ ERROR compilation successful
diff --git a/src/test/ui/feature-gate-fn_must_use-cap-lints-allow.stderr b/src/test/ui/feature-gate-fn_must_use-cap-lints-allow.stderr
deleted file mode 100644 (file)
index a2c1ded..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-error: compilation successful
-  --> $DIR/feature-gate-fn_must_use-cap-lints-allow.rs:22:1
-   |
-LL | fn main() {} //~ ERROR compilation successful
-   | ^^^^^^^^^^^^
-
-error: aborting due to previous error
-
diff --git a/src/test/ui/feature-gate-fn_must_use.rs b/src/test/ui/feature-gate-fn_must_use.rs
deleted file mode 100644 (file)
index 72fdcc7..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-// 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.
-
-#![feature(rustc_attrs)]
-
-struct MyStruct;
-
-impl MyStruct {
-    #[must_use] //~ WARN `#[must_use]` on methods is experimental
-    fn need_to_use_method() -> bool { true }
-}
-
-#[must_use] //~ WARN `#[must_use]` on functions is experimental
-fn need_to_use_it() -> bool { true }
-
-
-// Feature gates are tidy-required to have a specially named (or
-// comment-annotated) compile-fail test (which MUST fail), but for
-// backwards-compatibility reasons, we want `#[must_use]` on functions to be
-// compilable even if the `fn_must_use` feature is absent, thus necessitating
-// the usage of `#[rustc_error]` here, pragmatically if awkwardly solving this
-// dilemma until a superior solution can be devised.
-#[rustc_error]
-fn main() {} //~ ERROR compilation successful
diff --git a/src/test/ui/feature-gate-fn_must_use.stderr b/src/test/ui/feature-gate-fn_must_use.stderr
deleted file mode 100644 (file)
index 431c57a..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-warning: `#[must_use]` on methods is experimental (see issue #43302)
-  --> $DIR/feature-gate-fn_must_use.rs:16:5
-   |
-LL |     #[must_use] //~ WARN `#[must_use]` on methods is experimental
-   |     ^^^^^^^^^^^
-   |
-   = help: add #![feature(fn_must_use)] to the crate attributes to enable
-
-warning: `#[must_use]` on functions is experimental (see issue #43302)
-  --> $DIR/feature-gate-fn_must_use.rs:20:1
-   |
-LL | #[must_use] //~ WARN `#[must_use]` on functions is experimental
-   | ^^^^^^^^^^^
-   |
-   = help: add #![feature(fn_must_use)] to the crate attributes to enable
-
-error: compilation successful
-  --> $DIR/feature-gate-fn_must_use.rs:31:1
-   |
-LL | fn main() {} //~ ERROR compilation successful
-   | ^^^^^^^^^^^^
-
-error: aborting due to previous error
-
diff --git a/src/test/ui/feature-gate-tool_attributes.rs b/src/test/ui/feature-gate-tool_attributes.rs
new file mode 100644 (file)
index 0000000..2b7cf56
--- /dev/null
@@ -0,0 +1,15 @@
+// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+fn main() {
+    #[rustfmt::skip] //~ ERROR scoped attribute `rustfmt::skip` is experimental
+    let x = 3
+        ;
+}
diff --git a/src/test/ui/feature-gate-tool_attributes.stderr b/src/test/ui/feature-gate-tool_attributes.stderr
new file mode 100644 (file)
index 0000000..da89c4a
--- /dev/null
@@ -0,0 +1,11 @@
+error[E0658]: scoped attribute `rustfmt::skip` is experimental (see issue #44690)
+  --> $DIR/feature-gate-tool_attributes.rs:12:5
+   |
+LL |     #[rustfmt::skip] //~ ERROR scoped attribute `rustfmt::skip` is experimental
+   |     ^^^^^^^^^^^^^^^^
+   |
+   = help: add #![feature(tool_attributes)] to the crate attributes to enable
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0658`.
index 21950402c8c41cedd3007d2368b4b28253a17cbc..76fb09f27bedf7919166d9fabf344ffd3e377697 100644 (file)
@@ -50,7 +50,6 @@
 #![allow                       (x5300)] //~ WARN unknown lint: `x5300`
 #![forbid                      (x5200)] //~ WARN unknown lint: `x5200`
 #![deny                        (x5100)] //~ WARN unknown lint: `x5100`
-#![macro_reexport             = "5000"] //~ WARN unused attribute
 #![macro_use] // (allowed if no argument; see issue-43160-gating-of-macro_use.rs)
 #![macro_export               = "4800"] //~ WARN unused attribute
 #![plugin_registrar           = "4700"] //~ WARN unused attribute
@@ -186,25 +185,6 @@ mod inner { #![deny(x5100)] }
     //~^ WARN unknown lint: `x5100`
 }
 
-#[macro_reexport = "5000"]
-//~^ WARN unused attribute
-mod macro_reexport {
-    mod inner { #![macro_reexport="5000"] }
-    //~^ WARN unused attribute
-
-    #[macro_reexport = "5000"] fn f() { }
-    //~^ WARN unused attribute
-
-    #[macro_reexport = "5000"] struct S;
-    //~^ WARN unused attribute
-
-    #[macro_reexport = "5000"] type T = S;
-    //~^ WARN unused attribute
-
-    #[macro_reexport = "5000"] impl S { }
-    //~^ WARN unused attribute
-}
-
 #[macro_use]
 mod macro_use {
     mod inner { #![macro_use] }
@@ -661,7 +641,6 @@ mod must_use {
     mod inner { #![must_use="1400"] }
 
     #[must_use = "1400"] fn f() { }
-    //~^ WARN `#[must_use]` on functions is experimental
 
     #[must_use = "1400"] struct S;
 
index 0beed62798710e9710efff7af3c438e1b0f6e0bf..f8e5f58ca0e893f3daa3ad5d402645bff16a110f 100644 (file)
@@ -1,25 +1,17 @@
 warning: macro_escape is a deprecated synonym for macro_use
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:513:1
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:493:1
    |
 LL | #[macro_escape]
    | ^^^^^^^^^^^^^^^
 
 warning: macro_escape is a deprecated synonym for macro_use
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:516:17
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:496:17
    |
 LL |     mod inner { #![macro_escape] }
    |                 ^^^^^^^^^^^^^^^^
    |
    = help: consider an outer attribute, #[macro_use] mod ...
 
-warning: `#[must_use]` on functions is experimental (see issue #43302)
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:663:5
-   |
-LL |     #[must_use = "1400"] fn f() { }
-   |     ^^^^^^^^^^^^^^^^^^^^
-   |
-   = help: add #![feature(fn_must_use)] to the crate attributes to enable
-
 warning: unknown lint: `x5400`
   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:49:33
    |
@@ -51,154 +43,154 @@ LL | #![deny                        (x5100)] //~ WARN unknown lint: `x5100`
    |                                 ^^^^^
 
 warning: unknown lint: `x5400`
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:113:8
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:112:8
    |
 LL | #[warn(x5400)]
    |        ^^^^^
 
 warning: unknown lint: `x5400`
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:116:25
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:115:25
    |
 LL |     mod inner { #![warn(x5400)] }
    |                         ^^^^^
 
 warning: unknown lint: `x5400`
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:119:12
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:118:12
    |
 LL |     #[warn(x5400)] fn f() { }
    |            ^^^^^
 
 warning: unknown lint: `x5400`
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:122:12
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:121:12
    |
 LL |     #[warn(x5400)] struct S;
    |            ^^^^^
 
 warning: unknown lint: `x5400`
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:125:12
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:124:12
    |
 LL |     #[warn(x5400)] type T = S;
    |            ^^^^^
 
 warning: unknown lint: `x5400`
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:128:12
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:127:12
    |
 LL |     #[warn(x5400)] impl S { }
    |            ^^^^^
 
 warning: unknown lint: `x5300`
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:132:9
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:131:9
    |
 LL | #[allow(x5300)]
    |         ^^^^^
 
 warning: unknown lint: `x5300`
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:135:26
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:134:26
    |
 LL |     mod inner { #![allow(x5300)] }
    |                          ^^^^^
 
 warning: unknown lint: `x5300`
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:138:13
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:137:13
    |
 LL |     #[allow(x5300)] fn f() { }
    |             ^^^^^
 
 warning: unknown lint: `x5300`
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:141:13
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:140:13
    |
 LL |     #[allow(x5300)] struct S;
    |             ^^^^^
 
 warning: unknown lint: `x5300`
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:144:13
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:143:13
    |
 LL |     #[allow(x5300)] type T = S;
    |             ^^^^^
 
 warning: unknown lint: `x5300`
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:147:13
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:146:13
    |
 LL |     #[allow(x5300)] impl S { }
    |             ^^^^^
 
 warning: unknown lint: `x5200`
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:151:10
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:150:10
    |
 LL | #[forbid(x5200)]
    |          ^^^^^
 
 warning: unknown lint: `x5200`
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:154:27
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:153:27
    |
 LL |     mod inner { #![forbid(x5200)] }
    |                           ^^^^^
 
 warning: unknown lint: `x5200`
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:157:14
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:156:14
    |
 LL |     #[forbid(x5200)] fn f() { }
    |              ^^^^^
 
 warning: unknown lint: `x5200`
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:160:14
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:159:14
    |
 LL |     #[forbid(x5200)] struct S;
    |              ^^^^^
 
 warning: unknown lint: `x5200`
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:163:14
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:162:14
    |
 LL |     #[forbid(x5200)] type T = S;
    |              ^^^^^
 
 warning: unknown lint: `x5200`
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:166:14
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:165:14
    |
 LL |     #[forbid(x5200)] impl S { }
    |              ^^^^^
 
 warning: unknown lint: `x5100`
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:170:8
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:169:8
    |
 LL | #[deny(x5100)]
    |        ^^^^^
 
 warning: unknown lint: `x5100`
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:173:25
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:172:25
    |
 LL |     mod inner { #![deny(x5100)] }
    |                         ^^^^^
 
 warning: unknown lint: `x5100`
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:176:12
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:175:12
    |
 LL |     #[deny(x5100)] fn f() { }
    |            ^^^^^
 
 warning: unknown lint: `x5100`
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:179:12
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:178:12
    |
 LL |     #[deny(x5100)] struct S;
    |            ^^^^^
 
 warning: unknown lint: `x5100`
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:182:12
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:181:12
    |
 LL |     #[deny(x5100)] type T = S;
    |            ^^^^^
 
 warning: unknown lint: `x5100`
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:185:12
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:184:12
    |
 LL |     #[deny(x5100)] impl S { }
    |            ^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:192:17
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:192:5
    |
-LL |     mod inner { #![macro_reexport="5000"] }
-   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^
+LL |     #[macro_use] fn f() { }
+   |     ^^^^^^^^^^^^
    |
 note: lint level defined here
   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:44:9
@@ -209,311 +201,275 @@ LL | #![warn(unused_attributes, unknown_lints)]
 warning: unused attribute
   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:195:5
    |
-LL |     #[macro_reexport = "5000"] fn f() { }
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:198:5
-   |
-LL |     #[macro_reexport = "5000"] struct S;
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:201:5
-   |
-LL |     #[macro_reexport = "5000"] type T = S;
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:204:5
-   |
-LL |     #[macro_reexport = "5000"] impl S { }
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:189:1
-   |
-LL | #[macro_reexport = "5000"]
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:212:5
-   |
-LL |     #[macro_use] fn f() { }
-   |     ^^^^^^^^^^^^
-
-warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:215:5
-   |
 LL |     #[macro_use] struct S;
    |     ^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:218:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:198:5
    |
 LL |     #[macro_use] type T = S;
    |     ^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:221:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:201:5
    |
 LL |     #[macro_use] impl S { }
    |     ^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:228:17
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:208:17
    |
 LL |     mod inner { #![macro_export="4800"] }
    |                 ^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:231:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:211:5
    |
 LL |     #[macro_export = "4800"] fn f() { }
    |     ^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:234:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:214:5
    |
 LL |     #[macro_export = "4800"] struct S;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:237:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:217:5
    |
 LL |     #[macro_export = "4800"] type T = S;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:240:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:220:5
    |
 LL |     #[macro_export = "4800"] impl S { }
    |     ^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:225:1
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:205:1
    |
 LL | #[macro_export = "4800"]
    | ^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:247:17
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:227:17
    |
 LL |     mod inner { #![plugin_registrar="4700"] }
    |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:252:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:232:5
    |
 LL |     #[plugin_registrar = "4700"] struct S;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:255:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:235:5
    |
 LL |     #[plugin_registrar = "4700"] type T = S;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:258:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:238:5
    |
 LL |     #[plugin_registrar = "4700"] impl S { }
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:244:1
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:224:1
    |
 LL | #[plugin_registrar = "4700"]
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:265:17
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:245:17
    |
 LL |     mod inner { #![main="4300"] }
    |                 ^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:270:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:250:5
    |
 LL |     #[main = "4400"] struct S;
    |     ^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:273:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:253:5
    |
 LL |     #[main = "4400"] type T = S;
    |     ^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:276:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:256:5
    |
 LL |     #[main = "4400"] impl S { }
    |     ^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:262:1
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:242:1
    |
 LL | #[main = "4400"]
    | ^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:283:17
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:263:17
    |
 LL |     mod inner { #![start="4300"] }
    |                 ^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:288:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:268:5
    |
 LL |     #[start = "4300"] struct S;
    |     ^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:291:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:271:5
    |
 LL |     #[start = "4300"] type T = S;
    |     ^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:294:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:274:5
    |
 LL |     #[start = "4300"] impl S { }
    |     ^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:280:1
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:260:1
    |
 LL | #[start = "4300"]
    | ^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:333:17
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:313:17
    |
 LL |     mod inner { #![repr="3900"] }
    |                 ^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:336:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:316:5
    |
 LL |     #[repr = "3900"] fn f() { }
    |     ^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:341:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:321:5
    |
 LL |     #[repr = "3900"] type T = S;
    |     ^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:344:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:324:5
    |
 LL |     #[repr = "3900"] impl S { }
    |     ^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:330:1
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:310:1
    |
 LL | #[repr = "3900"]
    | ^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:352:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:332:5
    |
 LL |     #[path = "3800"] fn f() { }
    |     ^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:355:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:335:5
    |
 LL |     #[path = "3800"]  struct S;
    |     ^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:358:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:338:5
    |
 LL |     #[path = "3800"] type T = S;
    |     ^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:361:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:341:5
    |
 LL |     #[path = "3800"] impl S { }
    |     ^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:368:17
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:348:17
    |
 LL |     mod inner { #![abi="3700"] }
    |                 ^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:371:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:351:5
    |
 LL |     #[abi = "3700"] fn f() { }
    |     ^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:374:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:354:5
    |
 LL |     #[abi = "3700"] struct S;
    |     ^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:377:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:357:5
    |
 LL |     #[abi = "3700"] type T = S;
    |     ^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:380:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:360:5
    |
 LL |     #[abi = "3700"] impl S { }
    |     ^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:365:1
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:345:1
    |
 LL | #[abi = "3700"]
    | ^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:387:17
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:367:17
    |
 LL |     mod inner { #![automatically_derived="3600"] }
    |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:390:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:370:5
    |
 LL |     #[automatically_derived = "3600"] fn f() { }
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:393:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:373:5
    |
 LL |     #[automatically_derived = "3600"] struct S;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:396:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:376:5
    |
 LL |     #[automatically_derived = "3600"] type T = S;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:399:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:379:5
    |
 LL |     #[automatically_derived = "3600"] impl S { }
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:384:1
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:364:1
    |
 LL | #[automatically_derived = "3600"]
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: function is marked #[no_mangle], but not exported
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:407:27
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:387:27
    |
 LL |     #[no_mangle = "3500"] fn f() { }
    |                           -^^^^^^^^^
@@ -523,793 +479,787 @@ LL |     #[no_mangle = "3500"] fn f() { }
    = note: #[warn(private_no_mangle_fns)] on by default
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:420:17
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:400:17
    |
 LL |     mod inner { #![no_link="3400"] }
    |                 ^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:423:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:403:5
    |
 LL |     #[no_link = "3400"] fn f() { }
    |     ^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:426:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:406:5
    |
 LL |     #[no_link = "3400"] struct S;
    |     ^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:429:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:409:5
    |
 LL |     #[no_link = "3400"]type T = S;
    |     ^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:432:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:412:5
    |
 LL |     #[no_link = "3400"] impl S { }
    |     ^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:417:1
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:397:1
    |
 LL | #[no_link = "3400"]
    | ^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:439:17
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:419:17
    |
 LL |     mod inner { #![should_panic="3200"] }
    |                 ^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:442:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:422:5
    |
 LL |     #[should_panic = "3200"] fn f() { }
    |     ^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:445:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:425:5
    |
 LL |     #[should_panic = "3200"] struct S;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:448:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:428:5
    |
 LL |     #[should_panic = "3200"] type T = S;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:451:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:431:5
    |
 LL |     #[should_panic = "3200"] impl S { }
    |     ^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:436:1
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:416:1
    |
 LL | #[should_panic = "3200"]
    | ^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:458:17
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:438:17
    |
 LL |     mod inner { #![ignore="3100"] }
    |                 ^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:461:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:441:5
    |
 LL |     #[ignore = "3100"] fn f() { }
    |     ^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:464:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:444:5
    |
 LL |     #[ignore = "3100"] struct S;
    |     ^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:467:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:447:5
    |
 LL |     #[ignore = "3100"] type T = S;
    |     ^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:470:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:450:5
    |
 LL |     #[ignore = "3100"] impl S { }
    |     ^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:455:1
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:435:1
    |
 LL | #[ignore = "3100"]
    | ^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:477:17
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:457:17
    |
 LL |     mod inner { #![no_implicit_prelude="3000"] }
    |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:480:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:460:5
    |
 LL |     #[no_implicit_prelude = "3000"] fn f() { }
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:483:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:463:5
    |
 LL |     #[no_implicit_prelude = "3000"] struct S;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:486:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:466:5
    |
 LL |     #[no_implicit_prelude = "3000"] type T = S;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:489:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:469:5
    |
 LL |     #[no_implicit_prelude = "3000"] impl S { }
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:474:1
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:454:1
    |
 LL | #[no_implicit_prelude = "3000"]
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:496:17
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:476:17
    |
 LL |     mod inner { #![reexport_test_harness_main="2900"] }
    |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:499:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:479:5
    |
 LL |     #[reexport_test_harness_main = "2900"] fn f() { }
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:502:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:482:5
    |
 LL |     #[reexport_test_harness_main = "2900"] struct S;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:505:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:485:5
    |
 LL |     #[reexport_test_harness_main = "2900"] type T = S;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:508:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:488:5
    |
 LL |     #[reexport_test_harness_main = "2900"] impl S { }
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:493:1
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:473:1
    |
 LL | #[reexport_test_harness_main = "2900"]
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:519:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:499:5
    |
 LL |     #[macro_escape] fn f() { }
    |     ^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:522:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:502:5
    |
 LL |     #[macro_escape] struct S;
    |     ^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:525:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:505:5
    |
 LL |     #[macro_escape] type T = S;
    |     ^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:528:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:508:5
    |
 LL |     #[macro_escape] impl S { }
    |     ^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:536:17
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:516:17
    |
 LL |     mod inner { #![no_std="2600"] }
    |                 ^^^^^^^^^^^^^^^^^
 
 warning: crate-level attribute should be in the root module
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:536:17
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:516:17
    |
 LL |     mod inner { #![no_std="2600"] }
    |                 ^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:540:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:520:5
    |
 LL |     #[no_std = "2600"] fn f() { }
    |     ^^^^^^^^^^^^^^^^^^
 
 warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo]
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:540:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:520:5
    |
 LL |     #[no_std = "2600"] fn f() { }
    |     ^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:544:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:524:5
    |
 LL |     #[no_std = "2600"] struct S;
    |     ^^^^^^^^^^^^^^^^^^
 
 warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo]
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:544:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:524:5
    |
 LL |     #[no_std = "2600"] struct S;
    |     ^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:548:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:528:5
    |
 LL |     #[no_std = "2600"] type T = S;
    |     ^^^^^^^^^^^^^^^^^^
 
 warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo]
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:548:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:528:5
    |
 LL |     #[no_std = "2600"] type T = S;
    |     ^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:552:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:532:5
    |
 LL |     #[no_std = "2600"] impl S { }
    |     ^^^^^^^^^^^^^^^^^^
 
 warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo]
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:552:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:532:5
    |
 LL |     #[no_std = "2600"] impl S { }
    |     ^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:532:1
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:512:1
    |
 LL | #[no_std = "2600"]
    | ^^^^^^^^^^^^^^^^^^
 
 warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo]
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:532:1
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:512:1
    |
 LL | #[no_std = "2600"]
    | ^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:692:17
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:671:17
    |
 LL |     mod inner { #![crate_name="0900"] }
    |                 ^^^^^^^^^^^^^^^^^^^^^
 
 warning: crate-level attribute should be in the root module
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:692:17
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:671:17
    |
 LL |     mod inner { #![crate_name="0900"] }
    |                 ^^^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:696:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:675:5
    |
 LL |     #[crate_name = "0900"] fn f() { }
    |     ^^^^^^^^^^^^^^^^^^^^^^
 
 warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo]
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:696:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:675:5
    |
 LL |     #[crate_name = "0900"] fn f() { }
    |     ^^^^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:700:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:679:5
    |
 LL |     #[crate_name = "0900"] struct S;
    |     ^^^^^^^^^^^^^^^^^^^^^^
 
 warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo]
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:700:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:679:5
    |
 LL |     #[crate_name = "0900"] struct S;
    |     ^^^^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:704:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:683:5
    |
 LL |     #[crate_name = "0900"] type T = S;
    |     ^^^^^^^^^^^^^^^^^^^^^^
 
 warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo]
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:704:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:683:5
    |
 LL |     #[crate_name = "0900"] type T = S;
    |     ^^^^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:708:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:687:5
    |
 LL |     #[crate_name = "0900"] impl S { }
    |     ^^^^^^^^^^^^^^^^^^^^^^
 
 warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo]
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:708:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:687:5
    |
 LL |     #[crate_name = "0900"] impl S { }
    |     ^^^^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:688:1
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:667:1
    |
 LL | #[crate_name = "0900"]
    | ^^^^^^^^^^^^^^^^^^^^^^
 
 warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo]
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:688:1
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:667:1
    |
 LL | #[crate_name = "0900"]
    | ^^^^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:717:17
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:696:17
    |
 LL |     mod inner { #![crate_type="0800"] }
    |                 ^^^^^^^^^^^^^^^^^^^^^
 
 warning: crate-level attribute should be in the root module
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:717:17
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:696:17
    |
 LL |     mod inner { #![crate_type="0800"] }
    |                 ^^^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:721:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:700:5
    |
 LL |     #[crate_type = "0800"] fn f() { }
    |     ^^^^^^^^^^^^^^^^^^^^^^
 
 warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo]
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:721:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:700:5
    |
 LL |     #[crate_type = "0800"] fn f() { }
    |     ^^^^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:725:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:704:5
    |
 LL |     #[crate_type = "0800"] struct S;
    |     ^^^^^^^^^^^^^^^^^^^^^^
 
 warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo]
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:725:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:704:5
    |
 LL |     #[crate_type = "0800"] struct S;
    |     ^^^^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:729:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:708:5
    |
 LL |     #[crate_type = "0800"] type T = S;
    |     ^^^^^^^^^^^^^^^^^^^^^^
 
 warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo]
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:729:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:708:5
    |
 LL |     #[crate_type = "0800"] type T = S;
    |     ^^^^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:733:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:712:5
    |
 LL |     #[crate_type = "0800"] impl S { }
    |     ^^^^^^^^^^^^^^^^^^^^^^
 
 warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo]
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:733:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:712:5
    |
 LL |     #[crate_type = "0800"] impl S { }
    |     ^^^^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:713:1
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:692:1
    |
 LL | #[crate_type = "0800"]
    | ^^^^^^^^^^^^^^^^^^^^^^
 
 warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo]
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:713:1
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:692:1
    |
 LL | #[crate_type = "0800"]
    | ^^^^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:742:17
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:721:17
    |
 LL |     mod inner { #![feature(x0600)] }
    |                 ^^^^^^^^^^^^^^^^^^
 
 warning: crate-level attribute should be in the root module
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:742:17
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:721:17
    |
 LL |     mod inner { #![feature(x0600)] }
    |                 ^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:746:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:725:5
    |
 LL |     #[feature(x0600)] fn f() { }
    |     ^^^^^^^^^^^^^^^^^
 
 warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo]
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:746:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:725:5
    |
 LL |     #[feature(x0600)] fn f() { }
    |     ^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:750:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:729:5
    |
 LL |     #[feature(x0600)] struct S;
    |     ^^^^^^^^^^^^^^^^^
 
 warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo]
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:750:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:729:5
    |
 LL |     #[feature(x0600)] struct S;
    |     ^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:754:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:733:5
    |
 LL |     #[feature(x0600)] type T = S;
    |     ^^^^^^^^^^^^^^^^^
 
 warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo]
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:754:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:733:5
    |
 LL |     #[feature(x0600)] type T = S;
    |     ^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:758:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:737:5
    |
 LL |     #[feature(x0600)] impl S { }
    |     ^^^^^^^^^^^^^^^^^
 
 warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo]
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:758:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:737:5
    |
 LL |     #[feature(x0600)] impl S { }
    |     ^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:738:1
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:717:1
    |
 LL | #[feature(x0600)]
    | ^^^^^^^^^^^^^^^^^
 
 warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo]
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:738:1
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:717:1
    |
 LL | #[feature(x0600)]
    | ^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:768:17
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:747:17
    |
 LL |     mod inner { #![no_main="0400"] }
    |                 ^^^^^^^^^^^^^^^^^^
 
 warning: crate-level attribute should be in the root module
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:768:17
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:747:17
    |
 LL |     mod inner { #![no_main="0400"] }
    |                 ^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:772:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:751:5
    |
 LL |     #[no_main = "0400"] fn f() { }
    |     ^^^^^^^^^^^^^^^^^^^
 
 warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo]
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:772:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:751:5
    |
 LL |     #[no_main = "0400"] fn f() { }
    |     ^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:776:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:755:5
    |
 LL |     #[no_main = "0400"] struct S;
    |     ^^^^^^^^^^^^^^^^^^^
 
 warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo]
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:776:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:755:5
    |
 LL |     #[no_main = "0400"] struct S;
    |     ^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:780:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:759:5
    |
 LL |     #[no_main = "0400"] type T = S;
    |     ^^^^^^^^^^^^^^^^^^^
 
 warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo]
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:780:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:759:5
    |
 LL |     #[no_main = "0400"] type T = S;
    |     ^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:784:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:763:5
    |
 LL |     #[no_main = "0400"] impl S { }
    |     ^^^^^^^^^^^^^^^^^^^
 
 warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo]
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:784:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:763:5
    |
 LL |     #[no_main = "0400"] impl S { }
    |     ^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:764:1
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:743:1
    |
 LL | #[no_main = "0400"]
    | ^^^^^^^^^^^^^^^^^^^
 
 warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo]
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:764:1
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:743:1
    |
 LL | #[no_main = "0400"]
    | ^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:806:17
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:785:17
    |
 LL |     mod inner { #![recursion_limit="0200"] }
    |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: crate-level attribute should be in the root module
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:806:17
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:785:17
    |
 LL |     mod inner { #![recursion_limit="0200"] }
    |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:810:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:789:5
    |
 LL |     #[recursion_limit="0200"] fn f() { }
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo]
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:810:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:789:5
    |
 LL |     #[recursion_limit="0200"] fn f() { }
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:814:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:793:5
    |
 LL |     #[recursion_limit="0200"] struct S;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo]
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:814:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:793:5
    |
 LL |     #[recursion_limit="0200"] struct S;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:818:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:797:5
    |
 LL |     #[recursion_limit="0200"] type T = S;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo]
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:818:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:797:5
    |
 LL |     #[recursion_limit="0200"] type T = S;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:822:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:801:5
    |
 LL |     #[recursion_limit="0200"] impl S { }
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo]
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:822:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:801:5
    |
 LL |     #[recursion_limit="0200"] impl S { }
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:802:1
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:781:1
    |
 LL | #[recursion_limit="0200"]
    | ^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo]
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:802:1
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:781:1
    |
 LL | #[recursion_limit="0200"]
    | ^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:831:17
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:810:17
    |
 LL |     mod inner { #![type_length_limit="0100"] }
    |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: crate-level attribute should be in the root module
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:831:17
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:810:17
    |
 LL |     mod inner { #![type_length_limit="0100"] }
    |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:835:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:814:5
    |
 LL |     #[type_length_limit="0100"] fn f() { }
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo]
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:835:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:814:5
    |
 LL |     #[type_length_limit="0100"] fn f() { }
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:839:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:818:5
    |
 LL |     #[type_length_limit="0100"] struct S;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo]
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:839:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:818:5
    |
 LL |     #[type_length_limit="0100"] struct S;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:843:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:822:5
    |
 LL |     #[type_length_limit="0100"] type T = S;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo]
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:843:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:822:5
    |
 LL |     #[type_length_limit="0100"] type T = S;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:847:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:826:5
    |
 LL |     #[type_length_limit="0100"] impl S { }
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo]
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:847:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:826:5
    |
 LL |     #[type_length_limit="0100"] impl S { }
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:827:1
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:806:1
    |
 LL | #[type_length_limit="0100"]
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo]
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:827:1
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:806:1
    |
 LL | #[type_length_limit="0100"]
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:53:1
-   |
-LL | #![macro_reexport             = "5000"] //~ WARN unused attribute
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:55:1
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:54:1
    |
 LL | #![macro_export               = "4800"] //~ WARN unused attribute
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:56:1
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:55:1
    |
 LL | #![plugin_registrar           = "4700"] //~ WARN unused attribute
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:59:1
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:58:1
    |
 LL | #![main                      = "x4400"] //~ WARN unused attribute
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:60:1
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:59:1
    |
 LL | #![start                     = "x4300"] //~ WARN unused attribute
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:63:1
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:62:1
    |
 LL | #![repr                       = "3900"] //~ WARN unused attribute
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:64:1
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:63:1
    |
 LL | #![path                       = "3800"] //~ WARN unused attribute
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:65:1
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:64:1
    |
 LL | #![abi                        = "3700"] //~ WARN unused attribute
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:66:1
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:65:1
    |
 LL | #![automatically_derived      = "3600"] //~ WARN unused attribute
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:68:1
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:67:1
    |
 LL | #![no_link                    = "3400"] //~ WARN unused attribute
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:70:1
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:69:1
    |
 LL | #![should_panic               = "3200"] //~ WARN unused attribute
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:71:1
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:70:1
    |
 LL | #![ignore                     = "3100"] //~ WARN unused attribute
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:77:1
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:76:1
    |
 LL | #![proc_macro_derive          = "2500"] //~ WARN unused attribute
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: compilation successful
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:858:1
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:837:1
    |
 LL | / fn main() { //~ ERROR compilation successful
 LL | |     println!("Hello World");
diff --git a/src/test/ui/fn_must_use.rs b/src/test/ui/fn_must_use.rs
new file mode 100644 (file)
index 0000000..def2304
--- /dev/null
@@ -0,0 +1,78 @@
+// 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.
+
+// compile-pass
+
+#![warn(unused_must_use)]
+
+#[derive(PartialEq, Eq)]
+struct MyStruct {
+    n: usize,
+}
+
+impl MyStruct {
+    #[must_use]
+    fn need_to_use_this_method_value(&self) -> usize {
+        self.n
+    }
+}
+
+trait EvenNature {
+    #[must_use = "no side effects"]
+    fn is_even(&self) -> bool;
+}
+
+impl EvenNature for MyStruct {
+    fn is_even(&self) -> bool {
+        self.n % 2 == 0
+    }
+}
+
+trait Replaceable {
+    fn replace(&mut self, substitute: usize) -> usize;
+}
+
+impl Replaceable for MyStruct {
+    // ↓ N.b.: `#[must_use]` attribute on a particular trait implementation
+    // method won't work; the attribute should be on the method signature in
+    // the trait's definition.
+    #[must_use]
+    fn replace(&mut self, substitute: usize) -> usize {
+        let previously = self.n;
+        self.n = substitute;
+        previously
+    }
+}
+
+#[must_use = "it's important"]
+fn need_to_use_this_value() -> bool {
+    false
+}
+
+fn main() {
+    need_to_use_this_value(); //~ WARN unused return value
+
+    let mut m = MyStruct { n: 2 };
+    let n = MyStruct { n: 3 };
+
+    m.need_to_use_this_method_value(); //~ WARN unused return value
+    m.is_even(); // trait method!
+    //~^ WARN unused return value
+
+    m.replace(3); // won't warn (annotation needs to be in trait definition)
+
+    // comparison methods are `must_use`
+    2.eq(&3); //~ WARN unused return value
+    m.eq(&n); //~ WARN unused return value
+
+    // lint includes comparison operators
+    2 == 3; //~ WARN unused comparison
+    m == n; //~ WARN unused comparison
+}
diff --git a/src/test/ui/fn_must_use.stderr b/src/test/ui/fn_must_use.stderr
new file mode 100644 (file)
index 0000000..5026dac
--- /dev/null
@@ -0,0 +1,48 @@
+warning: unused return value of `need_to_use_this_value` which must be used: it's important
+  --> $DIR/fn_must_use.rs:60:5
+   |
+LL |     need_to_use_this_value(); //~ WARN unused return value
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+note: lint level defined here
+  --> $DIR/fn_must_use.rs:13:9
+   |
+LL | #![warn(unused_must_use)]
+   |         ^^^^^^^^^^^^^^^
+
+warning: unused return value of `MyStruct::need_to_use_this_method_value` which must be used
+  --> $DIR/fn_must_use.rs:65:5
+   |
+LL |     m.need_to_use_this_method_value(); //~ WARN unused return value
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+warning: unused return value of `EvenNature::is_even` which must be used: no side effects
+  --> $DIR/fn_must_use.rs:66:5
+   |
+LL |     m.is_even(); // trait method!
+   |     ^^^^^^^^^^^^
+
+warning: unused return value of `std::cmp::PartialEq::eq` which must be used
+  --> $DIR/fn_must_use.rs:72:5
+   |
+LL |     2.eq(&3); //~ WARN unused return value
+   |     ^^^^^^^^^
+
+warning: unused return value of `std::cmp::PartialEq::eq` which must be used
+  --> $DIR/fn_must_use.rs:73:5
+   |
+LL |     m.eq(&n); //~ WARN unused return value
+   |     ^^^^^^^^^
+
+warning: unused comparison which must be used
+  --> $DIR/fn_must_use.rs:76:5
+   |
+LL |     2 == 3; //~ WARN unused comparison
+   |     ^^^^^^
+
+warning: unused comparison which must be used
+  --> $DIR/fn_must_use.rs:77:5
+   |
+LL |     m == n; //~ WARN unused comparison
+   |     ^^^^^^
+
index 1801da6c8b2ddf73720c50a74235335089d80fa2..243e9018585138442786b9830af0e71b0b978069 100644 (file)
@@ -1,14 +1,30 @@
-error: compilation successful
-  --> $DIR/borrowing.rs:15:1
+error[E0597]: `a` does not live long enough
+  --> $DIR/borrowing.rs:18:18
    |
-LL | / fn main() { #![rustc_error] // rust-lang/rust#49855
-LL | |     let _b = {
-LL | |         let a = 3;
-LL | |         unsafe { (|| yield &a).resume() }
-...  |
-LL | |     };
-LL | | }
-   | |_^
+LL |         unsafe { (|| yield &a).resume() }
+   |                  ^^^^^^^^^^^^^
+   |                  |
+   |                  borrowed value does not live long enough
+   |                  borrow may end up in a temporary, created here
+LL |         //~^ ERROR: `a` does not live long enough
+LL |     };
+   |     -- temporary later dropped here, potentially using the reference
+   |     |
+   |     borrowed value only lives until here
 
-error: aborting due to previous error
+error[E0597]: `a` does not live long enough
+  --> $DIR/borrowing.rs:24:9
+   |
+LL | /         || {
+LL | |             yield &a
+LL | |             //~^ ERROR: `a` does not live long enough
+LL | |         }
+   | |_________^ borrowed value does not live long enough
+LL |       };
+   |       - borrowed value only lives until here
+LL |   }
+   |   - borrow later used here, when `_b` is dropped
+
+error: aborting due to 2 previous errors
 
+For more information about this error, try `rustc --explain E0597`.
index f80aca9fb00e6c357b73554d5c7f69411bf9b152..e56927d81823131b1e38e66cbff0394b743489fe 100644 (file)
@@ -8,11 +8,11 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(generators, generator_trait, rustc_attrs)]
+#![feature(generators, generator_trait)]
 
 use std::ops::Generator;
 
-fn main() { #![rustc_error] // rust-lang/rust#49855
+fn main() {
     let _b = {
         let a = 3;
         unsafe { (|| yield &a).resume() }
index 72ebaab32789825674c71e21fbf6975a5a0f7ec4..c352fd6a62f28522f2fa1763579479dd94926b83 100644 (file)
@@ -1,14 +1,20 @@
-error: compilation successful
-  --> $DIR/dropck.rs:16:1
+error[E0597]: `ref_` does not live long enough
+  --> $DIR/dropck.rs:22:11
    |
-LL | / fn main() { #![rustc_error] // rust-lang/rust#49855
-LL | |     let (cell, mut gen);
-LL | |     cell = Box::new(RefCell::new(0));
-LL | |     let ref_ = Box::leak(Box::new(Some(cell.borrow_mut())));
-...  |
-LL | |     // drops the RefCell and then the Ref, leading to use-after-free
-LL | | }
-   | |_^
+LL |       gen = || {
+   |  ___________^
+LL | |         // but the generator can use it to drop a `Ref<'a, i32>`.
+LL | |         let _d = ref_.take(); //~ ERROR `ref_` does not live long enough
+LL | |         yield;
+LL | |     };
+   | |_____^ borrowed value does not live long enough
+...
+LL |   }
+   |   -
+   |   |
+   |   borrowed value only lives until here
+   |   borrow later used here, when `gen` is dropped
 
 error: aborting due to previous error
 
+For more information about this error, try `rustc --explain E0597`.
index 8f4ba64fd57276fc4a121b4d0c203d1e724173a9..857288818c67c5e0f80a7bef0b77b0a80d8eef84 100644 (file)
@@ -8,15 +8,16 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(generators, generator_trait, box_leak, rustc_attrs)]
+#![feature(generators, generator_trait, box_leak)]
 
 use std::cell::RefCell;
 use std::ops::Generator;
 
-fn main() { #![rustc_error] // rust-lang/rust#49855
+fn main() {
     let (cell, mut gen);
     cell = Box::new(RefCell::new(0));
     let ref_ = Box::leak(Box::new(Some(cell.borrow_mut())));
+    //~^ ERROR `*cell` does not live long enough [E0597]
     // the upvar is the non-dropck `&mut Option<Ref<'a, i32>>`.
     gen = || {
         // but the generator can use it to drop a `Ref<'a, i32>`.
index 4a22d299701b496e9255d6fa786019d067c35aad..1a6fed2dd35944d0947eccee78ad7145e3b38a5e 100644 (file)
@@ -1,5 +1,16 @@
+error[E0597]: `*cell` does not live long enough
+  --> $DIR/dropck.rs:19:40
+   |
+LL |     let ref_ = Box::leak(Box::new(Some(cell.borrow_mut())));
+   |                                        ^^^^ borrowed value does not live long enough
+...
+LL | }
+   | - `*cell` dropped here while still borrowed
+   |
+   = note: values in a scope are dropped in the opposite order they are created
+
 error[E0597]: `ref_` does not live long enough
-  --> $DIR/dropck.rs:23:18
+  --> $DIR/dropck.rs:24:18
    |
 LL |     gen = || {
    |           -- capture occurs here
@@ -12,6 +23,6 @@ LL | }
    |
    = note: values in a scope are dropped in the opposite order they are created
 
-error: aborting due to previous error
+error: aborting due to 2 previous errors
 
 For more information about this error, try `rustc --explain E0597`.
index 08839c23c37622261aa1cb76e3a157e323af6534..70870b98365b9d1a1cb11fe0dd41f726273d5222 100644 (file)
@@ -1,11 +1,19 @@
 error[E0597]: `b` does not live long enough
   --> $DIR/ref-escapes-but-not-over-yield.rs:24:13
    |
-LL |         a = &b;
-   |             ^^ borrowed value does not live long enough
-LL |         //~^ ERROR `b` does not live long enough
-LL |     };
-   |     - borrowed value only lives until here
+LL |       let mut b = move || {
+   |  _________________-
+LL | |         yield();
+LL | |         let b = 5;
+LL | |         a = &b;
+   | |             ^^ borrowed value does not live long enough
+LL | |         //~^ ERROR `b` does not live long enough
+LL | |     };
+   | |     -
+   | |     |
+   | |     borrowed value only lives until here
+   | |_____temporary later dropped here, potentially using the reference
+   |       borrow may end up in a temporary, created here
 
 error: aborting due to previous error
 
index 816c443a06c21c6c38fb9600fde1173b0c082636..5a70dffd4c8c2f91b14e0da642c20f99b62d12d2 100644 (file)
@@ -25,5 +25,5 @@
 fn main() {
     assert_eq!('x'.ipu_flatten(), 1);
     //~^ WARN a method with this name may be added to the standard library in the future
-    //~^^ WARN once this method is added to the standard library, there will be ambiguity here
+    //~^^ WARN once this method is added to the standard library, the ambiguity may cause an error
 }
index 9c614d659d36f79319f9ec78b011ddb4bc33fe9c..a217bc57b367028cae9be7e8e5d30aba7e79d83a 100644 (file)
@@ -5,7 +5,7 @@ LL |     assert_eq!('x'.ipu_flatten(), 1);
    |                    ^^^^^^^^^^^
    |
    = note: #[warn(unstable_name_collision)] on by default
-   = warning: once this method is added to the standard library, there will be ambiguity here, which will cause a hard error!
+   = warning: once this method is added to the standard library, the ambiguity may cause an error or change in behavior!
    = note: for more information, see issue #48919 <https://github.com/rust-lang/rust/issues/48919>
    = help: call with fully qualified syntax `inference_unstable_itertools::IpuItertools::ipu_flatten(...)` to keep using the current method
    = note: add #![feature(ipu_flatten)] to the crate attributes to enable `inference_unstable_iterator::IpuIterator::ipu_flatten`
diff --git a/src/test/ui/issue-50187.rs b/src/test/ui/issue-50187.rs
new file mode 100644 (file)
index 0000000..87acf10
--- /dev/null
@@ -0,0 +1,49 @@
+// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// compile-pass
+
+#![feature(use_extern_macros, decl_macro)]
+
+mod type_ns {
+    pub type A = u8;
+}
+mod value_ns {
+    pub const A: u8 = 0;
+}
+mod macro_ns {
+    pub macro A() {}
+}
+
+mod merge2 {
+    pub use type_ns::A;
+    pub use value_ns::A;
+}
+mod merge3 {
+    pub use type_ns::A;
+    pub use value_ns::A;
+    pub use macro_ns::A;
+}
+
+mod use2 {
+    pub use merge2::A;
+}
+mod use3 {
+    pub use merge3::A;
+}
+
+fn main() {
+    type B2 = use2::A;
+    let a2 = use2::A;
+
+    type B3 = use3::A;
+    let a3 = use3::A;
+    use3::A!();
+}
diff --git a/src/test/ui/issue-50403.rs b/src/test/ui/issue-50403.rs
new file mode 100644 (file)
index 0000000..8d4c6c5
--- /dev/null
@@ -0,0 +1,15 @@
+// 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.
+
+#![feature(concat_idents)]
+
+fn main() {
+    let x = concat_idents!(); //~ ERROR concat_idents! takes 1 or more arguments
+}
diff --git a/src/test/ui/issue-50403.stderr b/src/test/ui/issue-50403.stderr
new file mode 100644 (file)
index 0000000..f2871c7
--- /dev/null
@@ -0,0 +1,8 @@
+error: concat_idents! takes 1 or more arguments.
+  --> $DIR/issue-50403.rs:14:13
+   |
+LL |     let x = concat_idents!(); //~ ERROR concat_idents! takes 1 or more arguments
+   |             ^^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
index 4ed82ab3b4025c283726b3b47b3cac4e2412d935..c0575f817c8d172a522fd41d6d6a77e7e06af5b0 100644 (file)
@@ -12,7 +12,6 @@
 
 // compile-pass
 
-#![feature(fn_must_use)]
 #![warn(unused_must_use)]
 
 fn main() {
index f444ef0907575e4b7cc5f3373ee811b7eed2d355..5703536ef48fd1e1153450e0a1e077b351d8c6a5 100644 (file)
 warning: unused comparison which must be used
-  --> $DIR/must-use-ops.rs:23:5
+  --> $DIR/must-use-ops.rs:22:5
    |
 LL |     val == 1;
    |     ^^^^^^^^
    |
 note: lint level defined here
-  --> $DIR/must-use-ops.rs:16:9
+  --> $DIR/must-use-ops.rs:15:9
    |
 LL | #![warn(unused_must_use)]
    |         ^^^^^^^^^^^^^^^
 
 warning: unused comparison which must be used
-  --> $DIR/must-use-ops.rs:24:5
+  --> $DIR/must-use-ops.rs:23:5
    |
 LL |     val < 1;
    |     ^^^^^^^
 
 warning: unused comparison which must be used
-  --> $DIR/must-use-ops.rs:25:5
+  --> $DIR/must-use-ops.rs:24:5
    |
 LL |     val <= 1;
    |     ^^^^^^^^
 
 warning: unused comparison which must be used
-  --> $DIR/must-use-ops.rs:26:5
+  --> $DIR/must-use-ops.rs:25:5
    |
 LL |     val != 1;
    |     ^^^^^^^^
 
 warning: unused comparison which must be used
-  --> $DIR/must-use-ops.rs:27:5
+  --> $DIR/must-use-ops.rs:26:5
    |
 LL |     val >= 1;
    |     ^^^^^^^^
 
 warning: unused comparison which must be used
-  --> $DIR/must-use-ops.rs:28:5
+  --> $DIR/must-use-ops.rs:27:5
    |
 LL |     val > 1;
    |     ^^^^^^^
 
 warning: unused arithmetic operation which must be used
-  --> $DIR/must-use-ops.rs:31:5
+  --> $DIR/must-use-ops.rs:30:5
    |
 LL |     val + 2;
    |     ^^^^^^^
 
 warning: unused arithmetic operation which must be used
-  --> $DIR/must-use-ops.rs:32:5
+  --> $DIR/must-use-ops.rs:31:5
    |
 LL |     val - 2;
    |     ^^^^^^^
 
 warning: unused arithmetic operation which must be used
-  --> $DIR/must-use-ops.rs:33:5
+  --> $DIR/must-use-ops.rs:32:5
    |
 LL |     val / 2;
    |     ^^^^^^^
 
 warning: unused arithmetic operation which must be used
-  --> $DIR/must-use-ops.rs:34:5
+  --> $DIR/must-use-ops.rs:33:5
    |
 LL |     val * 2;
    |     ^^^^^^^
 
 warning: unused arithmetic operation which must be used
-  --> $DIR/must-use-ops.rs:35:5
+  --> $DIR/must-use-ops.rs:34:5
    |
 LL |     val % 2;
    |     ^^^^^^^
 
 warning: unused logical operation which must be used
-  --> $DIR/must-use-ops.rs:38:5
+  --> $DIR/must-use-ops.rs:37:5
    |
 LL |     true && true;
    |     ^^^^^^^^^^^^
 
 warning: unused logical operation which must be used
-  --> $DIR/must-use-ops.rs:39:5
+  --> $DIR/must-use-ops.rs:38:5
    |
 LL |     false || true;
    |     ^^^^^^^^^^^^^
 
 warning: unused bitwise operation which must be used
-  --> $DIR/must-use-ops.rs:42:5
+  --> $DIR/must-use-ops.rs:41:5
    |
 LL |     5 ^ val;
    |     ^^^^^^^
 
 warning: unused bitwise operation which must be used
-  --> $DIR/must-use-ops.rs:43:5
+  --> $DIR/must-use-ops.rs:42:5
    |
 LL |     5 & val;
    |     ^^^^^^^
 
 warning: unused bitwise operation which must be used
-  --> $DIR/must-use-ops.rs:44:5
+  --> $DIR/must-use-ops.rs:43:5
    |
 LL |     5 | val;
    |     ^^^^^^^
 
 warning: unused bitwise operation which must be used
-  --> $DIR/must-use-ops.rs:45:5
+  --> $DIR/must-use-ops.rs:44:5
    |
 LL |     5 << val;
    |     ^^^^^^^^
 
 warning: unused bitwise operation which must be used
-  --> $DIR/must-use-ops.rs:46:5
+  --> $DIR/must-use-ops.rs:45:5
    |
 LL |     5 >> val;
    |     ^^^^^^^^
 
 warning: unused unary operation which must be used
-  --> $DIR/must-use-ops.rs:49:5
+  --> $DIR/must-use-ops.rs:48:5
    |
 LL |     !val;
    |     ^^^^
 
 warning: unused unary operation which must be used
-  --> $DIR/must-use-ops.rs:50:5
+  --> $DIR/must-use-ops.rs:49:5
    |
 LL |     -val;
    |     ^^^^
 
 warning: unused unary operation which must be used
-  --> $DIR/must-use-ops.rs:51:5
+  --> $DIR/must-use-ops.rs:50:5
    |
 LL |     *val_pointer;
    |     ^^^^^^^^^^^^
diff --git a/src/test/ui/macro-reexport-removed.rs b/src/test/ui/macro-reexport-removed.rs
new file mode 100644 (file)
index 0000000..bab583d
--- /dev/null
@@ -0,0 +1,18 @@
+// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// aux-build:two_macros.rs
+
+#![feature(macro_reexport)] //~ ERROR feature has been removed
+
+#[macro_reexport(macro_one)] //~ ERROR attribute `macro_reexport` is currently unknown
+extern crate two_macros;
+
+fn main() {}
diff --git a/src/test/ui/macro-reexport-removed.stderr b/src/test/ui/macro-reexport-removed.stderr
new file mode 100644 (file)
index 0000000..ba0ab23
--- /dev/null
@@ -0,0 +1,24 @@
+error[E0557]: feature has been removed
+  --> $DIR/macro-reexport-removed.rs:13:12
+   |
+LL | #![feature(macro_reexport)] //~ ERROR feature has been removed
+   |            ^^^^^^^^^^^^^^
+   |
+note: subsumed by `#![feature(use_extern_macros)]` and `pub use`
+  --> $DIR/macro-reexport-removed.rs:13:12
+   |
+LL | #![feature(macro_reexport)] //~ ERROR feature has been removed
+   |            ^^^^^^^^^^^^^^
+
+error[E0658]: The attribute `macro_reexport` is currently unknown to the compiler and may have meaning added to it in the future (see issue #29642)
+  --> $DIR/macro-reexport-removed.rs:15:1
+   |
+LL | #[macro_reexport(macro_one)] //~ ERROR attribute `macro_reexport` is currently unknown
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = help: add #![feature(custom_attribute)] to the crate attributes to enable
+
+error: aborting due to 2 previous errors
+
+Some errors occurred: E0557, E0658.
+For more information about an error, try `rustc --explain E0557`.
diff --git a/src/test/ui/print_type_sizes/repr_int_c.rs b/src/test/ui/print_type_sizes/repr_int_c.rs
new file mode 100644 (file)
index 0000000..04bb2ab
--- /dev/null
@@ -0,0 +1,35 @@
+// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// compile-flags: -Z print-type-sizes
+// compile-pass
+
+// This test makes sure that the tag is not grown for `repr(C)` or `repr(u8)`
+// variants (see https://github.com/rust-lang/rust/issues/50098 for the original bug).
+
+#![feature(start)]
+#![allow(dead_code)]
+
+#[repr(C, u8)]
+enum ReprCu8 {
+    A(u16),
+    B,
+}
+
+#[repr(u8)]
+enum Repru8 {
+    A(u16),
+    B,
+}
+
+#[start]
+fn start(_: isize, _: *const *const u8) -> isize {
+    0
+}
diff --git a/src/test/ui/print_type_sizes/repr_int_c.stdout b/src/test/ui/print_type_sizes/repr_int_c.stdout
new file mode 100644 (file)
index 0000000..254b3c7
--- /dev/null
@@ -0,0 +1,12 @@
+print-type-size type: `ReprCu8`: 4 bytes, alignment: 2 bytes
+print-type-size     discriminant: 1 bytes
+print-type-size     variant `A`: 3 bytes
+print-type-size         padding: 1 bytes
+print-type-size         field `.0`: 2 bytes, alignment: 2 bytes
+print-type-size     variant `B`: 1 bytes
+print-type-size type: `Repru8`: 4 bytes, alignment: 2 bytes
+print-type-size     discriminant: 1 bytes
+print-type-size     variant `A`: 3 bytes
+print-type-size         padding: 1 bytes
+print-type-size         field `.0`: 2 bytes, alignment: 2 bytes
+print-type-size     variant `B`: 0 bytes
diff --git a/src/test/ui/rfc_1940-must_use_on_functions/fn_must_use.rs b/src/test/ui/rfc_1940-must_use_on_functions/fn_must_use.rs
deleted file mode 100644 (file)
index d20ebf0..0000000
+++ /dev/null
@@ -1,79 +0,0 @@
-// 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.
-
-// compile-pass
-
-#![feature(fn_must_use)]
-#![warn(unused_must_use)]
-
-#[derive(PartialEq, Eq)]
-struct MyStruct {
-    n: usize,
-}
-
-impl MyStruct {
-    #[must_use]
-    fn need_to_use_this_method_value(&self) -> usize {
-        self.n
-    }
-}
-
-trait EvenNature {
-    #[must_use = "no side effects"]
-    fn is_even(&self) -> bool;
-}
-
-impl EvenNature for MyStruct {
-    fn is_even(&self) -> bool {
-        self.n % 2 == 0
-    }
-}
-
-trait Replaceable {
-    fn replace(&mut self, substitute: usize) -> usize;
-}
-
-impl Replaceable for MyStruct {
-    // ↓ N.b.: `#[must_use]` attribute on a particular trait implementation
-    // method won't work; the attribute should be on the method signature in
-    // the trait's definition.
-    #[must_use]
-    fn replace(&mut self, substitute: usize) -> usize {
-        let previously = self.n;
-        self.n = substitute;
-        previously
-    }
-}
-
-#[must_use = "it's important"]
-fn need_to_use_this_value() -> bool {
-    false
-}
-
-fn main() {
-    need_to_use_this_value(); //~ WARN unused return value
-
-    let mut m = MyStruct { n: 2 };
-    let n = MyStruct { n: 3 };
-
-    m.need_to_use_this_method_value(); //~ WARN unused return value
-    m.is_even(); // trait method!
-    //~^ WARN unused return value
-
-    m.replace(3); // won't warn (annotation needs to be in trait definition)
-
-    // comparison methods are `must_use`
-    2.eq(&3); //~ WARN unused return value
-    m.eq(&n); //~ WARN unused return value
-
-    // lint includes comparison operators
-    2 == 3; //~ WARN unused comparison
-    m == n; //~ WARN unused comparison
-}
diff --git a/src/test/ui/rfc_1940-must_use_on_functions/fn_must_use.stderr b/src/test/ui/rfc_1940-must_use_on_functions/fn_must_use.stderr
deleted file mode 100644 (file)
index d0a8bb5..0000000
+++ /dev/null
@@ -1,48 +0,0 @@
-warning: unused return value of `need_to_use_this_value` which must be used: it's important
-  --> $DIR/fn_must_use.rs:61:5
-   |
-LL |     need_to_use_this_value(); //~ WARN unused return value
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-note: lint level defined here
-  --> $DIR/fn_must_use.rs:14:9
-   |
-LL | #![warn(unused_must_use)]
-   |         ^^^^^^^^^^^^^^^
-
-warning: unused return value of `MyStruct::need_to_use_this_method_value` which must be used
-  --> $DIR/fn_must_use.rs:66:5
-   |
-LL |     m.need_to_use_this_method_value(); //~ WARN unused return value
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-warning: unused return value of `EvenNature::is_even` which must be used: no side effects
-  --> $DIR/fn_must_use.rs:67:5
-   |
-LL |     m.is_even(); // trait method!
-   |     ^^^^^^^^^^^^
-
-warning: unused return value of `std::cmp::PartialEq::eq` which must be used
-  --> $DIR/fn_must_use.rs:73:5
-   |
-LL |     2.eq(&3); //~ WARN unused return value
-   |     ^^^^^^^^^
-
-warning: unused return value of `std::cmp::PartialEq::eq` which must be used
-  --> $DIR/fn_must_use.rs:74:5
-   |
-LL |     m.eq(&n); //~ WARN unused return value
-   |     ^^^^^^^^^
-
-warning: unused comparison which must be used
-  --> $DIR/fn_must_use.rs:77:5
-   |
-LL |     2 == 3; //~ WARN unused comparison
-   |     ^^^^^^
-
-warning: unused comparison which must be used
-  --> $DIR/fn_must_use.rs:78:5
-   |
-LL |     m == n; //~ WARN unused comparison
-   |     ^^^^^^
-
index 83a4c5d5dd2ff4fc980291062d5360a6ae530657..eff1f98eb714e69706637b09d3583c1565f63669 100644 (file)
@@ -8,33 +8,10 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(attr_literals)]
-
-#[repr(align(16))]
-struct Gem {
-    mohs_hardness: u8,
-    poofed: bool,
-    weapon: Weapon,
-}
-
 #[repr(simd)] //~ ERROR are experimental
 struct Weapon {
     name: String,
     damage: u32
 }
 
-impl Gem {
-    #[must_use] fn summon_weapon(&self) -> Weapon { self.weapon }
-    //~^ WARN is experimental
-}
-
-#[must_use] //~ WARN is experimental
-fn bubble(gem: Gem) -> Result<Gem, ()> {
-    if gem.poofed {
-        Ok(gem)
-    } else {
-        Err(())
-    }
-}
-
 fn main() {}
index 179daf83c3c0b64c007dccd043b2d536058f15bf..a99530529fcf1a802d80f3a197ea925f7a90ef35 100644 (file)
@@ -1,27 +1,11 @@
 error[E0658]: SIMD types are experimental and possibly buggy (see issue #27731)
-  --> $DIR/gated-features-attr-spans.rs:20:1
+  --> $DIR/gated-features-attr-spans.rs:11:1
    |
 LL | #[repr(simd)] //~ ERROR are experimental
    | ^^^^^^^^^^^^^
    |
    = help: add #![feature(repr_simd)] to the crate attributes to enable
 
-warning: `#[must_use]` on methods is experimental (see issue #43302)
-  --> $DIR/gated-features-attr-spans.rs:27:5
-   |
-LL |     #[must_use] fn summon_weapon(&self) -> Weapon { self.weapon }
-   |     ^^^^^^^^^^^
-   |
-   = help: add #![feature(fn_must_use)] to the crate attributes to enable
-
-warning: `#[must_use]` on functions is experimental (see issue #43302)
-  --> $DIR/gated-features-attr-spans.rs:31:1
-   |
-LL | #[must_use] //~ WARN is experimental
-   | ^^^^^^^^^^^
-   |
-   = help: add #![feature(fn_must_use)] to the crate attributes to enable
-
 error: aborting due to previous error
 
 For more information about this error, try `rustc --explain E0658`.
index 122fd5be5201913d42e219e132d6569493583bca..af3f1cd29bc872b932a13083e531255aab233a7e 160000 (submodule)
@@ -1 +1 @@
-Subproject commit 122fd5be5201913d42e219e132d6569493583bca
+Subproject commit af3f1cd29bc872b932a13083e531255aab233a7e
index 9144e223a5b90e078366275ff3dcdd406e62eae3..d2f44357fef6d61f316abc403e0a5d917f2771c6 160000 (submodule)
@@ -1 +1 @@
-Subproject commit 9144e223a5b90e078366275ff3dcdd406e62eae3
+Subproject commit d2f44357fef6d61f316abc403e0a5d917f2771c6
index 6992f2ba123378d481baa367a5947e30f8f32d6d..1c79443dedf35551319ea138ec6580470e3162af 100644 (file)
@@ -87,6 +87,7 @@ function loadContent(content) {
     var Module = module.constructor;
     var m = new Module();
     m._compile(content, "tmp.js");
+    m.exports.ignore_order = content.indexOf("\n// ignore-order\n") !== -1;
     return m.exports;
 }
 
@@ -130,10 +131,10 @@ function lookForEntry(entry, data) {
             }
         }
         if (allGood === true) {
-            return true;
+            return i;
         }
     }
-    return false;
+    return null;
 }
 
 function main(argv) {
@@ -177,6 +178,7 @@ function main(argv) {
                                'exports.QUERY = QUERY;exports.EXPECTED = EXPECTED;');
         const expected = loadedFile.EXPECTED;
         const query = loadedFile.QUERY;
+        const ignore_order = loadedFile.ignore_order;
         var results = loaded.execSearch(loaded.getQuery(query), index);
         process.stdout.write('Checking "' + file + '" ... ');
         var error_text = [];
@@ -189,13 +191,17 @@ function main(argv) {
                 break;
             }
             var entry = expected[key];
-            var found = false;
+            var prev_pos = 0;
             for (var i = 0; i < entry.length; ++i) {
-                if (lookForEntry(entry[i], results[key]) === true) {
-                    found = true;
-                } else {
+                var entry_pos = lookForEntry(entry[i], results[key]);
+                if (entry_pos === null) {
                     error_text.push("==> Result not found in '" + key + "': '" +
                                     JSON.stringify(entry[i]) + "'");
+                } else if (entry_pos < prev_pos && ignore_order === false) {
+                    error_text.push("==> '" + JSON.stringify(entry[i]) + "' was supposed to be " +
+                                    " before '" + JSON.stringify(results[key][entry_pos]) + "'");
+                } else {
+                    prev_pos = entry_pos;
                 }
             }
         }
index 0f4ed08d0e3d180d66e46904126c3792f57668a9..b6cd17f28ae314f2484ff05d3ce57652d51c5e85 160000 (submodule)
@@ -1 +1 @@
-Subproject commit 0f4ed08d0e3d180d66e46904126c3792f57668a9
+Subproject commit b6cd17f28ae314f2484ff05d3ce57652d51c5e85